Recruiter-Pro
CV screening against a job corpus: parse, extract, score, explain.
Source (opens an external site)Project site (opens an external site)Live app (opens an external site)LLM explainer runs locally

Problem
A CV has to be scored against every role in an 800-job corpus, and each score has to come with a reason a recruiter can check, even when no language model is reachable.
Source · Recruiter-Pro/README.md:24-25,183-193 · as of4-agent pipeline (parser, extractor, scorer, explainer) in one deployable; the agents are function calls, not services.
Source · Recruiter-Pro/README.md:131-139,198-207 · as ofFastAPI backend and a Next.js 16 frontend.
Source · Recruiter-Pro/requirements.txt:32; frontend/package.json:15 · as ofExplainer providers: Ollama over HTTP, OpenRouter, and a rule-based fallback.
Source · Recruiter-Pro/README.md:183-187; src/agents/explaining/__init__.py:30 · as ofCI runs ruff, black, mypy, pytest with a coverage floor, corpus validation and a secrets check.
Source · Recruiter-Pro/.github/workflows/ci.yml:43-102 · as of
Architecture
Scroll sideways for the full diagram.
- 01Client → APIREST / JSON
- 02API → 1 Parserdispatch
- 031 Parser → 2 Extractclean text layer
- 042 Extract → 3 Scorerstructured profile
- 053 Scorer → 4 Explaintop-K matches
- Client
- Next.js 16, :3000
- API
- FastAPI; 10 MB cap, 5/min per IP
- 1 Parser
- pdf, docx, txt
- 2 Extract
- 679 canonical skills
- 3 Scorer
- 5 weighted rules + ML; 800 roles
- 4 Explain
- top-K only; ollama, openrouter, rule_based
Key decisions
- 01
ADR-1: LLM allocation across the four-agent pipeline.
Source · Recruiter-Pro/docs/adr/001-llm-allocation.md:1 · as of - 02
ADR-2: an LLMProvider protocol for the explainer, so CI runs the rule-based provider with no network or key.
Source · Recruiter-Pro/docs/adr/002-llm-provider-abstraction.md:1; .github/workflows/ci.yml:69-72 · as of - 03
ADR-3: one unified skill vocabulary, so React, ReactJS and React.js resolve to one skill.
Source · Recruiter-Pro/docs/adr/003-unified-skill-vocabulary.md:1; README.md:136 · as of - 04
Every match records which provider wrote its explanation, and the UI prints it.
Source · Recruiter-Pro/README.md:189-193,245 · as of
Evidence
- Branch coverageCI floor 81%
- 84.07%
- Source · Recruiter-Pro/README.md:37; .github/workflows/ci.yml:86 · as of
- TestsREADME states 544 and 530 in different places
- 500+
- Source · Recruiter-Pro/README.md:36,433 · as of
Screenshots
Stack
- Python
- FastAPI 0.111.0
- scikit-learn
- Ollama (HTTP)
- pytest
- Next.js 16.3.0
- React 18.3.1
- TypeScript 5.4.2
- GitHub Actions
Limits
A hosted deploy without an OpenRouter key serves rule-based explanations; Ollama runs locally only.
Source · Recruiter-Pro/README.md:185-189 · as of