Spaces:
Sleeping
Sleeping
import streamlit as st | |
import json | |
from typing import Dict, List, Any | |
import re | |
# Initialize Streamlit page configuration | |
st.set_page_config( | |
page_title="Manyue's Portfolio Chatbot", | |
page_icon="🤖", | |
layout="wide" | |
) | |
def extract_key_requirements(text: str) -> Dict[str, List[str]]: | |
"""Extract key requirements from text""" | |
text_lower = text.lower() | |
categories = { | |
'technical_skills': [ | |
'python', 'machine learning', 'deep learning', 'nlp', 'neural networks', | |
'data science', 'sql', 'tensorflow', 'pytorch', 'scikit-learn', 'data analysis' | |
], | |
'soft_skills': [ | |
'communication', 'teamwork', 'leadership', 'problem solving', 'analytical', | |
'collaborative', 'independent', 'innovative' | |
], | |
'education': [ | |
'master', 'phd', 'bachelor', 'degree', 'computer science', 'statistics', | |
'mathematics', 'post graduate', 'certification' | |
], | |
'experience': [ | |
'year', 'experience', 'background', 'industry', 'startup', 'enterprise' | |
] | |
} | |
found = {category: [] for category in categories} | |
for category, keywords in categories.items(): | |
for keyword in keywords: | |
if keyword in text_lower: | |
found[category].append(keyword) | |
return found | |
def analyze_profile_match(requirements: Dict[str, List[str]], knowledge_base: dict) -> Dict[str, Any]: | |
"""Analyze how well the profile matches requirements""" | |
my_skills = set(s.lower() for s in knowledge_base['skills']['technical_skills']) | |
my_soft_skills = set(s.lower() for s in knowledge_base['skills']['soft_skills']) | |
# Match technical skills | |
matching_tech_skills = [skill for skill in requirements['technical_skills'] | |
if any(my_skill in skill or skill in my_skill | |
for my_skill in my_skills)] | |
# Match soft skills | |
matching_soft_skills = [skill for skill in requirements['soft_skills'] | |
if any(my_skill in skill or skill in my_skill | |
for my_skill in my_soft_skills)] | |
# Find relevant projects | |
relevant_projects = [] | |
for project in knowledge_base['professional_experience']['projects']: | |
project_skills = set(s.lower() for s in project['skills_used']) | |
if any(skill in ' '.join(requirements['technical_skills']) for skill in project_skills): | |
relevant_projects.append(project) | |
# Check education match | |
education_matches = [] | |
for edu in knowledge_base['education']['postgraduate']: | |
if any(req in edu['course_name'].lower() for req in requirements['education']): | |
education_matches.append(edu) | |
return { | |
'matching_tech_skills': matching_tech_skills, | |
'matching_soft_skills': matching_soft_skills, | |
'relevant_projects': relevant_projects[:2], | |
'education_matches': education_matches, | |
'background_story': knowledge_base['frequently_asked_questions'][0]['answer'] # Transition story | |
} | |
def generate_response(query: str, knowledge_base: dict) -> str: | |
"""Generate enhanced responses using the knowledge base""" | |
query_lower = query.lower() | |
# Handle job descriptions or role requirements | |
if len(query.split()) > 20 or any(phrase in query_lower for phrase in | |
['requirements', 'qualifications', 'looking for', 'job description', 'responsibilities']): | |
requirements = extract_key_requirements(query) | |
match_analysis = analyze_profile_match(requirements, knowledge_base) | |
response_parts = [] | |
# Start with unique background if it's an ML role | |
if any(skill in query_lower for skill in ['machine learning', 'ml', 'ai', 'data science']): | |
transition_story = match_analysis['background_story'] | |
response_parts.append(f"With my unique transition from commerce to ML/AI, {transition_story[:200]}...") | |
# Add technical alignment | |
if match_analysis['matching_tech_skills']: | |
response_parts.append(f"I have hands-on experience with key technical requirements including {', '.join(match_analysis['matching_tech_skills'])}.") | |
# Highlight relevant project | |
if match_analysis['relevant_projects']: | |
project = match_analysis['relevant_projects'][0] | |
response_parts.append(f"My project '{project['name']}' demonstrates my capabilities as {project['description']}") | |
# Add education and Canadian context | |
response_parts.append("I'm completing advanced AI/ML education in Canada through Georgian College and George Brown College, gaining cutting-edge knowledge in ML engineering and practical implementation.") | |
# Add forward-looking statement | |
response_parts.append("I'm actively expanding my ML expertise through hands-on projects and am ready to contribute to innovative ML solutions in the Canadian tech industry.") | |
return ' '.join(response_parts) | |
# Handle specific company/role queries | |
elif any(word in query_lower for word in ['role', 'fit', 'job', 'position', 'company']): | |
company_name = None | |
words = query.split() | |
for word in words: | |
if word[0].isupper() and word.lower() not in ['i', 'ml', 'ai', 'nlp']: | |
company_name = word | |
break | |
projects = knowledge_base['professional_experience']['projects'] | |
skills = knowledge_base['skills']['technical_skills'] | |
goals = knowledge_base['goals_and_aspirations']['short_term'] | |
response = [ | |
f"{'As a candidate for ' + company_name if company_name else 'As an ML engineer candidate'}, I bring a unique combination of technical expertise and business understanding from my commerce background.", | |
f"My strongest project is my {projects[0]['name']}, where {projects[0]['description']}", | |
f"I've developed expertise in {', '.join(skills[:3])}, applying these skills in real-world projects.", | |
"With my Canadian AI/ML education and practical project experience, I'm well-prepared to contribute to innovative ML solutions.", | |
f"I'm actively {goals[0].lower()} and expanding my portfolio with industry-relevant projects." | |
] | |
return ' '.join(response) | |
# Handle specific skill queries | |
elif any(word in query_lower for word in ['skill', 'know', 'experience', 'expert']): | |
tech_skills = knowledge_base['skills']['technical_skills'] | |
projects = knowledge_base['professional_experience']['projects'] | |
return f"My core technical stack includes {', '.join(tech_skills[:5])}. I've applied these skills in real-world projects like my {projects[0]['name']}, which {projects[0]['description']}. I'm currently enhancing my ML expertise through advanced studies in Canada and practical project implementation." | |
# Handle background/journey queries | |
elif any(word in query_lower for word in ['background', 'journey', 'story']): | |
transition = next((qa['answer'] for qa in knowledge_base['frequently_asked_questions'] | |
if 'transition' in qa['question'].lower()), '') | |
return f"{transition[:300]}... This unique journey gives me both technical expertise and business understanding, valuable for ML engineering roles." | |
# Default response | |
return f"I'm {knowledge_base['personal_details']['full_name']}, a Machine Learning Engineer candidate with a unique background in commerce and technology. {knowledge_base['personal_details']['professional_summary']}" | |
# Load and cache knowledge base | |
def load_knowledge_base(): | |
try: | |
with open('manny_knowledge_base.json', 'r', encoding='utf-8') as f: | |
return json.load(f) | |
except FileNotFoundError: | |
st.error("Knowledge base file not found.") | |
return {} | |
def initialize_session_state(): | |
"""Initialize session state variables""" | |
if "messages" not in st.session_state: | |
st.session_state.messages = [] | |
if "knowledge_base" not in st.session_state: | |
st.session_state.knowledge_base = load_knowledge_base() | |
def main(): | |
st.title("💬 Chat with Manyue's Portfolio") | |
st.write(""" | |
Hi! I'm Manyue's AI assistant. I can tell you about: | |
- My journey from commerce to ML/AI | |
- My technical skills and projects | |
- My fit for ML/AI roles | |
- You can also paste job descriptions, and I'll show how my profile matches! | |
""") | |
# Initialize session state | |
initialize_session_state() | |
# Create two columns | |
col1, col2 = st.columns([3, 1]) | |
with col1: | |
# Display chat messages | |
for message in st.session_state.messages: | |
with st.chat_message(message["role"]): | |
st.markdown(message["content"]) | |
# Chat input | |
if prompt := st.chat_input("Ask me anything about Manyue's experience or paste a job description..."): | |
# Add user message | |
st.session_state.messages.append({"role": "user", "content": prompt}) | |
with st.chat_message("user"): | |
st.markdown(prompt) | |
# Generate and display response | |
with st.chat_message("assistant"): | |
response = generate_response(prompt, st.session_state.knowledge_base) | |
st.markdown(response) | |
st.session_state.messages.append({"role": "assistant", "content": response}) | |
with col2: | |
st.subheader("Quick Questions") | |
example_questions = [ | |
"Tell me about your ML projects", | |
"What are your technical skills?", | |
"Why should we hire you as an ML Engineer?", | |
"What's your journey into ML?", | |
"Paste a job description to see how I match!" | |
] | |
for question in example_questions: | |
if st.button(question): | |
st.session_state.messages.append({"role": "user", "content": question}) | |
st.experimental_rerun() | |
st.markdown("---") | |
if st.button("Clear Chat"): | |
st.session_state.messages = [] | |
st.experimental_rerun() | |
if __name__ == "__main__": | |
main() |