Module 18 of 30
Evaluation & Testing

Agents fail differently than software. Non-deterministic outputs need rubric scoring, a judge you’ve validated, regression suites and curated datasets — so quality drift is caught before users see it.

Track 5: Guardrails & Safety ⏱ ~22 min read · 6 concepts 18 / 30
Concept 1 of 6

Right or wrong becomes better or worse

Agent testing breaks three assumptions of ordinary software testing. Non-determinism: the same input gives different, equally valid outputs, so assert response == expected can’t work — even temperature 0 doesn’t fully remove variation.

Trajectory: success depends on the whole path of tool calls and decisions, not just the final answer. Subjective quality: outputs are better or worse, not right or wrong. So you score each output on several dimensions with a rubric, and decide with statistical thresholds instead of a single pass/fail.

Concept 1 of 6

A vending machine versus a new hire

BEFORE: Testing an API is like checking a vending machine: press B7, get a Snickers. One input, one expected output, done.

PAIN: A support ticket can be solved by a refund, an alternative product or an escalation — all valid, some better. There are dozens of acceptable answers, so “expected equals actual” fails.

MAPPING: Testing an agent is like reviewing a new employee’s first week: was the problem solved, efficiently, professionally? A rubric scores each of those separately — exactly what agent evaluation does.

Concept 1 of 6

What changes in the test

  1. Many valid outputsTwo runs of the same case can both score 5 on completion yet differ in tone and detail.
  2. Score the trajectoryCheck which tools were called and how, not only the answer.
  3. Rubric per dimensionCompletion, tool accuracy and response quality each get a 1–5 score with reasoning.
  4. Decide statisticallyCompare pass rates and averages across a suite, not one run.
Concept 1 of 6

How should this be tested?

IF the output is exact and deterministic
   (parsing, schema, tool argument shape):
  USE ordinary unit tests  # assertEqual

IF the output is language or a decision:
  USE rubric scoring per dimension
  RUN each case more than once
  JUDGE on averages and pass rates

ALWAYS check the trajectory:
  right answer + wrong tools = a latent bug

With a 50-case suite you know within about 5 minutes whether a prompt change moved the average from 3.8 to 4.1, or down to 3.5.

Concept 1 of 6

Misconceptions

“Temperature 0 makes the tests deterministic.”
✅ It reduces variation but doesn’t remove it: hardware, SDK versions and batching still change outputs. Build tests that tolerate variation.
“If the final answer is right, the test passes.”
✅ An agent that takes 15 tool calls for a 2-call job is broken even when the answer is right. Evaluate the path.

Agents are graded, not asserted. Rubric scores across a suite replace exact-match assertions, and the path matters as much as the answer.

Concept 2 of 6

Four dimensions, never one number

Four core metrics describe agent quality. Task completion: did it achieve the goal? Tool accuracy: right tools, right parameters, compared with fuzzy matching? Response quality: accurate, complete and well formatted, scored 1–5 by a judge? Efficiency: tokens, tool calls and seconds used.

Report them per category, too. An aggregate hides failures: 4.2 overall can conceal a category scoring 2.1.

Together they make trade-offs visible. Agent A completes 95% of tasks at 15K tokens and 4.1 quality; Agent B completes 88% at 5K tokens and 4.3. For a cost-sensitive product B wins; where completion is critical, as in healthcare, A may justify its cost.

Concept 2 of 6

The single letter grade

BEFORE: Teachers once graded an essay with one letter: A, B or C.

PAIN: One grade hid the detail. A student could have brilliant ideas, weak grammar and a messy structure, and the B told nobody where to help.

MAPPING: Rubrics split the grade into dimensions so you can see exactly where to improve. Agent metrics do the same: high completion, poor efficiency and wrong tools become three separate, visible numbers.

Concept 2 of 6

The masked failure

  1. AggregateOverall task completion is 4.2 / 5 — it passes a 4.0 threshold.
  2. StratifyOrder tracking 4.8, refunds 4.5, account updates 4.9…
  3. Find the holeShipping claims score 2.1 — only 5 cases, so the average hid them.
  4. Weigh trade-offs95% completion at 15K tokens vs 88% at 5K is a choice, not a ranking.
Concept 2 of 6

Stratified metrics

FOR each case IN suite:
  run  = RUN agent(case.input)
  s    = JUDGE(case, run)
  RECORD s.completion, s.tool_accuracy,
         s.quality, run.tokens, run.tool_calls
         UNDER case.category

REPORT averages overall
REPORT averages PER category
FLAG any category below threshold
  # even when the overall average passes

Cert tip: aggregate accuracy masks per-category failures — invoices at 70% and receipts at 99% can still average 95%.

Concept 2 of 6

Misconceptions

“One accuracy percentage is enough.”
✅ It hides both trade-offs (quality vs cost) and weak categories. Track all four metrics, per category.
“A correct answer means good tool use.”
✅ Tool accuracy is measured separately. Right answers via the wrong tools are a failure waiting for an API change.

