In Part I of this series, we built the foundation of our multicloud employee management solution by extracting data from Oracle NetSuite, storing it in Oracle Exadata Database Service on Exascale Infrastructure on Azure, and generating vector embeddings using Azure OpenAI.
Now, in Part II, we’ll create an intelligent search interface that leverages vector similarity search to provide natural language querying capabilities. Users can ask questions like “Find all managers hired in 2023” or “Compose and email to all Sales reps inviting them to a happy hour this Friday” and receive contextual, AI-generated responses.
What We’ll Build
Our AI-powered search interface will:
- Accept natural language queries from users
- Convert queries to vector embeddings using Azure OpenAI
- Perform similarity searches against our employee database
- Generate intelligent responses using GPT models
- Present results through an intuitive Streamlit web interface
Architecture Overview
User Query → Azure OpenAI (Embeddings) → Oracle Vector Search → GPT Response → Streamlit UI
The flow works as follows:
- User enters a natural language query
- Convert query to vector embedding using Azure OpenAI
- Search similar employee records using Oracle’s vector distance functions
- Pass matching records and original query to GPT for response generation
- Display the AI-generated response in the Streamlit interface
Step 1: Setting Up the Streamlit Environment
First, install the required dependencies:
pip install streamlit
pip install oracledb
pip install openai
pip install array
Step 2: Creating the Streamlit Application
Create a new Python file employee_search_app.py with the following structure:
import streamlit as st
import oracledb
import array
import os
from openai import AzureOpenAI
print("Successfully imported libraries and modules")
Step 3: Database and AI Service Connections
Configure connections to both Oracle Database and Azure OpenAI:
# Azure OpenAI Configuration
os.environ['AZURE_OPENAI_API_KEY'] = "your_api_key_here"
os.environ['AZURE_OPENAI_ENDPOINT'] = "https://your-endpoint.openai.azure.com"
# Initialize Azure OpenAI client
client = AzureOpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-06-01",
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT")
)
# Oracle Database Connection Parameters
username = "sys"
password = "your_password"
hostname = "your-scan-hostname.oracle.com"
port = 1521
service_name = "your_service_name"
# Create connection
def get_database_connection():
"""Establish connection to Oracle Database"""
dsn = f"{hostname}:{port}/{service_name}"
try:
connection = oracledb.connect(
user=username,
password=password,
dsn=dsn,
mode=oracledb.SYSDBA
)
print("Connected to Oracle Database successfully")
return connection
except Exception as e:
st.error(f"Database connection failed: {e}")
return None
# Establish database connection
connection = get_database_connection()
if connection:
cursor = connection.cursor()
Step 4: Building the Vector Search Function
Implement the core vector similarity search functionality:
#
#Code truncated for brevity
#
def perform_vector_search(query_text, limit=5):
"""
Perform vector similarity search on employee data
Args:
query_text (str): User's natural language query
limit (int): Number of similar records to return
Returns:
list: Matching employee records
"""
try:
# Generate embedding for the user query
print(f"Processing query: {query_text}")
response = client.embeddings.create(
input=query_text,
model="text-embedding-3-large"
)
# Convert embedding to Oracle-compatible format
query_vector = array.array("f", response.data[0].embedding)
# Execute vector similarity search
sql = """
SELECT PersonId, FirstName, LastName, HireDate,
WorkEmail, Title, ExpenseLimit
FROM EMPLOYEES
ORDER BY VECTOR_DISTANCE(EMBEDDINGS, :query_vector, EUCLIDEAN)
FETCH FIRST :limit ROWS ONLY
"""
cursor.execute(sql, {"query_vector": query_vector, "limit": limit})
results = cursor.fetchall()
print(f"Found {len(results)} similar records")
return results
except Exception as e:
st.error(f"Vector search failed: {e}")
return []
def generate_ai_response(user_query, search_results):
"""
Generate an AI response based on search results
Args:
user_query (str): Original user query
search_results (list): Matching employee records
Returns:
str: AI-generated response
"""
if not search_results:
return "I couldn't find any relevant employee information for your query."
# Build context from search results
context = f"User query: {user_query}\n\nRelevant employee information:\n\n"
for row in search_results:
person_id, first_name, last_name, hire_date, work_email, title, expense_limit = row
context += f"• {first_name} {last_name} (ID: {person_id})\n"
context += f" Title: {title}\n"
context += f" Hire Date: {hire_date}\n"
context += f" Email: {work_email}\n"
context += f" Expense Limit: ${expense_limit}\n\n"
try:
# Generate response using GPT
response = client.chat.completions.create(
model="gpt-35-turbo",
messages=[
{
"role": "system",
"content": "You are a helpful HR assistant. Analyze the employee data and provide a clear, informative response to the user's query. Be concise but comprehensive."
},
{
"role": "user",
"content": context
}
],
max_tokens=500,
temperature=0.7
)
return response.choices[0].message.content
except Exception as e:
st.error(f"AI response generation failed: {e}")
return "I encountered an error while generating a response."
Step 5: Creating the Streamlit User Interface
Build an intuitive web interface for the search functionality:
#
#Code truncated for brevity
#
def main():
"""Main Streamlit application"""
# Page configuration
st.set_page_config(
page_title="Employee Search AI",
page_icon="🔍",
layout="wide"
)
# Header and description
st.title('Multicloud Employee Search AI')
st.markdown("""
**Powered by Oracle Exadata on Azure + Azure OpenAI**
This intelligent search system:
- Extracts data from SaaS applications (NetSuite on OCI)
- Stores data in Oracle Database on Azure with vector embeddings
- Performs AI-powered similarity search
- Generates natural language responses
""")
# Sidebar with examples
with st.sidebar:
st.header("Example Queries:")
st.markdown("""
Try asking:
- "Find all managers hired in 2023"
- "Who are the software engineers?"
- "List recent hires in the sales department"
""")
st.header("System Status")
if connection:
st.success("Database Connected")
else:
st.error("Database Connection Failed")
# Main search interface
with st.form('search_form'):
st.subheader("Ask me anything about our employees")
user_query = st.text_area(
'Enter your question:',
placeholder="e.g., Find all managers with high expense limits",
height=100
)
col1, col2 = st.columns([1, 4])
with col1:
submitted = st.form_submit_button('Search', use_container_width=True)
with col2:
limit = st.slider("Number of results to consider", 1, 20, 5)
# Process search query
if submitted and user_query.strip():
# Perform vector search
search_results = perform_vector_search(user_query, limit)
if search_results:
# Generate AI response
with st.spinner('Generating intelligent response...'):
ai_response = generate_ai_response(user_query, search_results)
# Display results
st.subheader("AI Response")
st.info(ai_response)
# Show detailed results in expandable section
else:
st.warning("No matching employees found. Try rephrasing your query.")
elif submitted:
st.warning("Please enter a search query.")
# Application cleanup
def cleanup():
"""Clean up database connections"""
if connection:
cursor.close()
connection.close()
print("Database connection closed")
# Run the application
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
cleanup()
st.stop()
Step 6: Running the Application
To start your AI-powered employee search application:
streamlit run employee_search_app.py
The application will be available at http://localhost:8501
Key Features and Benefits
Advanced Vector Search
- Semantic Understanding: The system understands intent, not just keywords
- Fuzzy Matching: Finds relevant results even with imprecise queries
- Contextual Responses: AI generates human-like explanations of search results
Oracle Database 23ai Vector Capabilities
- VECTOR_DISTANCE Function: Efficient similarity calculations using Euclidean distance
- Vector Indexing: High-performance searches on large datasets
- Native Vector Storage: No need for external vector databases
User Experience
- Natural Language Interface: Users query in plain English
- Interactive Results: Expandable details for deeper exploration
- Real-time Processing: Fast responses powered by Exascale infrastructure
Conclusion
This AI-powered employee search system demonstrates the power of combining Oracle’s database capabilities with Azure’s AI services. Key capabilities include:
- Seamless Integration: Oracle Exadata on Exascale infrastructure at Azure with Azure OpenAI services
- Intelligent Search: Vector similarity enables semantic understanding
- Natural Interactions: Users can query using natural language
- Scalable Architecture: Built on enterprise-grade infrastructure
The solution showcases how modern businesses can leverage multicloud architectures to build sophisticated, AI-driven applications that enhance productivity and user experience.
For organizations seeking even greater automation, this solution can also be built using Oracle Autonomous Database at Azure, combining self-managing database technology with Azure’s AI capabilities.