cd /news/large-language-models/your-llm-judge-needs-a-test-suite Β· home β€Ί topics β€Ί large-language-models β€Ί article
[ARTICLE Β· art-50980] src=dev.to β†— pub= topic=large-language-models verified=true sentiment=↑ positive

Your LLM Judge Needs a Test Suite

A developer released rubric-bench v0.1, a TypeScript library and CLI that treats LLM judges as code under test by running regression tests against a golden set of cases. The tool, which scored 95.8% on a 72-case introductory statistics set, catches regressions before deployment and addresses non-determinism in LLM-as-judge evaluations.

read4 min views1 publishedJul 8, 2026

Nobody ships a payment system without tests, but teams ship LLM judges into production on vibes every day. A grader, a triage classifier, an eval pipeline's scoring model β€” if an LLM's judgment gates something users care about, its behavior is a production dependency. And unlike code, it changes when you didn't change it: a model-version bump, a quiet provider update, a prompt tweak that fixed one case and broke five others you never noticed.

The fix is boring and it works: regression tests. This is post 3 of the assessment-first series, and it ships rubric-bench v0.1 β€” a small TypeScript library and CLI that treats the grading engine from post 2 like any other code under test.

A golden set is a versioned JSON file of cases: a question (prompt, model answer, weighted rubric), one student answer, and the verdict a trustworthy grader must return: correct

, partial

, or incorrect

. A run scores a grader against every case and reports accuracy overall and per tag. A diff compares two runs of the same set, case by case; a regression is a case that passed before and fails now.

rubric-bench run  --set golden.json --out current.json --html report.html
rubric-bench diff baseline.json current.json     # exit 1 on regressions

The exit codes are the point. Wire diff

into CI, and the build that changes your grading prompt fails when it breaks a case that used to pass. Grader behavior stops being a thing you discover from user complaints and becomes a thing your pipeline tells you before merge.

The repo ships a 72-case golden set for introductory statistics: 60 genuine answers spread across correct, partial, and incorrect, written in actual undergraduate register (hedges, typos, half-remembered rules), plus 12 adversarial cases we'll get to next post. First full run of the post-2 grader on claude-sonnet-5: 69/72, 95.8%.

The three misses are the interesting part. All three were expected-partial

, graded-incorrect

β€” answers like "standard deviation is just easier to communicate than variance, so it became the convention." A human TA gives that half credit for knowing that SD is preferred while missing why (the units). The model judged the why-criterion unmet and the what-criterion unmet too, harshly but defensibly. None of the misses were expected-correct answers getting rejected, and none were wrong answers getting credit. The failure mode is concentrated exactly where human graders also disagree: the partial-credit gray zone. That's a distribution you can ship a pilot on, and precisely the region the tone-calibration work in post 5 targets.

Two engineering notes from the first run, because reality bit immediately. One API response came back with no text block and killed the whole 72-case run; the runner now captures per-case errors as failed cases with an error

field, and the reference grader retries once. And back-to-back identical runs differ by a case or two β€” LLM-as-judge non-determinism is well documented β€” so a single flipped case in a diff is noise, and a pattern of flips (three partials regressing after a prompt edit) is signal. The tool reports both; reading them is on you.

The template transfers to any LLM-judgment task β€” support-ticket triage, content moderation, resume screening:

correct/partial/incorrect

. You can't meaningfully diff 7.2 vs 6.9.Sixty cases took one focused authoring session. That's the entire capital cost of knowing, forever, whether your judge still behaves.

A grader that silently drifts mid-semester is a support catastrophe with a student body as witnesses; a triage model that drifts after a provider update mis-routes customers for weeks before anyone correlates the timing. The Dartmouth pilot this series builds on ran its whole term on one pinned model for a reason. Pin the version, bench the swap, gate the prompt edits. It's the same discipline you already apply to schema migrations, applied to judgment.

rubric-bench is regression testing, not psychometrics: it tells you the grader changed, not that it agrees with human raters at a publishable kappa; a real deployment eventually wants an inter-rater study against instructor grades, which this golden set can't substitute for. Seventy-two cases is a floor, not a benchmark; per-tag cells of 6 cases can't distinguish a real regression from noise at single-case granularity. And a golden set authored by one person inherits one person's judgment calls about partial credit β€” the honest fix is a second rater pass over the labels, which is on the roadmap.

Next post: the 12 cases I skipped. Students will put prompt injections in their homework, and what the bench found when I attacked my own grader surprised me twice.

── more in #large-language-models 4 stories Β· sorted by recency
── more on @rubric-bench 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/your-llm-judge-needs…] indexed:0 read:4min 2026-07-08 Β· β€”