Arjun Singh commited on
Commit
d83dcfb
·
1 Parent(s): 0fe9950

Added hallucination detection to AI Recruiting Agent

Browse files
Files changed (1) hide show
  1. app.py +44 -3
app.py CHANGED
@@ -120,6 +120,38 @@ def store_resumes(resume_files: List[tempfile._TemporaryFileWrapper]) -> str:
120
  resume_store.add_documents(all_docs)
121
  return f"Successfully stored {len(resume_files)} resumes"
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  def analyze_candidates(job_description: str) -> str:
124
  # First extract required skills from job description
125
  skills_prompt = PromptTemplate(
@@ -225,6 +257,9 @@ def analyze_candidates(job_description: str) -> str:
225
  "cultural_requirements": cultural_requirements
226
  })
227
 
 
 
 
228
  # Now analyze technical skills match
229
  skills_analysis_prompt = PromptTemplate(
230
  input_variables=["resume", "required_skills", "job_description"],
@@ -261,6 +296,9 @@ def analyze_candidates(job_description: str) -> str:
261
  "job_description": job_description
262
  })
263
 
 
 
 
264
  # Create final recommendation
265
  final_recommendation_prompt = PromptTemplate(
266
  input_variables=["skills_analysis", "culture_analysis", "job_description"],
@@ -300,6 +338,11 @@ def analyze_candidates(job_description: str) -> str:
300
  "job_description": job_description
301
  })
302
 
 
 
 
 
 
303
  # Append the analysis for this candidate to the consolidated analyses
304
  consolidated_analyses.append(f"""
305
  === Candidate Analysis (Resume ID: {resume_id}) ===
@@ -311,7 +354,7 @@ def analyze_candidates(job_description: str) -> str:
311
  {skills_fit}
312
 
313
  HIRING RECOMMENDATION:
314
- {final_recommendation}
315
 
316
  ----------------------------------------
317
  """)
@@ -329,8 +372,6 @@ def analyze_candidates(job_description: str) -> str:
329
  return "\n".join(consolidated_analyses)
330
 
331
 
332
-
333
-
334
  def clear_databases():
335
  """Clear both resume and culture document databases"""
336
  global resume_store, culture_store
 
120
  resume_store.add_documents(all_docs)
121
  return f"Successfully stored {len(resume_files)} resumes"
122
 
123
+ def verify_analysis(analysis_text: str, source_documents: List[str]) -> Dict:
124
+ """Verify analysis against source documents"""
125
+ verification_prompt = PromptTemplate(
126
+ input_variables=["analysis", "source_docs"],
127
+ template="""
128
+ Compare this analysis against source documents. Identify unsupported claims.
129
+
130
+ Analysis: {analysis}
131
+ Source Documents: {source_docs}
132
+
133
+ Provide:
134
+ UNSUPPORTED CLAIMS: [list or "None"]
135
+ FACTUALITY SCORE: [0-100]%
136
+ UNCERTAINTY: [areas or "None"]
137
+ """
138
+ )
139
+
140
+ chain = LLMChain(llm=llm, prompt=verification_prompt)
141
+ result = chain.run({
142
+ "analysis": analysis_text,
143
+ "source_docs": "\n---\n".join(source_documents)
144
+ })
145
+
146
+ # Parse score
147
+ try:
148
+ score_line = [line for line in result.split('\n') if 'FACTUALITY SCORE:' in line][0]
149
+ score = int(score_line.split(':')[1].strip().replace('%', '')) / 100
150
+ except:
151
+ score = 0.5
152
+
153
+ return {"factuality_score": score, "verification_result": result}
154
+
155
  def analyze_candidates(job_description: str) -> str:
156
  # First extract required skills from job description
157
  skills_prompt = PromptTemplate(
 
257
  "cultural_requirements": cultural_requirements
258
  })
259
 
260
+ # Verify culture analysis
261
+ culture_verification = verify_analysis(culture_fit, [resume_text, cultural_requirements])
262
+
263
  # Now analyze technical skills match
264
  skills_analysis_prompt = PromptTemplate(
265
  input_variables=["resume", "required_skills", "job_description"],
 
296
  "job_description": job_description
297
  })
298
 
299
+ # Verify skills analysis
300
+ skills_verification = verify_analysis(skills_fit, [resume_text, skills, job_description])
301
+
302
  # Create final recommendation
303
  final_recommendation_prompt = PromptTemplate(
304
  input_variables=["skills_analysis", "culture_analysis", "job_description"],
 
338
  "job_description": job_description
339
  })
340
 
341
+ # Add verification warnings if factuality score < 0.8
342
+ verification_notes = ""
343
+ if culture_verification["factuality_score"] < 0.8 or skills_verification["factuality_score"] < 0.8:
344
+ verification_notes = f"\n\n⚠️ VERIFICATION: Some claims may be unsupported. Culture: {culture_verification['factuality_score']:.0%}, Skills: {skills_verification['factuality_score']:.0%}"
345
+
346
  # Append the analysis for this candidate to the consolidated analyses
347
  consolidated_analyses.append(f"""
348
  === Candidate Analysis (Resume ID: {resume_id}) ===
 
354
  {skills_fit}
355
 
356
  HIRING RECOMMENDATION:
357
+ {final_recommendation}{verification_notes}
358
 
359
  ----------------------------------------
360
  """)
 
372
  return "\n".join(consolidated_analyses)
373
 
374
 
 
 
375
  def clear_databases():
376
  """Clear both resume and culture document databases"""
377
  global resume_store, culture_store