|
import streamlit as st |
|
import json |
|
from typing import Dict, List, Any |
|
import re |
|
|
|
|
|
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']) |
|
|
|
|
|
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)] |
|
|
|
|
|
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)] |
|
|
|
|
|
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) |
|
|
|
|
|
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'] |
|
} |
|
|
|
def generate_response(query: str, knowledge_base: dict) -> str: |
|
"""Generate enhanced responses using the knowledge base""" |
|
query_lower = query.lower() |
|
|
|
|
|
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 = [] |
|
|
|
|
|
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]}...") |
|
|
|
|
|
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'])}.") |
|
|
|
|
|
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']}") |
|
|
|
|
|
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.") |
|
|
|
|
|
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) |
|
|
|
|
|
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) |
|
|
|
|
|
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." |
|
|
|
|
|
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." |
|
|
|
|
|
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']}" |
|
|
|
|
|
@st.cache_data |
|
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() |
|
|
|
|
|
col1, col2 = st.columns([3, 1]) |
|
|
|
with col1: |
|
|
|
for message in st.session_state.messages: |
|
with st.chat_message(message["role"]): |
|
st.markdown(message["content"]) |
|
|
|
|
|
if prompt := st.chat_input("Ask me anything about Manyue's experience or paste a job description..."): |
|
|
|
st.session_state.messages.append({"role": "user", "content": prompt}) |
|
with st.chat_message("user"): |
|
st.markdown(prompt) |
|
|
|
|
|
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() |