Saptashwa
LLM pipeline that scores job postings for fitNov 2026

RoleRadar

Finds engineering jobs on company boards and scores fit with a calibrated two-step LLM pipeline.

My partDesigned the pipeline, the calibration and the eval, and reviewed every change.
Agent-heavyAgents wrote most of the code.
RoleRadar's Brief screen: new strong matches with fit scores, requirement squares and pay chips, plus a status bar with run time and spend
The Brief: what's new since the last visit, and the worker's health and spend. Companies and roles are made up.
Lead result · RoleRadar, an LLM pipeline that scores job postings

21 of 21 good jobs caught, on 59 postings the pipeline was never tuned on.

21 good fits, all caught · 38 other jobs
good fit by the reference labels, and scored above the 6.0 review thresholdother test jobs; no ineligible one was marked eligibledev 40 and holdout 30: used for tuning and checking, not counted

Target: ≥ 95% recall. With 21 good jobs the 95% interval is 85–100%, so the target is met on this sample, not proven.

0ineligible jobs marked eligible
$2.31/monthat 100 new jobs a day (target ≤ $3)
5–12 sp95 per job (target ≤ 30 s)

What it does

  1. Polls 312 company job boards (Greenhouse, Lever, Ashby) every hour from a Raspberry Pi, on systemd timers. In one run, 0 boards failed.
  2. Extracts each posting's requirements without seeing my profile, then matches them and applies eligibility rules in code.
  3. Scores new jobs for about $2.31 a month (p95 5–12 s per job), with a spend cap on every run.
  4. Live as a phone-first web app I use daily: a brief, triage, a shortlist and application tracking, with an alert if the worker stops.
  5. Tracks about 8,000 open engineering jobs at 149+ companies.

The hard part

Keeping the model from flattering me. Extraction runs without seeing my profile, eligibility is decided by code rules, and the pipeline, targets and threshold were fixed before the test run.

Read the details

The reference labels were written by an agent and corrected by me, so the eval measures agreement with a reviewed reference, not with independent human labels. The limits are listed above: correlation 0.85 against a 0.90 target, and about 17% of jobs crossing the threshold between runs. The known misses come from "X or Y" requirements; a prompt fix is planned.

What was tested

RoleRadar runs on a Raspberry Pi. It reads job postings from company boards and scores how well each one fits. I designed the pipeline, the calibration and this eval. Agents wrote most of the code.

How it was measured

  • The reference labels are requirement-by-requirement analyses written by an agent (Claude). I corrected the facts about me in two review rounds.
  • I settled 47 disputed requirements by hand: the ones where at least 3 of 4 models disagreed with the reference.
  • The protocol was frozen before the run: pipeline, targets and threshold were written down before any model saw the 59 test jobs. Nothing changed after the results.

Where it falls short

  • Correlation with the reference is 0.85. The target was 0.90. Not met.
  • About 17% of jobs cross the threshold between runs (0.73 points run to run; target 0.5). Planned fix: score borderline jobs (5.5 to 7.5) twice more and average.
  • 21 good jobs is too few to prove 95% recall. The lower bound is 85%.

How it's built

Job boardsGreenhouse · Lever · AshbyPi workerfetch → normalise → upsertLLM, two stepsextract (blind) → matchCode ruleseligibility · formulaPostgreSQLSupabasePhone apptriage · tracking

What it costs to run

Monthly scoring cost at 100 new jobs a day. The cheap model met the target; the mid-tier models weren't more accurate.

$0$10$20$30$40$50$60$70Chosen: DeepSeek V4.1 FlashChosen pipeline: about $2.31 a month$2.31Mid-tier models (Terra, Sol, Sonnet)Mid-tier extractors: $14 to $70 a month, no better accuracy$14$70target ≤ $3

The cost trap: hidden reasoning

Same model, same calibration jobs, reasoning off against its default hidden reasoning.

Reasoning offDefault (hidden) reasoning
Cost per callReasoning off: $0.00058$0.00058Default reasoning: $0.0245$0.0245about 42× the costSeconds per callReasoning off: 3.7 s3.7 sDefault reasoning: 107 s107 sabout 29× slower

