Skip to content
Back to the list

chat.rentaicoder.com

ATS — Multi-agent candidate ranking

Hybrid retrieval over 10,000 resumes, merged by RRF

The problem: given a job description, surface the ten resumes worth reading out of ten thousand. Keyword search misses candidates who phrase things differently; semantic search swallows hard requirements like a specific framework or a years-of-experience floor. The system runs both and merges the two rankings.

§ 01Algorithm

CandidateSearchOperator.cs — hybrid retrieval + RRF
BM25Index:  k1 = 1.5,  b = 0.75
  idf   = log((N − df + 0.5) / (df + 0.5) + 1)
  norm  = k1 · (1 − b + b · |d| / avgdl)
  score = idf · tf·(k1 + 1) / (tf + norm)

pipeline(jd, filters):
  1  dimIds  ← sql_filter(filters)              # lọc trước theo chiều cấu trúc
  2  ‖ bm25  ← bm25(jd, top = 200) ∩ dimIds     # chạy song song
     ‖ embed ← ann(embed(jd), top = 200)
  3  rrf[d]  ← Σ_lists 1 / (k + rank_i + 1),  k = 60
     pool    ← top 30 by rrf                    # hợp nhất, không cần chuẩn hoá thang điểm
  4  for c in pool (semaphore-bounded):
       eval[c] ← ‖ llm_judge(c, jd, view = CTO)
                 ‖ llm_judge(c, jd, view = HR)
  5  boost   ← apply_feedback(eval)
  6  return top 10 by overall_score

§ 02Highlights

  • Hand-rolled Okapi BM25, k1 = 1.5, b = 0.75
  • Reciprocal Rank Fusion at k = 60 — merges two rankings with no score normalisation
  • SQL pre-filter on structured dimensions, narrowing the pool before the expensive work
  • LLM scores a CTO view and an HR view in parallel, under a concurrency semaphore
  • Feedback loop: earlier human ratings boost later results

§ 03Screens

ATS — Multi-agent candidate ranking01
ATS — Multi-agent candidate ranking02
ATS — Multi-agent candidate ranking03