FindMyProfessor / src /faculty_advisor.py
dawnlaker's picture
Implement Gradio chat interface for faculty advisor using Chroma DB. Update faculty advisor functions to accept collection parameter for similarity search. Modify profile_to_vector_database notebook to reflect changes in execution counts and outputs.
61241ce
Raw History Blame Contribute Delete
3.89 kB
import os
from tqdm import tqdm
from dotenv import load_dotenv
import chromadb
from openai import OpenAI
from langchain_openai import OpenAIEmbeddings
# Initialize environment variables
load_dotenv(override=True)
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')
os.environ['HF_TOKEN'] = os.getenv('HF_TOKEN', 'your-key-if-not-using-env')
# Initialize OpenAI client
openai = OpenAI()
# Initialize vectorizer
vectorizer = OpenAIEmbeddings(
model="text-embedding-ada-002",
openai_api_key=os.getenv('OPENAI_API_KEY')
)
def find_similars(collection, description):
"""
Find similar faculty members based on the given description.
Args:
collection: The ChromaDB collection to search in
description (str): The description to search for similar faculty members
Returns:
tuple: (documents, names, links) containing the similar faculty members' information
"""
results = collection.query(
query_embeddings=vectorizer.embed_query(description),
n_results=10
)
documents = results['documents'][0][:]
name = [m['name'] for m in results['metadatas'][0][:]]
link = [m['url'] for m in results['metadatas'][0][:]]
return documents, name, link
def make_context(similars):
"""
Create a context string from similar faculty members.
Args:
similars (tuple): The output from find_similars function
Returns:
str: Formatted context string
"""
message = "To provide some context, here are some faculty members that might be relevant to your description.\n\n"
documents, names, links = similars
for similar, name, link in zip(documents, names, links):
message += f'''Potentially related faculty:
{name}
website: {link}
{similar}\n\n'''
return message
def messages_for(description, similars):
"""
Create a message object for the OpenAI API.
Args:
description (str): The user's description
similars (tuple): The output from find_similars function
Returns:
dict: Message object for OpenAI API
"""
user_prompt = f"Here is my description: {description}\n\n"
user_prompt += make_context(similars)
return {"role": "user", "content": user_prompt}
def gpt_4o_mini_rag(description, history, collection):
"""
Generate a response using GPT-4o-mini model with RAG.
Args:
description (str): The user's description
history (list): Chat history as list of tuples (user_message, assistant_message)
collection: The ChromaDB collection to search in
Yields:
str: Generated response chunks
"""
system_message = {
"role": "system",
"content": "You are a academic advisor. You estimate the relevance of faculty members to a given description. Suggest relevant faculty members. Don't forget to include a link to the faculty member's profile. You should give explanation for your choice in markdown format."
}
# Format chat history into proper message format
formatted_history = []
for user_msg, assistant_msg in history:
formatted_history.append({"role": "user", "content": user_msg})
formatted_history.append({"role": "assistant", "content": assistant_msg})
similars = find_similars(collection=collection, description=description)
current_message = messages_for(description, similars)
# Combine all messages in the correct order
messages = [system_message] + formatted_history + [current_message]
stream = openai.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
seed=42,
stream=True
)
response = ""
for chunk in stream:
response += chunk.choices[0].delta.content or ''
yield response