A 4-call smoke test against a 120-call run. One side-by-side call showed 7× the cost and 16× slower, so the size of the trap varies by job; reasoning stays off.

Show as a table
SetupCostLatency
Chosen pipeline (DeepSeek V4.1 Flash, blind extraction then matching)about $2.31 a monthp95 about 5–12 s per job
Target≤ $3 a monthp95 ≤ 30 s
Mid-tier extractors (GPT-6.1 Terra, GPT-6.1 Sol, Claude Sonnet 5.5)$14–70 a monthno better accuracy
DeepSeek V4.1 Flash, reasoning off (120 calls)$0.00058 per call3.7 s per call
DeepSeek V4.1 Flash, default reasoning (4 calls)$0.0245 per call107 s per call

What the calibration showed

Blind extraction was the real fix.

A model that sees my profile while it extracts requirements leaves out the ones I lack, which inflated scores by 0.6 to 0.9 points. Splitting extraction (blind) from matching removed most of that. Holdout correlation rose from 0.88–0.90 to 0.89–0.95.

Nine models compared.

The mid-tier models were not better extractors and cost 5 to 30 times more. Hidden reasoning was a cost trap: on the same jobs, the same model cost about 42 times more per call and ran about 29 times slower (measured in the chart above).

The simpler setup won, on a rule agreed in advance.

One model looked best on the dev and holdout sets but did not hold up on the untouched sets. The rule written down beforehand prefers the simpler setup, so a single-model pipeline was chosen.

Calibration cost $8.48 of a $13 budget, across all rounds.

The protocol, as frozen before the test

Written down on 6 November 2026, before any model saw the 59 test jobs. An excerpt:

Pipelines:
- P1 (primary): DeepSeek V4.1 Flash blind extraction (split.py SYS_X) -> Qwen 3.8 Flash matching (SYS_M). Reasoning off.
- P2: same extraction -> DeepSeek matching.
- P3: mean of P1 and P2 (same extraction).
- Each with/without the implied-language code rule (posting mostly in French/German/Portuguese/Spanish/Italian/Dutch
  and no requirement mentions that language -> add a core must-have "Professional <language>" at level N).
- Safety net "near-miss": show a job if its uncapped score is >= threshold.

Targets (pooled fresh + v4): T1 recall of good jobs (ref >= 7.5) >= 95% at the chosen review threshold;
T2 0 false-eligible, binary eligibility >= 95%; T3 auto-CV precision >= 90%; T4 corr >= 0.90, |bias| <= 0.3;
T5 consistency <= 0.5, flips <= 5%; T6 <= $3/month, p95 <= 30 s.
No changes after seeing the results; any change becomes the next round, tested on new jobs.

From FINAL_PROTOCOL.md, lines 6–12 and 19–22, unedited.

A second eval: who writes the CV

RoleRadar also drafts a tailored CV for each shortlisted job. Five writer setups and four reviewer models were compared on three real shortlisted jobs, and three agents with no context ranked the results blind, as recruiters. The cheapest pair (DeepSeek writing, Gemini reviewing) ranked first on average, and GPT 6.1 Sol's cover letters won 9 of 9. The blind review also found four pipeline bugs that no score had shown. The whole bake-off cost $1.12.

A rule change, checked on the reference set

An earlier change to the eligibility rules was checked across all 129 reference jobs. Three-way agreement went from 106 to 116, with no job wrongly marked eligible.

This set includes the jobs used for tuning, so it is a regression check, not a test. The test is the 59-job result above.

Re-applying the rules to all 768 stored scores needed no new model calls: it reuses the extractor's stored verdicts.

106 agreed before10 more after the rule change13 still differ, none wrongly eligible

Screens

A table of eligible roles sorted by fit, with requirement squares, level, years and job family
Eligible roles, sorted by fit.
A shortlist with a quick-look panel showing one role's requirements and the evidence for each
Quick look: each requirement with the evidence it was matched against.
A job page comparing the chosen role with three other open roles at the same company
Comparing roles at one company before applying.
A bar chart of open roles per company, split into eligible, unclear and not eligible
Open roles by company, split by eligibility.

Shares a stack with