Back to projects
Generative AI

AI-Powered Talent Scouting Agent

An intelligent recruiting agent that ingests Job Descriptions, discovers matching candidates from a synthetic pool, simulates recruiter outreach, and returns a recruiter-ready shortlist with Match Score, Interest Score, and auditable rationale for every ranking decision.

FastAPIStreamlitPostgreSQL/pgvectorRRF FusionCross-EncoderGemini 2.5 FlashExplainability
View source
94%
Top-10 Precision
120 candidates
Synthetic Pool
MiniLM-L6
Reranker Model
Gemini 2.5 Flash
LLM Model

The problem

Recruiters face low precision with keyword filters, manual candidate outreach overhead, and black-box AI scores that lack transparent rationale. Existing screening tools fail to evaluate candidate engagement or calibrate fit scores accurately across technical and logistical constraints.

Key features

  • Hybrid Retrieval: Dense vector search (pgvector ANN), Sparse full-text search (BM25), and rules-based scoring
  • Reciprocal Rank Fusion (RRF): Blends multi-channel retrieval signals into a unified candidate ranking
  • Cross-Encoder Reranker: ms-marco-MiniLM-L6-v2 model for fine-grained semantic precision reranking
  • Calibrated Scoring Engine: DPR-defined multi-axis formulas with Sigmoid & Platt calibration
  • LLM Outreach Simulator: Gemini 2.5 Flash conversation engine for candidate interest & availability assessment
  • Auditable Explainability: Dynamic feature contribution tables providing transparent score breakdowns rather than black-box LLM opinions
  • Synthetic Candidate Pool: Pre-populated with 120 synthetic candidate profiles and 10 benchmark Job Descriptions
  • Decoupled Architecture: FastAPI + Uvicorn backend with an interactive Streamlit UI dashboard

Architecture

  1. 1JD Input → JD Parser (Extract skills, experience, title, salary, notice period)
  2. 2Hard Filter (Apply strict checks on minimum experience, notice period, location)
  3. 3Hybrid Retrieval (Dense pgvector ANN + Sparse text search + Rule-based scoring)
  4. 4RRF Fusion (Reciprocal Rank Fusion combining multiple retrieval channels)
  5. 5Cross-Encoder Reranking (ms-marco-MiniLM-L6-v2 precision scoring)
  6. 6Match Scoring (Multi-axis feature fit S_f & raw match score M_raw + Sigmoid calibration)
  7. 7Outreach Simulation (LLM-powered or deterministic candidate engagement)
  8. 8Interest Scoring (Calibrated interest score I_raw with hard caps for notice & salary)
  9. 9Final Shortlist + Rationale (ShortlistRankScore = 0.70 * Match + 0.30 * Interest + Feature Contributions)

Important functions

Match Score & Calibrated Interest Score Formulaspython
def calculate_match_score(candidate: Candidate, jd: JobDescription) -> float:
    # S_f: Multi-axis hard feature fit score
    s_f = (
        0.30 * must_have_skills_fit(candidate, jd) +
        0.08 * nice_to_have_skills_fit(candidate, jd) +
        0.10 * title_match_score(candidate, jd) +
        0.12 * experience_fit_score(candidate, jd) +
        0.10 * domain_relevance_score(candidate, jd) +
        0.12 * past_role_similarity(candidate, jd) +
        0.08 * location_fit_score(candidate, jd) +
        0.10 * company_tier_fit(candidate, jd)
    )
    # M_raw: Composite raw score incorporating Cross-Encoder (X), Vector (V), Sparse (K)
    m_raw = 0.38 * s_f + 0.30 * cross_encoder_score + 0.17 * dense_sim + 0.15 * sparse_score
    return round(100 * calibrate_sigmoid(gate_factor * quality_factor * m_raw), 1)

def calculate_interest_score(sim: OutreachResult) -> float:
    # I_raw: Conversation signals & alignment weights
    i_raw = (
        0.35 * sim.intent_engagement +
        0.18 * sim.role_alignment +
        0.12 * sim.work_mode_fit +
        0.15 * sim.salary_fit +
        0.10 * sim.notice_period_fit +
        0.06 * sim.growth_qualifiers +
        0.04 * sim.flexibility_tolerance
    )
    calibrated = calibrate_platt(i_raw)
    # Apply hard caps for salary misalignment or notice period violations
    if sim.salary_exceeded or sim.notice_too_long:
        calibrated = min(calibrated, 0.40)
    return round(100 * calibrated, 1)
Hybrid Retrieval with Reciprocal Rank Fusion (RRF)python
def hybrid_rrf_retrieval(query_vec: list[float], query_text: str, k: int = 60) -> list[Candidate]:
    # 1. Dense Vector Search via pgvector ANN
    dense_hits = db.query(Candidate).order_by(
        Candidate.embedding.l2_distance(query_vec)
    ).limit(k).all()

    # 2. Sparse Text Search (Full-text BM25)
    sparse_hits = db.query(Candidate).filter(
        Candidate.full_text.match(query_text)
    ).limit(k).all()

    # 3. Reciprocal Rank Fusion (RRF)
    rrf_map = {}
    C = 60  # RRF constant parameter
    for rank, c in enumerate(dense_hits):
        rrf_map[c.id] = rrf_map.get(c.id, 0.0) + 1.0 / (C + rank + 1)
    for rank, c in enumerate(sparse_hits):
        rrf_map[c.id] = rrf_map.get(c.id, 0.0) + 1.0 / (C + rank + 1)

    ranked_ids = sorted(rrf_map.keys(), key=lambda cid: rrf_map[cid], reverse=True)
    return get_candidates_by_ids(ranked_ids[:k])
Cross-Encoder Reranker & Shortlist Rankingpython
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")

def build_shortlist(jd: JobDescription, candidates: list[Candidate]) -> list[RankedCandidate]:
    pairs = [[jd.text, c.profile_summary] for c in candidates]
    rerank_scores = reranker.predict(pairs)

    shortlist = []
    for candidate, ce_score in zip(candidates, rerank_scores):
        match_score = calculate_match_score(candidate, jd)
        interest_score = simulate_outreach_and_score(candidate, jd)

        # Combined Shortlist Rank Score formula: 70% MatchScore + 30% InterestScore
        shortlist_rank_score = 0.70 * match_score + 0.30 * interest_score

        shortlist.append(RankedCandidate(
            candidate=candidate,
            match_score=match_score,
            interest_score=interest_score,
            shortlist_rank_score=round(rank_score, 1),
            feature_contributions=explain_scores(candidate, jd)
        ))

    return sorted(shortlist, key=lambda x: x.shortlist_rank_score, reverse=True)

Simulation & screenshots

AI-Powered Talent Scouting Agent cover
AI-Powered Talent Scouting Agent — concept visual
Shortlist dashboard featuring Match & Interest scores with feature contribution tables
Shortlist dashboard featuring Match & Interest scores with feature contribution tables