Leer en español · Lire en français · Auf Deutsch lesen
Section 12.5 of 12.8 · Advanced · 28 min read
Evaluating and testing AI-enabled systems
Video lesson
5 min · narrated, with captionsListen only (audio)
Read the transcript
How do you test a component whose answers vary, and can change overnight with no change to your code? This lesson shows how professionals evaluate probabilistic systems.
Checking a calculator is easy: two plus two must give four. Checking an essay is harder, because many different essays deserve full marks. Exam boards cope by writing a marking scheme, and marking a large sample of scripts. They use several markers, compare their marks, and re-check borderline cases. Testing an assistant built on artificial intelligence, or AI, works the same way. The result is an estimate with a margin of error, not a simple pass or fail.
Conventional tests assert exact behaviour. A model breaks that. The same input can give different outputs, because the model samples. Many outputs can be equally correct. A good answer to a customer asking where their order is can be worded a hundred ways. And behaviour can change with no change to your code, when a provider updates a model. So the useful statement is a measurement: the assistant handles ninety three per cent of refund questions correctly, plus or minus three points. Public benchmarks say little about your task. Reliable teams build their own evaluations, or evals, and treat them as the executable specification.
The most valuable asset in evaluation is the golden set: a versioned collection of realistic cases, each with its expected outcome. Cases come from sampled production traffic, domain experts, incidents and complaints, and red teaming. Split the set into slices, by intent, language or difficulty, so that a regression in one slice isn't hidden by an improvement in another. Keep a held-out part that nobody looks at while tuning prompts, or the score will overstate quality. And add every confirmed production failure as a new case.
Most teams use a model as the judge, because it scales. But it has biases. In pairwise comparisons it tends to favour one position, usually the first. It rates longer answers higher, even when they add nothing. It may favour answers from its own model family, and it can even be manipulated by text in the answer it's judging. So treat the judge as an instrument to calibrate. Use specific criteria, run pairwise comparisons in both orders, and measure its agreement with human labels before you trust it.
Evaluation is a loop. It starts with the golden set. Every change runs offline evals, a gate that compares the candidate with the baseline. Versions that pass go to an online test, such as a canary on a small share of users, and then to full production. In production, monitoring samples one to five per cent of conversations for scoring by a judge model and by people. Red teaming attacks the system on purpose, looking for injection, abuse and leaks. Triage labels the failures, drift and complaints they find, and adds them to the golden set. So each bug is fixed once, and stays fixed.
Here's an evaluation suite for the support assistant. Its golden set has six hundred cases, including a hundred and fifty allergen questions and fifty adversarial ones. A hundred and twenty are held out. Two support leads label two hundred cases, and the judge agrees with them on a hundred and eighty two. But of the fifty answers the humans failed, the judge passed eight. So the rubric is tightened. The thresholds: task success at least ninety per cent, policy compliance at least ninety eight, and zero ungrounded allergen answers, as a hard gate. Three hundred and sixty eight of four hundred cases pass: ninety two per cent. But with a sample that size, the true figure is probably between eighty nine and ninety four. Zero failures in a hundred and fifty allergen cases still allows a true failure rate of up to about two per cent. So a guardrail also blocks any allergen answer without a cited source. At the section's illustrative prices, a full run costs about two dollars twenty to generate and six dollars seventy five to judge. That's far less than an hour of expert review.
A regression eval is a fitness function for behaviour. It runs whenever a prompt, model version, retrieval setting, tool or guardrail changes. Even a one word prompt edit counts. Suites are tiered. A smoke set of thirty to a hundred cases runs on every pull request, and the full golden set runs nightly and before every release. Because outputs vary, compare the candidate with the baseline on the same cases, with a margin that reflects the measured noise. And hard constraints, such as never approving a refund above policy, block the release on any single failure.
The full section also explains how this course's written answers are marked by a model, with its guards and limits. Next, in Section twelve point six, we look at guardrails and safety. See you there.
What you need to know
- AI components are probabilistic, have many acceptable outputs and can change without a code change, so evaluation measures pass rates over distributions of cases, with confidence intervals, rather than single test results.
- A golden set is a versioned, stratified collection of cases with expected outcomes, drawn from production, experts, incidents and red teaming; a held-out part must never be used for prompt tuning.
- Scoring combines deterministic checks, reference metrics, task success, human rubric scoring, LLM-as-judge and user signals; each has distinct strengths and blind spots.
- LLM judges show position, verbosity and self-enhancement biases (Zheng et al., 2023) and can be injected; calibrate them against human labels, use specific criteria and pin their versions.
- Offline evaluation compares versions on the same cases before release; online evaluation (shadow, canary, A/B tests) measures real outcomes; monitoring and red teaming feed new failures back into the golden set.
- Regression evals in CI act as fitness functions for behaviour, triggered by any change to prompts, models, retrieval or tools, with zero-tolerance gates for hard constraints.
- Small samples give wide error bars: zero failures in 150 cases still allows a failure rate of about 2%, so unacceptable failures need design-time guardrails as well as evaluation.
Why testing probabilistic systems is different
Conventional tests assert exact behaviour: given this input, the function returns this output, every time. A component built around a language model breaks all three assumptions in that sentence. The same input can produce different outputs because the model samples from a probability distribution (section 12.1); many different outputs can be equally correct, because a good answer to where is my order?
can be worded a hundred ways; and the behaviour can change without any change to your code, because a provider updates a model, a retrieval index is refreshed or a tool returns new data. A single passing test therefore proves little, and a single failing one does not necessarily mean the system is broken.
The unit of evaluation consequently shifts from the individual test case to a distribution of cases. The useful statement is not the assistant answered this refund question correctly
but the assistant handles 93% of refund questions correctly, plus or minus 3 points, and has never approved a refund above policy in 400 attempts
. That is a measurement with an uncertainty, much like a latency percentile in Chapter 2. Evaluation of AI systems is closer to experimental science, with samples, error bars and controls, than to unit testing.
Two further differences matter architecturally. First, the system under test is the whole pipeline, not the model: the prompt template, retrieval, tool definitions, post-processing, guardrails and model version together produce the behaviour, and a change to any of them can improve one task and silently damage another. Second, public benchmarks of models (general knowledge, coding or maths leaderboards) say little about your task, your data and your users. A model that ranks higher on a leaderboard can perform worse on your support conversations. Teams that ship reliable AI features almost always build their own evaluations (usually shortened to evals) and treat them as the executable specification of the behaviour they want.
Evaluation datasets and golden sets
A golden set is a curated, versioned collection of inputs with the expected outcome for each: an exact answer where one exists, a reference answer, a list of facts the answer must contain, or the rubric by which it will be judged. It is the most valuable asset in an AI evaluation programme and usually the most neglected.
Good cases come from several sources. Sampled production traffic (anonymised, see section 12.8) shows what users really ask. Domain experts write the cases that matter most, such as allergen questions or refund disputes. Edge cases come from incidents and complaints. Adversarial cases come from red teaming. Synthetic cases generated by a model can fill gaps quickly, but people must review them, because a model tends to produce questions that resemble what it already handles well.
Structure matters as much as size. Stratify the set into slices (by intent, language, customer type, channel, difficulty) so that a regression in one slice is not hidden by an improvement in another. Keep a held-out portion that nobody looks at while tuning prompts: if engineers iterate on a prompt until the golden set passes, the golden set has become training data and its score overstates real quality, the AI form of Goodhart's law met in section 3.8. Version the dataset alongside the code, record which version produced which score, and add every confirmed production failure as a new case, so that each bug is fixed once and stays fixed.
Ways of scoring an output
| Method | What it checks | Strengths | Weaknesses |
|---|---|---|---|
| Deterministic checks | Valid JSON against a schema, required fields, citation present, banned phrases absent, correct tool chosen, length limits | Cheap, fast, exact, run on every change | Only checks form and simple facts, not whether the answer is right or helpful |
| Exact match and reference metrics | Output equals or overlaps a reference (exact match, F1 over extracted fields; BLEU or ROUGE for text overlap) | Objective and reproducible for classification and extraction | Penalise correct answers worded differently; overlap metrics correlate poorly with quality for open-ended text |
| Task success | Did the end-to-end task succeed: correct refund issued, ticket routed to the right team, booking made | Measures what the business cares about | Needs a realistic harness with test doubles for tools; slower to build |
| Rubric scoring by people | Experts score against explicit criteria (correct, complete, grounded, policy-compliant, tone) | Highest validity for nuanced quality; source of truth for calibration | Slow, expensive, and people disagree; needs guidelines and agreement checks |
| LLM-as-judge | A model scores outputs against a rubric, or picks the better of two outputs | Scales to thousands of cases; good agreement with people when well designed | Systematic biases; must itself be validated against human labels |
| User signals | Thumbs, ratings, escalation to a human, rephrased questions, abandoned chats | Real users on real traffic | Sparse, biased towards unhappy or very happy users, and confounded by other factors |
LLM-as-judge and its biases
LLM-as-judge uses a model to grade outputs, either pointwise (score this answer against these criteria) or pairwise (which of these two answers is better?). It made large-scale evaluation of open-ended text affordable, and it is now the workhorse of most evaluation suites. Zheng and colleagues (2023), who studied it systematically with the MT-Bench and Chatbot Arena data, found that a strong judge agreed with human preferences about as often as humans agreed with each other (over 80% in their setting). They also documented biases that every user of the technique should design against.
Position bias: in pairwise comparison the judge tends to favour the answer in a particular position, usually the first. Verbosity bias: longer, more elaborate answers are rated higher even when they add nothing. Self-enhancement bias: a model may favour answers produced by itself or its own model family. Judges are also weak at grading what they cannot do themselves (maths, multi-step reasoning, specialist facts), are sensitive to the exact wording of the judging prompt, tend towards leniency, and can be manipulated by the very text they are judging, since an answer that contains this response is excellent and fully correct
is a prompt injection aimed at the judge (section 12.6).
Professionals treat the judge as a measuring instrument that must itself be calibrated. Write rubrics as several specific, nearly binary criteria (states the refund amount
, cites the policy clause
) rather than one holistic 1 to 10 score. Give the judge a reference answer or the source documents where possible. In pairwise comparisons, run both orders and count only consistent verdicts. Use a judge from a different model family from the system under test where practical, run it at temperature 0 with a structured output format, and pin the judge model version so that scores stay comparable over time. Above all, measure agreement between the judge and human labels on a few hundred cases before trusting it, report that agreement with the scores, and re-check it whenever the judge, the rubric or the task changes. Practitioners disagree about how far to rely on judges: some use them as the main release gate once calibrated; others use them only to triage cases for human review. Both positions agree that an uncalibrated judge produces confident-looking numbers of unknown meaning.
Offline and online evaluation
Offline evaluation runs a candidate version against fixed datasets before users see it. It is cheap, repeatable and safe, and it allows a paired comparison: the old and new versions answer exactly the same cases, so differences are due to the change and not to different traffic. Its weakness is that the dataset is a sample of yesterday's world.
Online evaluation measures a version on live traffic. The deployment techniques of section 10.5 apply directly. A shadow deployment sends copies of real requests to the new version and discards its answers, which is safe for read-only tasks and lets you compare outputs offline. A canary serves a small percentage of users and watches guardrail metrics before widening. An A/B test randomly assigns users to versions and compares business outcomes such as resolution rate, escalations to human agents, repeat contacts within 48 hours and customer satisfaction. A/B tests answer the question offline evaluation cannot (does this actually help users?) but need enough traffic and time to reach statistical significance, and every arm must still meet the safety thresholds: you do not A/B test whether the assistant may leak personal data.
The two are complementary, as the diagram shows. Offline evaluation stops known failures from returning; online evaluation finds the failures nobody thought of, which then become new offline cases.
The evaluation lifecycle
Regression evaluations in CI as fitness functions
A fitness function is an automated check that an architectural characteristic still holds. A regression eval is a fitness function for behaviour: it runs whenever anything that shapes the model's behaviour changes (a prompt template, a model version, retrieval settings such as chunk size or top-k, a tool description, a guardrail rule) and fails the pipeline if quality drops below a threshold or below the current production baseline by more than an agreed margin. Treat prompts and model identifiers as code for exactly this reason: a one-word prompt edit is a behaviour change and deserves the same gate as a code change (section 12.7).
Because model calls are slow and cost money, evaluation suites are usually tiered. A smoke set of 30 to 100 cases with deterministic checks runs on every pull request in a few minutes. The full golden set with judge scoring runs nightly and before every release. Expensive human review is reserved for release candidates and for disagreements between judge and baseline. Non-determinism makes naive thresholds flaky, so compare against the baseline on the same cases, run uncertain cases more than once, and set thresholds with a margin that reflects the measured run-to-run noise. Hard constraints (never approve a refund above policy, never state an allergen as absent without a source) are expressed as zero-tolerance checks that block the release on any failure, while softer qualities (tone, concision) are tracked as trends.
def gate(results, baseline, margin=0.02):
# results: one dict per golden case, from the candidate version
hard = [r for r in results if r["slice"] == "allergen" and not r["grounded"]]
if hard:
return False, f"{len(hard)} ungrounded allergen answers"
for name in ("task_success", "policy_ok"):
score = sum(r[name] for r in results) / len(results)
if score < baseline[name] - margin:
return False, f"{name} {score:.1%} vs baseline {baseline[name]:.1%}"
return True, "ok"Monitoring in production
Once live, an AI feature can degrade without any deployment. Drift takes several forms: the inputs change (a new menu, a new country, a viral complaint), the knowledge sources change (stale or newly contradictory documents in the retrieval index), the world changes so that yesterday's correct answer becomes wrong (a new refund policy), or the model changes because a provider updated the model behind an alias. Pin dated model versions where providers offer them, and treat an upgrade as a release that goes through the gate.
Monitoring therefore adds quality signals to the usual observability of latency, errors and cost. Typical practice is to sample a small fraction of conversations (1 to 5% is common) for automatic judge scoring, a smaller fraction for human review, and to chart the results per slice with alerts on drops. Implicit signals are cheap and plentiful: escalations to a human, users repeating or rephrasing a question, abandoned sessions, refunds reversed by staff. Explicit feedback (thumbs up or down) is valuable but sparse and skewed. Track the distribution of inputs too, for example the share of each intent and of questions the classifier cannot place: a rising unknown
share is an early warning that the golden set no longer represents reality. Production logs used for evaluation contain personal data, so access, retention and anonymisation must be designed in from the start (section 12.8).
Red teaming
Red teaming is deliberate adversarial testing: people, sometimes helped by automated attack generators, try to make the system misbehave. Targets include jailbreaks that bypass content policies, prompt injection through documents or tool results, leaking the system prompt or other customers' data, abusing tools (issuing refunds, sending messages), producing harmful or defamatory content, and running up cost. Red teaming is most valuable before launch and after significant changes, by people who did not build the system. Open-source tools can generate large numbers of known attack patterns, but creative human testers still find the failures specific to your domain. Every successful attack becomes a regression case, and the patterns found inform the guardrail design of section 12.6. Red teaming finds problems; it can never show their absence.
Worked example
Worked example: an evaluation suite for the support assistant
The food-delivery platform's support assistant (section 12.2) answers order-status questions, handles missing-item and late-delivery claims through a refund tool, answers allergen questions from restaurant data and escalates to human agents. The team designs its evaluation suite before launch. All prices are illustrative.
| Golden set | 600 cases: 100 each for order status, missing items, late delivery and account changes; 150 allergen questions; 50 adversarial cases (injection, abuse, out-of-scope). 120 cases are held out and never used while tuning prompts. |
|---|---|
| Scoring | Deterministic checks (valid tool call, refund amount within policy, citation present) plus a judge scoring four binary criteria: correct, grounded in the retrieved data, policy-compliant, appropriate escalation. |
| Judge calibration | Two support leads label 200 cases. Judge and humans agree on 182 (91%); Cohen's kappa is 0.76. But of the 50 answers humans failed, the judge passed 8 (16%), so judge-only release decisions would overstate quality. The rubric is tightened and agreement re-measured. |
| Thresholds | Task success at least 90%; policy compliance at least 98%; allergen answers: zero ungrounded answers (hard gate); no case may regress from pass to fail on two consecutive runs without review. |
| Confidence | 368 of the 400 cases in the four main intents pass (92%). The 95% Wilson interval is about 88.9% to 94.3%, so a reported 92% really means probably between 89% and 94%. |
| Zero failures | 0 ungrounded answers in 150 allergen cases. By the rule of three, the true failure rate could still be up to about 3/150 = 2% (95% confidence). Evaluation alone cannot prove safety here, so a guardrail also blocks any allergen answer without a cited source. |
| Detecting regressions | Detecting a drop from 92% to 89% between two independent samples with 80% power needs about 1,500 cases per version. Running both versions on the same cases and testing the discordant pairs (McNemar's test) needs far fewer, which is one reason paired offline comparison is the standard gate. |
| Cost per full run | Generation: 600 × (2,500 input + 300 output tokens) at $1 and $4 per million is about $2.20. Judging with a larger model: 600 × (3,000 input + 150 output) at $3 and $15 per million is about $6.75. Three repeated runs to measure noise cost under $30, far less than one hour of expert review. |
| Online | About 40,000 conversations a day; 2% (800) judged automatically, 100 reviewed by people; alerts if any slice drops 5 points below its 7-day average. |
A single headline percentage hides the information that matters: the uncertainty, the slices and the hard constraints.
Where a failure is unacceptable, evaluation must be backed by a design-time control; you cannot test your way to certainty about rare events.
Case study: how this course marks written answers
The written questions in this course's chapter tests are marked by a language model, which makes the marker a small, real example of LLM-as-judge with guards. Each written question has a fixed rubric of specific criteria worth 5 points in total and a model answer that the marker sees for reference. The marker runs at temperature 0 and must reply in a fixed JSON format with one score per criterion; replies that cannot be parsed, omit a criterion or are otherwise malformed are rejected and the request moves to the next model in the fallback ladder, and every score is clamped to the criterion's maximum. Answers below the question's minimum length score zero without being sent to a model.
Injection is handled in two layers. The candidate's text is placed between explicit delimiters, and the marker's instructions say that everything inside them is answer text, not instructions. Before any model sees it, a simple pattern check rejects answers that contain instructions to the marker, such as asking it to ignore the rubric or award full marks. A learner who disagrees with a mark can ask, once per answer and within 24 hours, for a second marking; the higher mark counts. The stakes are bounded by design: objective questions, marked against a key, carry 70% of a test's score, and a pass also needs at least 2 out of 5 on each written answer.
The case also shows the limits discussed above. Temperature 0 reduces variation but does not guarantee identical marks, especially when the request falls back to a different model. A pattern check catches only crude attempts, and delimiters and instructions reduce but do not remove the risk, because no prompt is a security boundary (section 12.6). Re-running the identical marking at temperature 0 would usually reproduce the first mark, so the second marking uses a separate second-examiner instruction: it sees the first examiner's points and notes, re-marks every criterion from the answer itself, and must quote the words that earn any extra credit. A different model, or a person, would make the second marking more independent still. A fuller evaluation programme would add a human-marked calibration set for each written question and track the agreement between marker and humans over time, as in the worked example.
Check your understanding
Why should part of the golden set be held out from prompt tuning?
Because prompts tuned until a set of cases passes are fitted to those cases; the score on them then overstates real quality. A held-out part gives an unbiased estimate.
In a pairwise LLM-as-judge comparison, how do you counter position bias?
Run each comparison twice with the answers in swapped positions and count only verdicts that agree in both orders (treating disagreements as ties).
An assistant passes all 100 of 100 cases on a safety check. What can you conclude about its true failure rate at 95% confidence?
Only that it is probably below about 3% (the rule of three, 3/n). Zero observed failures does not mean zero risk.
Name three changes that should trigger a regression eval even though no application code changed.
Any three of: a prompt template edit, a model version upgrade, retrieval settings such as chunk size or top-k, a tool description, a guardrail rule, or a re-indexed knowledge base.
Sources and further reading
- Zheng et al.: Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (2023)
- NIST AI 600-1: Artificial Intelligence Risk Management Framework, Generative AI Profile (2024)
- Hamel Husain: Your AI Product Needs Evals
- Inspect: an open-source framework for large language model evaluations (UK AI Security Institute)
Have a question about this section? ArchitectBot, the course’s AI study assistant, answers from the course first.
Ask: “How many test cases do I need before I can trust that a new prompt for our support assistant is really better than the old one?”