Skip to content

Commit 3f5c499

Browse files
committed
Update: Add in response from cypherqagraph. Fix: Fix issue where job title doesn't exists, allow node search switch
1 parent 216ba0f commit 3f5c499

File tree

3 files changed

+42
-42
lines changed

3 files changed

+42
-42
lines changed

be_repo/modules/job_recommendation_system.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import sys
99

1010
def main():
11-
1211

1312
# Redirect standard output to a file
1413
sys.stdout = open('output.log', 'w')
@@ -34,6 +33,8 @@ def main():
3433
password=NEO4J_PASSWORD
3534
)
3635

36+
node_label = "JTitle" # Adjust as needed; could be dynamic based on user input or other criteria
37+
3738
# Initialize Controller Components
3839
resume_processor = ResumeProcessor()
3940
retrieval_engine = RetrievalEngine(resume_processor, neo4j_model)
@@ -51,7 +52,6 @@ def main():
5152
return
5253

5354
# Perform Mixed Retrieval for 'JD' Node Label
54-
node_label = "JD" # Adjust as needed; could be dynamic based on user input or other criteria
5555
similar_docs, graph_results = retrieval_engine.perform_mixed_retrieval(resume_text, node_label=node_label)
5656

5757
if not similar_docs and not graph_results:

be_repo/modules/recommendation_generator.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,42 @@ def merge_results(self, vector_docs, graph_results):
99

1010
# Process vector similarity results
1111
for doc in vector_docs:
12-
comp = doc.metadata.get("comp", "")
13-
resp = doc.metadata.get("resp", "")
14-
job_title = f"{resp} at {comp}".strip()
15-
if job_title:
16-
combined_jobs[job_title] = combined_jobs.get(job_title, 0) + 1
12+
# Exclude 'id' and get all other non-empty metadata properties
13+
metadata = {k: v for k, v in doc.metadata.items() if k != 'id' and v}
14+
# Create a description string from the non-empty properties
15+
job_description = ', '.join(f"{k}: {v}" for k, v in metadata.items())
16+
if job_description:
17+
combined_jobs[job_description] = combined_jobs.get(job_description, 0) + 1
1718

1819
# Process graph traversal results
19-
# Access the context from intermediate steps
2020
intermediate_steps = graph_results.get('intermediate_steps', [])
2121
if len(intermediate_steps) > 1:
2222
context = intermediate_steps[1].get('context', [])
2323
for job in context:
24-
job_title = job.get('job_title', '')
25-
company = job.get('company', '')
26-
if job_title and company:
27-
combined_job = f"{job_title} at {company}"
28-
combined_jobs[combined_job] = combined_jobs.get(combined_job, 0) + 1
24+
# Exclude 'id' and get all other non-empty properties
25+
job_data = {k: v for k, v in job.items() if k != 'id' and v}
26+
# Create a description string
27+
job_description = ', '.join(f"{k}: {v}" for k, v in job_data.items())
28+
if job_description:
29+
combined_jobs[job_description] = combined_jobs.get(job_description, 0) + 1
30+
31+
# Include the 'result' from 'graph_results' directly
32+
graph_result_text = graph_results.get('result', '').strip()
33+
if graph_result_text:
34+
combined_jobs[graph_result_text] = combined_jobs.get(graph_result_text, 0) + 1
2935

3036
# Convert to sorted list based on combined score
3137
sorted_jobs = sorted(combined_jobs.items(), key=lambda item: item[1], reverse=True)
3238
return [job for job, score in sorted_jobs]
33-
39+
3440
def generate_recommendations(self, vector_docs, graph_results):
3541
"""
3642
Generate a ranked list of job recommendations by merging vector and graph results.
37-
43+
3844
Parameters:
3945
vector_docs (List[Document]): Documents from vector similarity search.
4046
graph_results (dict): Results from graph traversal.
41-
47+
4248
Returns:
4349
List[str]: Ranked list of unique job recommendations.
4450
"""

be_repo/modules/retrieval_engine.py

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,10 @@ def __init__(self, resume_processor, neo4j_model):
2626
self.graph_chain = self.neo4j_model.get_graph_chain()
2727

2828
# Define the PromptTemplate with 'context' as input variable
29-
prompt = PromptTemplate(
30-
template="""
31-
You are an expert Cypher query writer for a Neo4j graph database.
29+
template="""
30+
You are an assistant that matches resumes to relevant job descriptions.
3231
33-
Given the user's question, generate an efficient Cypher query that:
34-
- extract entities and relationships from the following resume.
35-
- Focus solely on the resume content.
32+
Given the user's resume, find the most relevant job descriptions.
3633
3734
**Entities to Extract:**
3835
- **Education (Edu):** Details about degrees, fields of study, institutions, start and end years, GPA.
@@ -42,30 +39,20 @@ def __init__(self, resume_processor, neo4j_model):
4239
- **Certifications (Cert):** Certification names, issuing organizations, expiration dates.
4340
- **Soft Skills (SSkill):** Non-technical skills like leadership, communication.
4441
45-
**Relationships to Identify:**
46-
- **UTILIZES_SKILL:** A Work Experience (WE) node utilizes a Skill (Skill) node.
47-
- **USES_TECH:** A Project (Proj) node uses a Skill (Skill) node as a technology.
48-
- **REL_TO (Proj to Skill):** A Project (Proj) node is related to a Skill (Skill) node.
49-
- **REL_TO (Skill to Skill):** A Skill (Skill) node is similar to another Skill (Skill) node.
50-
5142
**Resume:**
5243
\"\"\"
5344
{context}
5445
\"\"\"
55-
""",
56-
input_variables=["input"]
57-
)
58-
59-
# Create a documents chain
60-
self.combine_docs_chain = create_stuff_documents_chain(self.llm, prompt=prompt)
46+
"""
6147

62-
# Initialize Retrieval Chain
63-
# Default node_label is 'JD'; can be adjusted as needed
64-
self.retrieval_chain = create_retrieval_chain(
65-
self.neo4j_model.get_retriever(node_label="JD"),
66-
self.combine_docs_chain
48+
self.prompt_template = PromptTemplate(
49+
template=template,
50+
input_variables=["input"]
6751
)
6852

53+
# Create a documents chain
54+
self.combine_docs_chain = create_stuff_documents_chain(self.llm, self.prompt_template)
55+
6956
def perform_mixed_retrieval(self, resume_text, node_label="JD"):
7057
"""
7158
Perform mixed retrieval using vector similarity and graph traversal.
@@ -89,14 +76,21 @@ def perform_mixed_retrieval(self, resume_text, node_label="JD"):
8976
# Access the schema property correctly
9077
schema = self.neo4j_model.graph.get_schema
9178

79+
# Get the retriever for the given node label
80+
retriever = self.neo4j_model.get_retriever(node_label=node_label)
81+
82+
# Create the retrieval chain with the retriever and the combine_docs_chain
83+
retrieval_chain = create_retrieval_chain(
84+
retriever,
85+
self.combine_docs_chain
86+
)
87+
9288
# Perform vector similarity search
93-
similar_docs_result = self.retrieval_chain.invoke({"input": resume_text}) # Corrected to 'context'
89+
similar_docs_result = retrieval_chain.invoke({"input": resume_text}) # Corrected to 'context'
9490
similar_docs = similar_docs_result.get("output", [])
9591
print("similar_docs_result:", similar_docs_result)
9692
print("Keys in similar_docs_result:", similar_docs_result.keys())
9793

98-
99-
10094
for doc in similar_docs:
10195
print("Document Metadata:", doc.metadata)
10296

0 commit comments

Comments
 (0)