A five-stage LLM screening pipeline that evaluates a resume against job descriptions from a Talent Consultant's perspective.
If you're a recruiter, hiring manager, or job seeker who wants to know whether a resume would survive real screening — not just keyword matching — this pipeline reads it the way a sceptical human would: adversarially first, then charitably, then strategically.
Each stage is a discrete system prompt with a defined role, input, output format, and verdict logic. Stages chain output forward. The pipeline exits early on a hard rejection, so you only get the full read on candidates who clear the gate.
| Stage | Name | Role | Early exit? |
|---|---|---|---|
| 0 | ATS Simulation | 15-second triage pass — keyword surface, title signal, recency, hard filters | No |
| 1 | Reject Gate | Adversarial — builds the strongest honest case for rejection | Yes, on KILL |
| 2 | Signal Quality | Calibrates how much to trust the CV — catches oversell and undersell | No |
| 3 | JD Fit | Floor check against core requirements; reads through Stage 2 calibration | No |
| 4 | Candidate Read | Surfaces hypotheses for interview — agency language, ceiling signals, friction | No |
| 5 | TC Brief Stub | Drafts the brief a recruiter would send to a hiring manager | No |
Stage chaining: Stage 3 (JD Fit) receives the full output of Stage 2 (Signal Quality) and Stage 1 (Reject Gate) as context — it reads the CV through the calibration, not in isolation.
Running sample-resume.md against jds/example-senior-csm.md with claude-sonnet-4-6:
## Triage Summary
| Role | ATS | Gate | JD Fit |
|-----------------------------------|------|------------------|--------------|
| Senior Customer Success Manager | Pass | CONDITIONAL PASS | Plausible fit|
### Reject Gate
**Verdict:** CONDITIONAL PASS
**Case for rejection:**
- No CS platform named beyond Gainsight — JD asks for Gainsight or similar, which is met,
but depth of use is unverified
- Government sector experience mentioned once (GovTech migration) but not developed —
JD lists it as a strong plus; thin as stated
**Why this isn't fatal:** The core NRR track record (114%, 108%) and enterprise scope
(S$2.4M ARR, CIO-level relationships) clear the primary bar. The government experience
gap is a soft concern, not a hard kill.
### Signal Quality
**Reliability:** High
**Primary risk:** None
**Oversell flags:** None — metrics carry context (ARR, seat count, specific outcomes).
**Undersell flags:** The GovTech migration is described in one clause. If that account
had meaningful complexity, it's probably understated.
**Calibration note:** Read the JD fit generously on the government experience gap —
there may be more there than stated.
Full sample report: reports/example-assessment.md
git clone https://github.com/ChiefStarKid/resume-assessor.git
cd resume-assessor
pip install -r requirements.txt
# Run against example files
python resume_assessor.py --resume sample-resume.md --jd jds/example-senior-csm.md
# Run against your own JD bank (all .md files in a directory)
python resume_assessor.py --resume path/to/resume.md --jd-dir path/to/jds/- Python 3.9+
- Claude Code CLI installed and authenticated (
claudeon your PATH) - No API key needed — uses
claude -p(session auth from your Claude Code login)
pip install -r requirements.txtrequirements.txt is empty — the script uses only the standard library and the claude CLI. Install Claude Code and you're ready.
python resume_assessor.py --resume RESUME [options]
Required:
--resume PATH Resume markdown file
JD input (one of):
--jd PATH Single JD markdown file
--jd-dir DIR Directory of JD markdown files (default: ./jds/)
Output:
--output-dir DIR Where reports are saved (default: ./reports/)
--prompts PATH Prompt file (default: assessor_prompt.md next to this script)
Model:
--models MODEL[,...] Comma-separated model IDs (default: claude-sonnet-4-6)
Options: claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5-20251001
# Single resume against single JD
python resume_assessor.py --resume resume.md --jd jds/role.md
# Single resume against all JDs in a folder
python resume_assessor.py --resume resume.md --jd-dir jds/
# Run two models in sequence, save to custom output folder
python resume_assessor.py \
--resume resume.md \
--jd-dir jds/ \
--models claude-opus-4-8,claude-sonnet-4-6 \
--output-dir results/
# Override prompt file
python resume_assessor.py --resume resume.md --jd jds/role.md --prompts my_prompts.mdResume — any markdown file. The pipeline reads it as plain text.
JD — markdown file. The first # Heading becomes the role label in the report. Include a "Compulsory application questions" section if the role has screening questions — the pipeline uses them as explicit criteria in the reject gate and candidate read stages.
# Role Title — Company Name
[JD body]
## Compulsory application questions
1. Question one
2. Question twoAll stage prompts live in assessor_prompt.md, loaded by section header at runtime. Edit the prompt file freely — no code changes needed.
Each prompt defines:
- A discrete role with a single responsibility
- Input context (what it receives)
- Output format (structured markdown with named fields)
- Verdict tiers with explicit criteria
Stage 3 (JD Fit) is intentionally chained — it receives the full text output of Stages 1 and 2 in its context, so it reads the CV through the prior calibration rather than independently.
See assessor_prompt.md for the full prompt text.
The pipeline is designed around a Talent Consultant (recruiter) reading a CV against a JD. It can be adapted:
- Different screening criteria — edit the
reject_gatesection inassessor_prompt.mdto change what counts as a kill signal - Different output formats — the output format block in each section is plain markdown; change the fields to match your workflow
- Additional stages — add a new
## [stage_name]section toassessor_prompt.mdand callrun_pipeline()with the new section name - Different models per stage — the
run_pipeline()function takes a model argument; route heavy stages (reject gate, candidate read) to a more capable model if needed
resume_assessor.py — pipeline script
assessor_prompt.md — all stage prompts, loaded by section at runtime
sample-resume.md — fictional example resume for testing
jds/
example-senior-csm.md — fictional example JD
reports/ — output directory (gitignored)
What does this pipeline actually do? It reads a resume and a job description, then runs five sequential LLM prompts that simulate how a Talent Consultant would screen the candidate — not how an ATS keyword-matcher would. The output is a structured brief: triage verdict, strongest case for rejection, signal quality calibration, JD fit assessment, and a recruiter-ready candidate brief.
How is this different from an ATS or keyword scanner? An ATS checks for keyword presence. This pipeline checks for signal quality — whether the evidence behind each claim is credible, whether the metrics carry context, whether the candidate is overselling or underselling. Stage 2 (Signal Quality) explicitly flags both directions. The Reject Gate (Stage 1) is adversarial by design: it builds the strongest honest case for rejection before the rest of the pipeline runs.
Does it need an API key? No. It uses the CLI command, which authenticates via your Claude Code session. If you have Claude Code installed and logged in, you are ready.
What model does it use? by default. You can override with for higher-stakes assessments or for faster batch runs. Multi-model is supported — pass a comma-separated list and the pipeline runs once per model.
Can I run it against multiple JDs at once? Yes. Use and it will run the full pipeline against every file in the directory, saving one report per JD to the output folder.
Can I adapt the screening criteria? Yes. All stage prompts are in , loaded by section header at runtime. Edit the reject gate criteria, change output fields, or add stages — no code changes needed. The pipeline is designed to be prompt-editable.
What does the output look like? Each run produces a markdown report with: triage table, reject gate verdict and case, signal quality calibration, JD fit assessment, candidate read hypotheses, and a TC brief stub. A sample report is at reports/example-assessment.md.
- Author: Joseph Solomon · LinkedIn
- General enquiries: joseph@kainosis.com
- Bugs and feature requests: open an issue
MIT