Without an eval set, every change to a prompt or a retrieval pipeline is judged by trying a couple of inputs and forming an impression. That impression is unreliable, does not survive the week, and cannot tell a real improvement from noise in a non-deterministic system.
An eval set fixes the inputs so the only thing varying is your system.
What one looks like
Not much:
export const evalSet = [
{
id: 'refund-outside-window',
input: 'I bought this 45 days ago and want a refund',
expects: { policy: 'refund-window', mentionsDays: 30, escalates: false },
},
{
id: 'refund-damaged',
input: 'Arrived cracked, bought yesterday',
expects: { policy: 'damaged-goods', escalates: true },
},
]Note what expects holds: checkable properties, not an exact expected string. Demanding an exact match against generated prose fails on harmless rewording and teaches you nothing. Assert the things that must be true.
Where the cases come from
The best eval sets are grown, not authored. Every case should come from somewhere real:
- Production failures. The single richest source. Something went wrong, so it becomes case number 41 and never regresses silently again.
- Support tickets and user reports, which is where the inputs you did not imagine live.
- Edge cases you deliberately reasoned about, clearly marked as synthetic so you know which parts of the set reflect reality.
Twenty cases drawn from real failures beat two hundred you invented at a desk.
Keeping it honest
- Freeze it. An eval set you edit whenever it disagrees with you measures nothing. Add cases; resist rewriting them to pass.
- Hold some back. If you tune against every case, you have fitted to the set. Keep a slice you look at rarely.
- Record the score, not just the pass. "31 of 40" tracks progress; "it works" does not.
Related terms
LLM-as-judge
An LLM-as-judge uses one model call to score the output of another against a rubric. It is how you evaluate fuzzy, open-ended work at scale when there is no single correct answer to match against.
Read definition →ConceptRubric
A rubric is the explicit set of criteria a judge scores against, with each level spelled out. Without one, asking a model to rate quality from 1 to 10 produces numbers that mean nothing and drift between runs.
Read definition →PatternValidatedPairwise comparison
Pairwise comparison asks which of two outputs is better rather than scoring either in isolation. Relative judgements are far more consistent than absolute ones, which makes it the reliable way to tell whether a change actually helped.
Read definition →AntipatternProvenGoodharting
Goodharting is optimising a system until it satisfies the metric rather than the goal the metric stood for. Your eval score climbs, real quality does not, and the number you trusted is now the thing hiding the problem.
Read definition →