talentry-ai / docs /architecture.md
williyam's picture
deploy: sync from talentry-ai @ f4ea7a8
c008e60
|
Raw
History Blame Contribute Delete
10.3 kB

Talentry AI - System Architecture

This document is the engineer's guide to Talentry AI. If you are reviewing the codebase at Stage 3 (reproduction) or Stage 5 (defend-your-work) of the Redrob × Hack2Skill - India Runs challenge, start here.


1. Goals and constraints

The challenge (submission_spec.md §3) imposes a hard envelope on the ranking step:

Constraint Limit
Wall-clock runtime ≤ 5 minutes
RAM ≤ 16 GB
Compute CPU only
Network Off (no LLM API calls)
Disk (intermediate state) ≤ 5 GB

We additionally treat these product requirements as first-class:

  • Explainability - every score must be defensible at Stage 4 manual review.
  • Reproducibility - bit-for-bit reproducibility in a sandboxed Docker.
  • Anti-trap robustness - the dataset deliberately contains keyword stuffers, plain-language Tier-5s, behavioural twins, and ~80 honeypots.
  • No hallucination in reasoning - every reasoning string must reference only facts present in the candidate's own profile.

2. High-level architecture

┌──────────────────────────────────────────────────────────────────────────┐
│                              Talentry AI                                 │
│                                                                          │
│   ┌──────────┐    ┌──────────────┐    ┌────────────────────────────┐    │
│   │ JD text  │───▶│ JD Parser    │───▶│     JobRequirements         │    │
│   └──────────┘    │ (rules+lex)  │    │  • role family, seniority   │    │
│                   └──────────────┘    │  • must / nice / disqual.   │    │
│                                       │  • locations, behaviour      │    │
│                                       └──────────────┬─────────────┘    │
│                                                      │                  │
│                                                      ▼                  │
│   ┌──────────────────┐   ┌──────────────────┐   ┌─────────────────┐    │
│   │ candidates.jsonl │──▶│ Loader + models │──▶│ Feature builder │    │
│   └──────────────────┘   └──────────────────┘   │ (text_blob,     │    │
│                                                 │  role signals)  │    │
│                                                 └────────┬────────┘    │
│                                                          │             │
│            ┌─────────────────────────────────────────────┴───────┐     │
│            ▼                                                     ▼     │
│  ┌─────────────────┐                              ┌────────────────────┐│
│  │ BM25 + TF-IDF   │  hybrid semantic score      │ Skill Evidence     ││
│  │ hybrid index    │─────────────────┐           │ (cluster, stuffer  ││
│  └─────────────────┘                  │           │  detection)        ││
│                                       ▼           └────────┬───────────┘│
│                          ┌────────────────────────┐        │            │
│                          │   Scorer (5 weighted)  │◀───────┘            │
│                          │   + Behavioural × mul. │                      │
│                          │   − Honeypot penalty   │                      │
│                          └──────────┬─────────────┘                      │
│                                     ▼                                    │
│                          ┌────────────────────────┐                      │
│                          │ Sort + Reasoning + CSV │                      │
│                          └──────────┬─────────────┘                      │
│                                     ▼                                    │
│                                submission.csv                            │
└──────────────────────────────────────────────────────────────────────────┘

Module → file mapping

Module File
Domain models src/talentry/core/models.py
Tokeniser + synonyms src/talentry/nlp/tokenize.py
Domain lexicons src/talentry/nlp/lexicons.py
Candidate I/O src/talentry/io/candidates.py
Submission CSV writer src/talentry/io/submission.py
Per-candidate features src/talentry/features/builder.py
Skill evidence scoring src/talentry/features/skill_match.py
Behavioural multiplier src/talentry/signals/behavioural.py
Honeypot penalty src/talentry/signals/honeypot.py
Hybrid BM25+TF-IDF index src/talentry/ranker/semantic.py
JD parser src/talentry/ranker/jd_parser.py
Scoring formulae src/talentry/ranker/scorer.py
Reasoning composer src/talentry/ranker/reasoning.py
End-to-end pipeline src/talentry/ranker/engine.py
CLI src/talentry/cli/rank.py
HTTP API (FastAPI) src/talentry/api/server.py
React UI ui/talentry-space/

3. Why not dense embeddings?

Reviewers will rightly ask: "this is a retrieval challenge - why not a sentence-transformer?" Three reasons:

  1. Budget. Loading a 90 MB MiniLM and encoding 100K text blobs is right at the edge of the 5-minute CPU budget; once you add the per-row scoring, feature building, sort, and CSV write, you have no headroom for slow I/O on the Stage 3 sandbox.
  2. Dependency surface. A serialised PyTorch model artifact is one more thing that can break reproduction; pure BM25 + TF-IDF reproduces from pip install-able libraries alone.
  3. Signal saturation. BM25 saturates on rare-term overlap and TF-IDF smooths over phrasing - and that is exactly what this dataset rewards. Adding a dense model marginally improves recall on prose-only profiles but adds noise on the keyword surface where stuffers live.

If we had two hours and a GPU per ranking call we would absolutely add a domain-fine-tuned reranker on the top 1000. We do not.


4. Composition formula

linear = 0.32·title_alignment
       + 0.22·semantic_fit
       + 0.28·skill_evidence
       + 0.12·experience_band
       + 0.06·location

final  = linear × behavioural_multiplier      ∈ [0.55, 1.20]
       − honeypot_penalty                     ∈ [0, 0.50]
       (clipped to [-0.5, 1.5])

Every constant is grounded in a specific line of the JD; see methodology.md for the rationale.


5. Determinism

  • Hot path uses no random state.
  • reference_date for behavioural recency is overridable for tests.
  • Sort tie-break: candidate_id ascending - matches the validator.
  • CSV writer enforces the exact validator invariants at write-time so any drift fails loudly in the CLI, never silently at upload.

6. Threat model - the four traps

Trap Defence
Keyword stuffer Skill evidence (endorsements × duration × proficiency)
Plain-language Tier 5 BM25 over career-description text + role-family trajectory
Behavioural twin Behavioural multiplier in [0.55, 1.20]
Honeypot Honeypot penalty subtracts up to 0.50

7. Operational notes

  • CLI: python -m talentry.cli.rank ... (see make submission).
  • API: talentry-serve (or make serve) → http://localhost:7860.
  • UI: make ui-dev (http://localhost:5173 with /api proxied).
  • Container: make docker-build && make docker-run - same image is pushed to the HuggingFace Space.