DEV Community

praveenlavu
praveenlavu

Posted on Originally published at praveenlavu.com

Validate Your AI Judge With Negative Controls

The Test That Has to Fail

There is a specific kind of dread that sets in when everything looks too good.

I had spent weeks wiring an AI judge into the review layer of a generation pipeline.
The judge was an LLM we had carefully prompted to read outputs and score them against
a rubric: coherence, factual grounding, format compliance, tone. It was supposed to
be the quality gate that meant a human did not have to eyeball every single thing the
pipeline produced. In theory, a beautiful piece of leverage.

Then one afternoon I opened the evaluation dashboard and saw green across the board.
Every output from the last three batches: approved. Pass rate sitting right at the top.

I stared at it for a long time. And instead of feeling relieved, I felt the floor
tilt under me.

Because I realized I had no idea whether the judge was working or whether it had
quietly learned to approve everything.

The Problem With a Judge That Never Says No

Here is the thing about AI judges that nobody puts in the tutorial: a judge that
never flags anything looks exactly the same on a dashboard as a judge that is
genuinely evaluating and finding everything acceptable. From the outside, both
produce the same green tiles.

We built the judge in the first place because human review at scale is expensive
and slow. The pipeline was producing too much output for a person to read
everything. So the judge was meant to stand in, catch the bad stuff, and let the
good stuff through. Standard quality-gate logic.

But quality gates only work if they can actually close.

With traditional software, this is not that hard to prove. You write a unit test
that checks a function's output. You run it before writing the function and watch
it fail. The failure is the evidence that the test is real, that it is actually
checking what you think it is checking. You cannot claim a test is valid until you
have seen it fail.

With an AI judge, that discipline breaks down in a frustrating way. The judge is
not deterministic. It does not have a clean, inspectable logic path you can trace.
It is a model that was trained on patterns and is now producing judgments. You
cannot look inside and verify the wiring. You can only observe what it does.

So you run some outputs through it and it says they are fine. But fine compared to
what? What would have to be true about an output for the judge to flag it? You do
not actually know. And that not-knowing is a loaded gun sitting quietly on the table.

The Recursive Trap

The obvious instinct at this point is to validate the judge with another judge. Run
the judge on a set of outputs where you already know the ground truth, score the
judge's calls against that truth, measure accuracy.

The problem is: where does the ground truth come from?

If a human labeled the ground truth, you now need a human to be involved, which was
the thing you were trying to get away from. If another AI labeled the ground truth,
you have moved the trust problem up exactly one level. The question is now whether
you can trust the labeler, which is the same question you started with, just wearing
a different hat.

There is a version of this that works, carefully constructed human-labeled eval
sets, regularly updated, treated as a permanent fixture of the pipeline. It is
expensive to build and requires real discipline to maintain. Most teams skip it
and convince themselves the all-green dashboard means things are fine.

I was one of those teams. Until the dread sat with me long enough that I started
looking for a different answer.

What the Lab Scientists Figured Out

I had a conversation with someone who had spent years doing cell biology before
moving into software. I was describing the judge-validation problem and she gave me
a look like I was overcomplicating something obvious.

"Negative controls," she said.

In a biology lab, a negative control is a sample that is specifically prepared to
produce no signal. You run it alongside your real samples every single time you run
an assay. The negative control is not supposed to tell you anything about your
samples. It is supposed to tell you whether your assay is working.

If the negative control produces a positive result, something is wrong with your
assay. Maybe your reagent is contaminated. Maybe there was a procedural error.
Maybe the test is detecting something other than what you thought. Whatever the
reason, a positive on a negative control is a hard stop. You do not trust any of
the results from that run. You fix the assay first.

The negative control has to fail. That is the entire point. Its failure is the
evidence that the test is real.

I wrote that down and sat with it for a while. Then I started building what I
should have built six weeks earlier.

The Fixture Library

A negative-control fixture for an AI judge is an output that MUST be flagged.
Not one that should probably be flagged, not one that a careful reader might
flag. One where there is no reasonable interpretation under which the judge
should approve it.

Building the library means constructing failures deliberately. Incoherent text
that looks like a paragraph but does not follow any logical thread. Factual claims
that contradict themselves within two sentences. Required format sections that are
simply missing. Responses that are technically words but are completely off-topic
relative to the input. The kind of output that, if a human saw it, would prompt
a baffled look and a "what is this?"

The fixture library does not need to be large. It needs to cover the main failure
categories your judge is supposed to catch, with examples that are so clearly
wrong that any functioning judge should reject them. A dozen well-constructed
fixtures is more valuable than a hundred borderline ones.

Then you run the library at the start of every evaluation batch, before a single
real output gets scored. If the judge passes any fixture, the batch does not run.
You stop, diagnose the judge, fix what broke, and run the library again. Only
when every fixture fails, only when the judge correctly rejects every piece of
known-bad output, do you trust it with the real work.

That is the discipline. And it is not glamorous. Building the fixture library
takes a few hours and produces nothing you can show a stakeholder. It does not
make the pipeline faster or the outputs better. It just makes the judge honest.

A Test Suite That Never Fails Is Telling You Something

After I added the negative-control layer, the first thing that happened was that
the judge failed three fixtures I was confident it would catch. The failures were
in a category I had not thought to tune for. I spent a day fixing the judge's
prompt, rerunning, failing, adjusting again. Uncomfortable. Slow. Exactly what I
did not want to spend time on.

But here is what changed: when the dashboard finally went green after that, I
actually believed it.

The principle I took away is one that applies anywhere you are testing something
that does not have a deterministic, inspectable core. A test suite that never
fails is not evidence of quality. It is evidence of blindness. Either the tests
are not checking what you think they are checking, or the system has found a way
to pass them without doing the real work, or both.

The only honest quality gate is one that you have personally seen close.

If you are building AI evaluation into a pipeline and you have not yet built the
fixtures designed to make the judge fail, the all-green dashboard is not your
friend. It is just the absence of evidence pretending to be evidence of absence.

Build the tests that have to fail. Run them first. Trust the rest only after.

Top comments (1)

Collapse
 
vinhnguyenthanhdn profile image
Vinh Nguyen

Negative controls prove the judge can reject obvious failures, but they do not show whether it rejects acceptable outputs or whether borderline scores are calibrated. Pair them with a small known-good control set, then record the model, prompt, rubric, temperature, and outcome distribution across repeated runs. That gives you both sensitivity to known failures and a check against false positives or sampling instability.