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.
Visit product— ATS — Multi-agent candidate ranking (opens in a new tab)
- .NET 10
- NTG.Adk
- EmbeddingGemma
- SQLite
- SSE
§ 01 — Algorithm
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§ 02 — Highlights
- 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
§ 03 — Screens


