The scripts are in the repository, not in the installed package. Clone it,
then
cd recipes/02-measure/is-your-eval-any-good before running the commands below. Browse this recipe on GitHub.Run it
The six checks
The three the comparison gets
These only run when you pass two arms, and they are the ones that invalidate a result outright rather than weakening it.- Are the two arms different models? If both arms carry the same
policy_version, nothing in the rows says which weights produced which. Base and every adapter can share a served model name, so passadvanced={"model_version": "my-agent-base"}and"my-agent-sft"to tell them apart. - Did both arms face the same user? If the simulated user runs on the model
under test, the trained arm talks to a different person than the base arm did.
The delta then measures the pair, not the policy. Pin
user_model=to one fixed model on both arms. - The comparison itself, reported but explicitly not readable when either of the above failed. An interval that excludes zero is not a result when the arms differed in something other than the weights.
Reading it
ok means the check passed. WARN means it could not be verified, usually
because the rows do not carry what it needs. BAD means it failed and the
number above it should not be quoted.
The order matters. Work top down: there is no point tightening an interval on
an eval that is at ceiling, and no point reading any interval at all if the two
arms were not the same setup.
Two things this deliberately does not do. It does not tell you your model is
good, only whether your eval can tell you. And it never rewrites a number: when
a comparison is unreadable it prints the delta and the interval anyway, next to
the reason not to use them, because a number quietly suppressed is a number
someone re-derives by hand later.
Where else it shows up
pass_at(rows) for the first two checks and .headroom, group_signal(rows)
for mixed-verdict counts, eval_variance(a, b, c) for self-noise,
reward_correlations(rows) and hack_scan(rows) for the judge,
decontaminate(train, eval) for overlap, and delta_report(before, after)
for the full comparison with per-marker regressions and the over-optimization
verdict. This recipe is those calls in the order that stops you wasting a GPU
hour.
Next
Every checkok on your own arms: the interval is a result, so pick the rows
worth training on with 03-select/schema. A BAD
on room to move or contains the behaviour: the eval needs harder situations
before another run means anything, and
eval-your-agent is where the markers that make a
criterion fail get written.
References
- Lambert, N. Reinforcement Learning from Human Feedback. arXiv:2504.12501, 2025. Chapter Evaluation.
- Zheng, L. et al. Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena. NeurIPS 2023. arXiv:2306.05685.
- Lambert, N. et al. Tülu 3: Pushing Frontiers in Open Language Model Post-Training. arXiv:2411.15124, 2024.