Find the 100 best-fit engineers in a 100,000-candidate pool — by reading what people actually built, not the buzzwords in their skills list.
Live deployment
- Frontend (demo console): https://redrob-talentgraph-ai.vercel.app
- Backend (API): https://redrob-talentgraph-api.onrender.com — interactive docs · health
- Repository: https://github.com/0xSHSH/redrob-talentgraph-ai
Redrob is hiring a founding Senior AI Engineer. The job description is deliberately
sharp: it wants production retrieval/ranking experience, real evaluation rigor, and a
shipper mindset — and it explicitly warns that the dataset is full of traps. Keyword
matching fails here on purpose: a "Marketing Manager" who lists Pinecone, LangChain
and Embeddings as skills looks perfect to a keyword model and is completely wrong.
TalentGraph scores evidence over keywords. It weighs what a candidate did in their career descriptions (hybrid retrieval, learning-to-rank, A/B-tested ranking systems) far above a self-declared skills list, layers in real availability signals (recruiter response, recency, notice period), and runs a profile-consistency engine that floors impossible "honeypot" profiles to zero before they can reach the top 100.
| Metric | Value |
|---|---|
| Candidates evaluated | 100,000 |
| Full ranking runtime | ~89s · CPU-only · no network |
| Honeypots in top 100 | 0% (10% = disqualification) |
| India-based in top 100 | 92 / 100 |
| Unique, candidate-specific reasonings | 100 / 100 |
| Official validator | ✅ passes |
candidates.jsonl ──▶ loader ──▶ features ──▶ honeypot check ──▶ scoring ──▶ top-100
(100k) (stdlib) (evidence) (consistency) (evidence + reasoning
× signals + monotonic
× location) scores)
│
┌────────────────────────────────────────┤
▼ ▼
submissions/team_talentgraph.csv artifacts/top100.json + audit.json
│ │
▼ ▼
official validator FastAPI backend ◀──▶ Next.js dashboard
(Render) (Vercel)
The ranking step (rank.py → src/) uses only the Python standard library, so it
reproduces deterministically inside a sandbox. The dashboard reads committed JSON from
frontend/public/data/ and works with no backend at all; point it at the API only
if you want the live sample-ranking demo.
| Landing | Dashboard | Candidate deep-dive | Methodology |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
- Ranker: Python 3.11, standard library (deterministic, CPU-only, no network)
- Backend: FastAPI + Uvicorn
- Frontend: Next.js 14 (App Router), TypeScript, Tailwind CSS, Framer Motion, Recharts
- Deploy: Vercel (frontend) · Render (backend)
redrob-talentgraph-ai/
├── rank.py # one-command reproducible ranker
├── requirements.txt # ranking deps (stdlib only — nothing required)
├── submission_metadata.yaml
├── src/ # loader, features, honeypot, scoring, reasoning, ranker
├── scripts/ # validate_submission.py, build_demo_data.py, audit_top100.py
├── submissions/team_talentgraph.csv
├── artifacts/ # top100.json, audit.json, UI screenshots
├── backend/ # FastAPI app + requirements
├── frontend/ # Next.js dashboard (public/brand/ = logo assets)
├── docker/ranker.Dockerfile # optional Stage-3 reproduction image (NOT for web hosting)
├── docs/ # DEPLOYMENT.md, demo-script.md, judge-pitch.md
└── data/ # candidates.jsonl goes here (git-ignored)
Drop the hackathon
candidates.jsonlintodata/first (it is git-ignored).
# 1) Reproduce the submission CSV (~90s on a laptop CPU)
python rank.py --candidates ./data/candidates.jsonl --out ./submissions/team_talentgraph.csv
# 2) Validate it against the official rules
python scripts/validate_submission.py ./submissions/team_talentgraph.csv
# 3) (optional) Rebuild dashboard data
python scripts/build_demo_data.pypip install -r backend/requirements.txt
uvicorn backend.app:app --reload --port 8000
# open http://localhost:8000/api/healthcd frontend
npm install
npm run build
npm run dev # http://localhost:3000| Method | Path | Returns |
|---|---|---|
| GET | /api/health |
{status, service, top100_loaded} |
| GET | /api/top100 |
full enriched top-100 |
| GET | /api/summary |
headline metrics + title distribution |
| GET | /api/audit |
honeypot rate, India count, score range |
| GET | /api/candidates?q=&min_score=&limit= |
slim searchable list |
| GET | /api/candidates/{candidate_id} |
one full candidate |
| POST | /api/validate |
validate an uploaded CSV |
| POST | /api/rank-sample |
live-rank a sample (≤200) |
Full step-by-step (with the common errors and their fixes) lives in
docs/DEPLOYMENT.md. Short version:
Frontend → Vercel (live: https://redrob-talentgraph-ai.vercel.app)
| Setting | Value |
|---|---|
| Framework | Next.js |
| Root Directory | frontend |
| Install Command | npm install |
| Build Command | npm run build |
| Output Directory | (empty — Next.js default) |
| Env | NEXT_PUBLIC_API_URL=https://redrob-talentgraph-api.onrender.com |
Backend → Render (live: https://redrob-talentgraph-api.onrender.com)
| Setting | Value |
|---|---|
| Runtime | Python 3 (not Docker) |
| Root Directory | (empty) |
| Build Command | pip install -r backend/requirements.txt |
| Start Command | uvicorn backend.app:app --host 0.0.0.0 --port $PORT |
| Health Check Path | /api/health |
| Env | PYTHON_VERSION=3.11.10 |
- Evidence > keywords. Career-description signals are weighted ~4× the skills list, because the planted traps abuse the skills list.
- Honeypots via contradiction, not blocklists. We flag profiles whose own numbers don't add up (stated years vs. the dated timeline, summary vs. profile field, a single role longer than the whole career). These rules fire on ~0.03% of the pool — exactly the scale of the planted honeypots — so genuine seniors are not dropped.
- Availability is a multiplier. A perfect-on-paper candidate who never answers recruiters and has a 120-day notice is re-weighted down to reality.
- Determinism. Fixed reference date and stdlib-only ranking → the CSV reproduces bit-for-bit.
Keyword models rank the "Marketing Manager with 12 AI skills" near the top and rank the real engineer — who wrote "migrated keyword search to a hybrid BGE + learning-to-rank system at a product company" but never typed the word "RAG" — near the bottom. TalentGraph does the opposite, and it can show you why for every single row.
- The semantic tie-breaker is a light local TF-IDF cosine, not a trained model — it only reorders near-ties (±2%). A learned ranker on labeled feedback is the natural next step.
- Reasoning is template-assembled from real extracted facts; it is factual but could be richer with a small local generation model (still no hosted API).
- Future: recruiter feedback loop, online A/B of ranker variants, per-recruiter personalization.
submissions/team_talentgraph.csv— the ranked top 100rank.py+src/— the reproducible rankerartifacts/top100.json,artifacts/audit.json— dashboard + audit datascripts/validate_submission.py— the validatorsubmission_metadata.yaml— portal metadata



