Kratoq
← All Bench Notes
POST C / 4 · FLAGSHIP·HOW WE MEASURE·2026

How to test an LLM change without fooling yourself

We turned a knob, ran it once, and the output looked sharper. Nearly shipped it. Then we ran it a few more times and most of that improvement went away. The setup below is what we use now to tell a real gain from a lucky run before it reaches users.

taskCh.1 Foundation synthesis
methodfrozen retrieval
judges2 model families
replicatesn = 4

There's a new model or reasoning setting almost every week, and it's easy to try one, glance at the result, and decide it's better. That glance is the problem. A single run tells you very little, and it will cheerfully confirm whatever you were hoping to see. So we built a small rig to check properly. It is not a study — the samples are far too small — but it has caught us being wrong more than once.

1 · Change exactly one thing

frozen retrieval

Most bad comparisons move two things at once. We move one. The evidence stays frozen — the same eight vetted sources on every run — and the prompt is the real one, imported straight from the app instead of retyped, so we're testing what actually ships. Then we change a single knob: the model, the reasoning effort, or the length instruction. Whatever shifts in the output came from that knob. It's cheap, too. There's no live search to pay for, so a full grid is minutes and a few dollars.

Fig.C1the rig · one variable moves
HELD CONSTANT8 fixed sourcesreal promptimported, not retypedvary ONE knobmodel · effort · lengthN cellsany Δ ⇒caused by that knob
Isolate the variable. Hold evidence + prompt fixed, move one knob, and the comparison is fair by construction — no live search, so a whole grid is minutes and dollars, not hours and a budget.

2 · Grade blind — and let the other model grade too

self-preference is real

A model grading its own output tends to like what it sees. So we stripped the labels off every candidate and had both families grade — Opus marking Sonnet's work, Sonnet marking Opus's. The two defaults came out level, 4.68 to 4.68. What mattered was the next part: change the grader and the order stayed put. Opus scored at least as high as Sonnet whether Opus or Sonnet held the pen. Had only one judge called it a tie, we wouldn't have trusted it.

Fig.C2composite /5 · who graded whom · axis 4.50–4.85
4.604.704.804.504.784.634.604.60Opus's workSonnet-5's work
graded by Opusgraded by Sonnet-5
Grade across families. Opus's own judges rated its work a shade higher than Sonnet's judges did (4.78 vs 4.63); Sonnet's judges showed no such self-lift (4.60 = 4.60). The mild self-preference never flipped the order — Opus scored ≥ Sonnet no matter who held the pen — and the two defaults themselves tied at 4.68/5.

3 · Then replicate — because one run will lie

the run that nearly fooled us

Here is the moment. At maximum reasoning effort, the first output caught two methodological points the default had skipped — a 75% jump on our depth measure, and enough to justify paying for the expensive setting. Then we ran it three more times. Those two points never came back once. Over four runs the gap collapsed into ordinary run-to-run scatter, and the methodology that actually carries the brief showed up at both effort levels every time. One run is a story you tell yourself. You only see the pattern when you repeat it.

Fig.C3max effort · depth vs default · n=1 → n=4

what n=1 suggested

+75%

first run caught 7 vs 4 points

what n=4 showed

+25%

5.0 vs 4.0 — within scatter

max depth per run: 7 · 5 · 4 · 4. The two "extra" insights appeared in one run and never again; the load-bearing method was in every run, both effort levels.

4 · The method caught our own mistakes

two honest edges

The judge's blind spot. To save tokens, we handed the graders a shortened version of the sources. They flagged "fabrications" — except the flagged details were sitting right there in the full sources, just missing from our short copy. The eval was manufacturing the very problem it was meant to catch. Fix: give the graders the whole source, not your abridged one.

The cost mirage. We first read cost straight off the dev CLI. It drags along its own cached system prompt, which pushed the reported number up 3–4× and even flipped which model looked cheaper. You have to recompute against list prices for whatever you'll actually deploy on. The figure your dev tool prints is not that figure.

The checklist

the checklist we wrote ourselves

  1. 01Freeze everything except the one variable you are testing.
  2. 02Import the real production prompt — never retype a clean copy.
  3. 03Anonymize candidates; grade across model families, not just your own.
  4. 04Replicate. One good run on its own proves nothing.
  5. 05Give judges the complete evidence, not a convenient summary.
  6. 06Measure cost on the real deployment shape, not the dev CLI.

Bench note · honest edges

One case, one step of the pipeline, small n, and depth scored by a keyword probe rather than a blind human. Directional, not conclusive. We ran the method on our own numbers too, which is the only reason we can point at these holes.