Fabricated benchmarks
The most damaging failure mode in AI-augmented ML. The agent produces a number that looks like a measurement but came from nowhere. The number lands in a model card, a slide, a blog post, a tweet. Then someone tries to reproduce it.
Hard rule, not suggestion: no number ships unless a script measured it and the script lives in the repo.
How fabrication happens
Three pathways. All common.
1. The agent estimates instead of running
Prompt: "What's the inference latency of this model on an L4?"
Bad output: "Approximately 45ms per token, based on typical L4 performance for similar models."
The agent has invented a number. It is plausible. It is not measured. It will be wrong by a factor of 2 or more.
2. The agent confuses a similar number for the actual one
You ask for the F1 of model A on dataset X. The agent finds an F1 in the codebase — for model B on dataset Y — and reports it for model A on dataset X. Numerically it looks defensible. It is wrong.
3. The agent runs once and reports a noisy single value
Cold-start, single trial, no warmup, no comparison. The number is real but unreliable. The third decimal place is noise; the first might be too.
The rule
Every number in user-facing material must trace to a runnable measurement script committed to the repo OR a cited source with a working URL.
Disclaimers like "approximate," "preliminary," or "internal estimate" do not make fabricated numbers acceptable. They make them worse — they suggest data exists that does not.
When you do not have a measurement: leave the cell empty, write "TBD," or omit the table. Empty is honest. Fake is not.
Methodology checklist (so the measurement is also real)
Having a script is necessary, not sufficient. The script's protocol must be sound:
| Metric type | Required protocol |
|---|---|
| Throughput / latency | Warmup ≥3 calls; report best-of-N (N≥3); state protocol in result |
| Quality (F1, accuracy, etc.) | Confidence interval from CV or seed variance; state corpus, license, registers |
| Comparison vs. competitor | Pin and report the competitor's version; record bench date |
| Cost ($/inference, $/train) | Hardware spec, cloud SKU, market price as of date |
Single-run results without warmup are noise. They have caused public embarrassment when "135× speedup" turned into "21× speedup" after fixing the cold-start artifact (caught on a project of mine in April 2026).
A bench script template
# benchmarks/run_latency.py
import json, time, statistics, argparse
from pathlib import Path
def bench(model, inputs, n_warmup: int = 3, n_trials: int = 7) -> dict:
for _ in range(n_warmup):
model(inputs[0])
timings = []
for x in inputs[:n_trials]:
t0 = time.perf_counter()
model(x)
timings.append(time.perf_counter() - t0)
return {
"n_warmup": n_warmup,
"n_trials": n_trials,
"median_s": statistics.median(timings),
"min_s": min(timings),
"max_s": max(timings),
"stddev_s": statistics.stdev(timings) if len(timings) > 1 else 0.0,
"raw_s": timings,
}
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("--out", required=True)
args = ap.parse_args()
# ... load model, build inputs ...
result = bench(model, inputs)
Path(args.out).write_text(json.dumps(result, indent=2))
Now any number in a doc cites: "median 23ms over 7 trials after 3 warmups,
measured by benchmarks/run_latency.py, see benchmarks/results/2026-05-04.json."
That is what a defensible benchmark looks like.
Auditing existing docs
The agent can help here. A subagent prompt:
#.claude/agents/benchmark-auditor.md
For each numeric claim in the given file:
1. Find the script that would have produced it (search benchmarks/, eval/).
2. If no script exists, flag it.
3. If a script exists, run it and compare. Flag any > 1% drift.
4. Report a table: claim | source | currently-measured | drift.
Do not edit the file. Just produce the report.
Run before any release. Be willing to delete claims that cannot be verified.
What to do when you find a fabricated number
In your own work:
- Remove the number. Replace with "TBD" or empty.
- Decide whether to measure it (yes if it matters, no if it does not).
- Update the doc with the measured value (in the same commit).
- Add a
CLAUDE.mdrule that would have prevented it.
In someone else's work that depends on yours: politely flag, share the measurement script, encourage them to update.
The cultural piece
Fabricated benchmarks erode trust faster than any other error. A broken function gets fixed in an afternoon. A wrong benchmark in a public artifact survives in screenshots, citations, and reposts long after you correct the original.
Publish fewer numbers; make every published number defendable. The reputation compounds.