# File: src/evaluator.py # Purpose: Score candidate responses using Groq and produce a hiring report import json import re from typing import List, Dict, Any from groq import Groq from config import GROQ_API_KEY, GROQ_LLM_MODEL, SCORE_WEIGHTS _groq = Groq(api_key=GROQ_API_KEY) EVALUATION_PROMPT = """You are an expert technical recruiter evaluating a candidate's interview. Score the candidate on these three dimensions (0-10 scale): 1. communication_score: Clarity, structure, and articulation of responses. 2. technical_score: Depth, accuracy, and relevance of technical knowledge. 3. confidence_score: Certainty, specificity, and ownership shown in answers. Also extract: - skills: JSON array of technical skills demonstrated. - strengths: 2-3 bullet points. - weaknesses: 1-2 bullet points. - recommendation: One of ["Proceed to Technical Round", "Proceed with Caution", "Do Not Proceed"]. - summary: One paragraph summary for the recruiter. Respond ONLY with a valid JSON object. No markdown, no extra text. Schema: { "communication_score": , "technical_score": , "confidence_score": , "skills": [], "strengths": [], "weaknesses": [], "recommendation": , "summary": } """ def evaluate_candidate(candidate_name: str, transcript: List[Dict[str, str]]) -> Dict[str, Any]: transcript_text = "\n".join(f"{t['speaker']}: {t['text']}" for t in transcript) response = _groq.chat.completions.create( model=GROQ_LLM_MODEL, messages=[ {"role": "system", "content": EVALUATION_PROMPT}, {"role": "user", "content": f"Candidate: {candidate_name}\n\nTranscript:\n{transcript_text}"}, ], temperature=0, max_tokens=800, ) raw = response.choices[0].message.content.strip() raw = re.sub(r"```json|```", "", raw).strip() result = json.loads(raw) overall = ( result["communication_score"] * SCORE_WEIGHTS["communication"] + result["technical_score"] * SCORE_WEIGHTS["technical_skills"] + result["confidence_score"] * SCORE_WEIGHTS["confidence"] ) result["overall_score"] = round(overall, 2) return result def format_report(candidate_name: str, phone: str, evaluation: Dict[str, Any]) -> str: skills_str = "\n".join(f" - {s}" for s in evaluation.get("skills", [])) strengths_str = "\n".join(f" - {s}" for s in evaluation.get("strengths", [])) weaknesses_str = "\n".join(f" - {w}" for w in evaluation.get("weaknesses", [])) return f""" AI Interview Screening Report ============================== Candidate : {candidate_name} Phone : {phone} Scores ------ Communication : {evaluation['communication_score']:.1f} / 10 Technical : {evaluation['technical_score']:.1f} / 10 Confidence : {evaluation['confidence_score']:.1f} / 10 Overall : {evaluation['overall_score']:.1f} / 10 Skills Identified ----------------- {skills_str} Strengths --------- {strengths_str} Areas to Probe Further ----------------------- {weaknesses_str} Summary ------- {evaluation.get('summary', '')} Recommendation -------------- {evaluation.get('recommendation', 'N/A')} ============================== """.strip()