Why We Let a Rival Model Grade Our AI Benchmark
Models grade their own family generously. So we gave the gavel to the candidate our winner beat, set it to temperature zero, and limited it to the questions that cannot be checked by code. Any residual bias would work against us. It still scored our model about 4.9 out of 5.
Key Takeaways
- LLM judges carry self-preference bias — they favour their own outputs and their own model family — plus position and verbosity bias. A better prompt does not remove them.
- Shrink the judge's job: deterministic graders check facts against database ground truth, tool calls, output format, refusals and traps. The judge only rates what code cannot.
- Appoint an adversarial judge. We used the winner's direct rival at temperature zero, so any leftover bias would count against the model we wanted to ship.
- Declare what is missing. Ours was a single judge with no second rater and therefore no inter-rater agreement measure.
Every internal model benchmark has the same credibility problem. You chose the winner. You wrote the tests. And increasingly, you used an LLM to grade the answers. At which point a reader is entitled to ask what exactly stopped the whole thing from flattering the conclusion you had already reached.
This is how we tried to answer that question when selecting the model behind Seal AI.
The problem with LLM-as-a-judge
Using a language model to score another model's answers is cheap, fast and scales to hundreds of outputs. It is also biased in ways that have been documented repeatedly:
- Self-preference bias. Judges rate their own outputs — and outputs from models in their own family — more generously than a neutral rater would.
- Position bias. When shown two answers, judges systematically favour one slot over the other, independently of content.
- Verbosity bias. Longer answers score higher, even when the extra length adds nothing.
None of these are prompt-engineering problems. You cannot instruct a judge to stop preferring itself any more than you can instruct a witness to stop being the defendant's brother. You handle it structurally.
Step one: give the judge almost nothing to do
The first mitigation is to shrink the judge's remit until what remains is genuinely a matter of taste.
In our benchmark, everything objective is graded by deterministic code before a judge sees anything. At the start of each run we compute ground truth directly from the analytics database — entrances, conversions, bounce rate, revenue, top channel, top source, top device — so every figure the assistant asserts can be compared against reality. Deterministic graders then check:
- Grounding — is every stated number the true number?
- Tool-calling — did the model call the right tools from the 63-tool inventory?
- Structured format — did the response validate against the schema the product expects?
- Refusals — did the model decline a task it was perfectly capable of?
- Traps — nonexistent entities, empty periods, and the injected-instruction canary.
Those graders have 26 unit tests of their own, and a separate script re-scores archived runs offline at zero token cost, so a grading change can be applied retroactively without re-querying a single model. The graders decide the outcome.
What is left for the judge is the residue that code genuinely cannot measure: is the answer useful, is it clear, is it formally precise. Scored 1 to 5, cross-model, and labelled in the report as a non-deterministic signal. Never the verdict.
Step two: appoint a judge with a motive
The second mitigation is the one we would recommend to anyone publishing an internal benchmark, because it costs nothing and removes an entire class of objection.
We made the judge qwen3-235b — one of the two candidate models our winner was competing against, and the strongest of them on several public evaluations. Not a neutral third party. The direct rival of the model we ended up shipping, run at temperature zero for reproducibility.
The logic is simple. If self-preference bias is real, it now points away from our conclusion. A rival judge has every structural reason to rate its own family's answers highly and the winner's answers less so. Any bias left in the system works against the result we were hoping for.
It scored gpt-oss-120b at roughly 4.9 out of 5.0 on usefulness, clarity and formal precision. That number is worth more than a 5.0 from a friendly judge, precisely because of who gave it.
What we still cannot claim
One judge is one opinion. With a single rater there is no way to compute inter-rater agreement, which means we cannot distinguish between "this answer was clear" and "this particular judge finds this style clear." A second independent rater — another model, or a human panel on a sample — would let us report agreement rather than ask you to take one model's word for it.
We did not do that. It is a real limitation, it is stated in the benchmark documentation, and it is the first thing we would fix in the next revision.
Rules for using LLM-as-a-judge honestly
- Deterministic first. Anything that can be checked against ground truth must be checked against ground truth. The judge gets the leftovers, not the core.
- Never judge your own family. At minimum use a model from a different lineage than the one being evaluated. Better: use the candidate it is competing with.
- Temperature zero. A judge whose score changes between runs is not a measurement instrument.
- Randomise order, watch for length. Position and verbosity bias are cheap to mitigate and embarrassing to ignore.
- Label the score as a signal. Report it next to the deterministic results, never as the headline, and never as the tiebreaker on a correctness question.
- State your rater count. One judge, no agreement measure — say so. Readers can weigh a stated limitation. They cannot weigh one you left out.
The bottom line
An internal benchmark is only as credible as its incentives. Ours were arranged so that the easiest way to get a flattering result was to actually deserve one: objective scoring in code against live database ground truth, subjective scoring by the model with the most to gain from marking us down, and the gaps written into the report rather than out of it.
The full design, graders and archived runs are documented in our internal benchmark write-up, including the first full run we threw away as invalid.