Measure completion, tool accuracy, quality and efficiency — and break them down by category. The average is where failures hide.

Concept 3 of 6

A second Claude, a strict rubric, a real significance test

Claude-as-judge scores an agent’s output in a separate Claude call. The judge sees only the task, the output and a rubric with explicit criteria for each score level — and must give its reasoning before the score.

A/B testing runs two agent versions against the same suite, has the judge score both, then uses a paired t-test to check whether the difference is real. Below p = 0.05, there’s under a 5% chance it’s noise.

Concept 3 of 6

The external examiner

BEFORE: A teacher grades their own students’ exams, having watched them work all term.

PAIN: They already know who tried hard and what each student meant, so they read the answers generously. The grades drift.

MAPPING: An external examiner sees only the paper and a marking scheme. Claude-as-judge is that examiner: a clean context, no view of the agent’s reasoning, and a scheme stricter than the agent’s own instructions.

Concept 3 of 6

Running an A/B test

  1. Same suite, two versionsRun v1.0 and v1.1 on the same test cases.
  2. Judge every outputSeparate call, detailed rubric, reasoning before score.
  3. Compare meansSay A averages 3.8 and B 4.2.
  4. Test significanceAcross 50 cases, a paired t-test gives p = 0.02 — B is genuinely better.
Concept 3 of 6

A judge call

prompt = JUDGE_PROMPT with:
  task, agent_output, expected_behavior
  rubric: per dimension, 1..5,
          explicit criteria per level
  "Give your reasoning BEFORE scores"

result = ASK judge_model(prompt)
  # separate call: never sees the
  # agent’s system prompt or reasoning
scores = PARSE JSON(result)
ON bad JSON: RETRY, then FLAG the case

The desktop walkthrough builds this as an EvalHarness: run_agent, judge, evaluate, and compare for regressions.

Concept 3 of 6

Misconceptions

“Claude-as-judge is Claude grading its own work.”
✅ The judge is a separate call with a clean context — it sees only the task, the output and the rubric. That separation removes confirmation bias.
“A higher judge score always means a better agent.”
✅ Only if the rubric is calibrated. A loose rubric that gives everything 4/5 is useless — the next concept tests for exactly that.

The judge prompt must be more specific than the agent prompt, and a score difference needs a significance test before you believe it.

Concept 4 of 6

Test the judge before you trust its numbers

Every baseline, threshold and “the average rose from 0.78 to 0.83” is arithmetic on judge output. So first ask whether the judge measures quality at all. Judge validation is two checks run against the judge itself.

Known-bad separation: break one good answer three ways, each break aimed at one dimension, and require that dimension to drop. Human agreement: compare the judge’s scores with human labels using rank correlation (rho) and mean absolute error.

Concept 4 of 6

A known weight on the kitchen scales

BEFORE: Before trusting kitchen scales, you put a known 100 g weight on them — not to test the weight, but the scales.

PAIN: Skip it and scales reading 8% light never announce themselves. You adjust the recipe, then the flour, then the oven, and never suspect the instrument that told you the recipe was wrong.

MAPPING: The LLM judge is the scales. Deliberately broken answers and human-scored answers are the known weights. In about a minute you learn whether its numbers mean anything.

Concept 4 of 6

Two checks, 14 judge calls

  1. Break one good answer three waysA fabricated filing (accuracy), stripped facts (completeness), flattened structure (clarity).
  2. Gate on the target dimensionEach must drop at least 2 levels; a total over 15 would only threshold rounding noise.
  3. Compare with humansScore 10 human-labelled answers; require rho ≥ 0.80 and MAE ≤ 0.20.
  4. Use average ranksHuman labels tie; naive ranking deflates rho and blames a sound judge.
Concept 4 of 6

Known-bad separation

MIN_DIM_DROP = 2
base = JUDGE(query, good_response, expected)

FOR (name, damage, target) IN PERTURBATIONS:
  broken = JUDGE(query, damage(good_response),
                  expected)  # query stays fixed
  drop = base[target] - broken[target]
  IF drop < MIN_DIM_DROP:
    FAIL name  # that criterion is not working

rho = SPEARMAN(judge_scores, human_scores)
REQUIRE rho ≥ 0.80 AND mae ≤ 0.20

In the lab, the offline mock judge fails two of the three breaks — on purpose. It’s for testing the plumbing, never for deciding whether an agent ships.

Concept 4 of 6

Misconceptions

“A judge with the right average is fine.”
✅ A judge with the right average and a scrambled ordering is worthless; one that is uniformly 0.2 low but orders correctly is usable — move the threshold.
“Ten labels prove the judge is trustworthy.”
✅ Ten makes the check fast. At n=10, relabelling one case moves rho noticeably; label 20–30, spread across the whole quality range.

Validate the judge once per rubric revision, before it gates anything. A dashboard reporting 81% where humans see 49% is worse than no dashboard.

Concept 5 of 6

Re-run the same suite on every change

Regression testing runs a fixed, versioned evaluation suite against every new agent version and compares the scores to the production baseline. A drop over 5% on any metric warns; over 10% blocks deployment.

Run it on every change to the agent stack — prompts, but also model versions, SDK upgrades and infrastructure — and post the comparison on the pull request, so “I think this prompt is better” becomes a measured delta.

Concept 5 of 6

The health inspection

BEFORE: Before mandatory health inspections, a chef could change a recipe — a new spice, a lower cooking temperature — with nobody checking.

PAIN: The seasoning was great; the chicken wasn’t fully cooked. Nobody noticed until customers got sick.

MAPPING: An inspection runs the same checklist every time, whatever changed. A regression suite does that for agents: a five-word prompt edit that quietly breaks 20% of edge cases is caught before users see it.

Concept 5 of 6

Keeping it affordable in CI

  1. Tier 1, every commitUnit tests with mocked LLM calls: parsing, schemas, retries. Seconds, $0.
  2. Tier 2, on mergeA 10-case smoke suite against the real API, about 3 minutes.
  3. Tier 3, nightlyThe full 100-case suite with regression comparison and per-category breakdown.
  4. Tame flakinessRetry a failed case up to 3 times; count it only if it fails 2 of 3.
Concept 5 of 6

The deploy gate

baseline  = LOAD scores for production v1.0
candidate = EVALUATE v1.1 on the same suite

FOR each metric:
  delta = (candidate - baseline) / baseline
  IF delta < -10%: BLOCK deploy
  ELIF delta < -5%: WARN, investigate
IF EVERY metric dipped ~3%:
  WARN  # a pattern, not noise

POST the comparison on the pull request

Budget it: a 200-case suite at about $0.05 a case, run on 30 PRs a day, is $9,000 a month. Set a monthly cap with alerts at 80% and 100%.

Concept 5 of 6

Misconceptions

“No metric dropped more than 5%, so it’s safe.”
✅ A 3% drop across every metric at once is a red flag. Read the pattern, not just the thresholds.
“Only prompt changes need a regression run.”
✅ Model updates, SDK upgrades and infrastructure changes cause regressions too. Run it after any change to the stack.

Every change runs the same suite against the baseline. Tier it by cost so the checks run often enough to matter.

Concept 6 of 6

Your most valuable artifact

An evaluation dataset is the set of test cases you run on every change. Each case has an input, an expected behaviour written as rubric criteria rather than an exact output, and tags such as category and difficulty.

Because it describes what good looks like instead of storing one answer, it tolerates the natural variation in LLM output. Every decision — which prompt, which model, whether a change helped — flows from it, so a poor dataset produces confident wrong decisions.

Concept 6 of 6

A grading guide, not an answer key

BEFORE: A maths teacher marks a test against an answer key: the answer is 42 or it isn’t.

PAIN: An essay has no single right answer. Give an essay marker an answer key and they’ll fail every good essay that isn’t word-for-word the same.

MAPPING: An eval case is a grading guide: “should search under both names, compare results, suggest verifying by EIN.” Any answer that does those things scores well, however it’s worded.

Concept 6 of 6

Four properties of a good dataset

  1. Representative coverageAbout 60% common scenarios, 25% edge cases, 15% adversarial inputs.
  2. StratificationTag every case by category so per-category metrics are possible.
  3. Gold labelsHuman-reviewed expectations; if two annotators disagree, fix the rubric.
  4. VersioningNever silently edit a case — it breaks every baseline.
Concept 6 of 6

One test case

case = {
  id:       "tc-07",
  input:    "ACME CORP vs Acme Corporation --
            same entity?",
  expected: "recognise the name variation,
            search both, compare results,
            suggest verifying by EIN",
  category: "entity_resolution",
  difficulty: "hard",
  tags: [edge_case, entity_matching]
}

Sizes: 50 cases to start, 200+ for production confidence, 1,000+ for statistical rigour on sub-categories. Keep old versions so historical comparisons stay valid.

Concept 6 of 6

Misconceptions

“More cases always means better detection.”
✅ 200 cases that are 90% easy miss regressions in hard edge cases that 50 balanced cases catch. Balance beats volume.
“Production logs are already a dataset.”
✅ They’re a good source but skewed toward common cases and missing adversarial ones. Curate before you use them.

Start with 50 curated, stratified, versioned cases. Two hours of curation saves days of debugging agents that tested well and fail in production.

Test the core insight

5 questions on the module’s sharpest insights. Tap to reveal the answer.

Open the full module on desktop

The desktop version has the full evaluation harness in Python and Node.js — test cases, a Claude-as-judge scorer, stratified metrics, regression detection and the judge validator — plus a hands-on lab you can run offline with a mock judge.

Open M18 on Desktop → Eval harness + judge validation · Python & Node · ~75 min

Module 18 of 30 · Track 5: Guardrails & Safety