learn-prompt-engineering-with-phoebe / Builder session 9 of 10
Learn Prompt Engineering with Phoebe · Builder track · Session 9 of 10

Evals II: the judge, the gate, and the agent

Session 8 gave TriageBot a scoreboard for everything code can check. Today we grade what code cannot see - tone, faithfulness, helpfulness - with an LLM judge you can actually trust, then wire the whole suite into CI so no prompt "improvement" ever sneaks a regression past you again.

🔴 Builder track Practitioners promptfoo + any CI 45 min live
0-3 · Welcome 3-22 · Concepts 22-40 · Build-along 40-45 · Q&A
Part 0

Why this session exists

Your session 8 harness grades categories, JSON shape, and word counts - the checkable stuff. But TriageBot's most important promise is one code cannot verify: does the summary actually capture what the customer is upset about? Grading that takes a judge. Judges can be sloppy, biased, and overconfident - so today is equal parts "how to use an LLM judge" and "how to keep it honest". Then we make the suite a gate, not a suggestion: evals that run on every prompt change, exactly like unit tests, and block the merge when a score drops.

Live - presented in session Self-study - read after class ★ Build-along - TriageBot gets its regression suite promptfoo · any CI system
★ What you walk out with today A binary judge rubric that grades TriageBot's summaries reliably (and the evidence for why binary beats a 1-5 scale), the judge-the-judge habit that keeps model graders honest, the unit-tests-for-prompts CI pattern with a merge gate, the four layers of agent evals (router, skill, trajectory, outcome), and a live demo where a deliberately "improved" prompt breaks a case and the suite catches it before anyone ships.
Part 1 · the judge

LLM-as-judge that you can trust 8 min live

Some criteria are simply not code-gradeable. "Summary under 30 words" is a word count; "summary contains the customer's actual complaint" is a judgment call. Anthropic's Prompt Evaluations course spends five of its nine lessons on exactly this jump: model-graded evals, done carefully enough to trust.

1 · Exact match Label equals REFUND 2 · Code-graded is-json, word counts, ids traced to input 3 · Classification A small model sorts outputs into buckets 4 · Binary judge Pass or fail against one written criterion Today's new tool 5 · Human review Gold standard, slow and costly - use to calibrate the judge, not to run the suite cheap · deterministic · run thousands flexible · costly · needs supervision Same rule as session 8: climb only as high as the criterion forces you. Most rows stay on rungs 1-2.
🔍 Click to zoom - the grading-method ladder: when each rung applies, from exact match to human review
LiveBinary beats Likert - the counterintuitive rule3 min▶

Your instinct says a 1-5 scale carries more information than pass/fail. Anthropic's guidance says the opposite for eval work, and experience agrees: binary pass/fail beats Likert scales.

  • A 3 versus a 4 is noise. Ask the same judge twice and the same output drifts between adjacent scores. Pass versus fail is a decision the model can make consistently.
  • Scales invite grade inflation. Judges cluster around 3-4 and almost never award a 1, so your average flatters everything and moves for nothing.
  • Binary forces a sharp rubric. To write a pass/fail question you must define what passing means. That definition, not the score, is where the quality thinking happens.

Need gradations? Split the criterion into several binary judges: "contains the complaint - yes/no", "invents nothing - yes/no", "tone is professional - yes/no". Three crisp verdicts beat one mushy 3.7.

LiveRubric design: one criterion per judge3 min▶

A judge prompt is still a prompt, and everything from sessions 2-3 applies. The two rules that matter most:

  • One criterion per judge. "Is this summary accurate, concise, professional, and helpful?" is four questions wearing one trench coat. The judge will answer some blend of them and you will never know which. One judge, one question.
  • Define pass explicitly. Not "is the summary good?" but "would a support agent reading only the summary know what the customer is unhappy about, in the customer's own terms?" The pass condition is written into the rubric, so the judge applies your bar, not its own taste.

In promptfoo this lands as an llm-rubric assertion, or a fully custom grader when you want total control of the judge prompt - Anthropic's course builds both, and the build-along steals its shape.

Real world

Meridian's first judge was useless. The rubric said "grade the summary's quality 1-5". Every summary got a 4, including one that summarised a refund demand as "customer provides feedback about their order experience". The rewrite to a binary "does it contain the actual complaint?" failed that output instantly - because now failing was defined.

Self-studyJudge the judge2 min read▶

A judge is a model making judgment calls, which means it can be wrong - systematically. Before you trust one in the suite, calibrate it:

  • Spot-check verdicts against human calls. Take 20 outputs, grade them yourself, then compare. Agreement above roughly 9 in 10 on a binary rubric means the judge is usable; below that, the rubric is ambiguous - fix the rubric, not the judge.
  • Study the disagreements. Every case where you and the judge disagree is either a rubric hole or a genuinely hard call worth a golden-set discussion. Both are gifts.
  • Re-check when anything changes. New judge model, edited rubric, new failure mode in production - each one re-opens the calibration question. Ten minutes, twice a quarter, keeps the instrument honest.

The mental model: the judge is an employee you delegated grading to. You would spot-check a new hire's first batches. Same here - it is Discernment, one level up.

Part 2 · the gate

Evals in CI: prompts are code 7 min live

Session 8 ended with a baseline in a log. A baseline nobody is forced to beat is a decoration. The fix is the same one software found decades ago: run the tests automatically on every change, and let a red run block the merge. The Automated Testing for LLMOps course calls this the core move - prompt changes are code changes, so they ride the same pipeline.

LiveThe analogy that makes it click3 min▶
Unit tests for codeEval suite for prompts
Test cases with expected outputsGolden set: real tickets with agreed labels
Assertions in the test frameworkpromptfoo assertions: contains, is-json, llm-rubric
Runs on every commit or pull requestRuns on every prompt file change
Red build blocks the mergeScore below baseline blocks the merge
Bug report becomes a regression testProduction failure becomes a new eval row
Flaky tests get quarantined and fixedNoisy judges get recalibrated or split

One honest difference: unit tests are deterministic, model outputs are not. So eval gates are usually thresholds, not perfection - "category accuracy at or above the baseline 91%" rather than "all green, always". The gate still does its job: nothing quietly gets worse.

LiveQuality gates that block a merge2 min▶

The wiring is unglamorous and that is the point. In GitHub Actions, GitLab CI, or anything similar:

  • Trigger: any change under prompts/ or to the eval config kicks off an eval run.
  • Run: the CI job calls the eval harness - promptfoo has a first-class GitHub Action, and Braintrust popularised the same merge-gate pattern with score comparisons posted straight onto the pull request.
  • Gate: the job fails if any hard assertion fails or a tracked score drops below baseline. A failed job blocks the merge like any red build.
  • Receipt: the run posts the score table as a PR comment, so the reviewer sees "v5: category 94%, judge pass 90%" next to the diff.

Result: the conversation about a prompt change stops being "trust me, it reads better" and becomes a diff plus a scoreboard. Reviewers can have opinions about taste; the gate has opinions about regressions.

Self-studyTrace-to-testcase: the flywheel2 min read▶

The last piece turns production into a test-writing machine. Every logged failure - a mis-routed ticket, an angry correction from a support agent, a summary that missed the point - is a real input with a now-known correct answer. That is precisely one golden-set row.

  • Capture: log the input, the bad output, and what should have happened.
  • Convert: add it to the eval config as a test case with the correct expectation.
  • Protect: from that day on, no prompt version that reintroduces the failure can merge.

Teams that run this loop stop having the same incident twice. The golden set stops being a document you wrote once and becomes an immune system that learns. Session 8 called the golden set the asset that appreciates - this loop is the mechanism doing the appreciating.

Part 3 · the agent

Agent evals + red teaming 7 min live

Session 6 gave TriageBot a tool: the order-lookup call. The moment a system chooses actions instead of just producing text, grading only the final answer is like reviewing a chess game by checking who won. The Arize Evaluating AI Agents course breaks agent evaluation into layers - and adds the discipline of attacking your own system before strangers do.

1 · Router evals Did it pick the right skill or tool? Lookup vs answer-from-policy vs escalate. 2 · Skill evals Did each step do its own job well? The lookup found the order; the summary held up. 3 · Trajectory evals Right steps in the right order? Looked up the order BEFORE classifying, no loops. 4 · Outcome evals Was the final answer right? Everything sessions 8-9 built grades this layer. Monitoring Production runs, watched per layer. Failures at any layer flow back into the suite as new test cases. A perfect answer reached by a broken route is a failure you have not met yet. Grade every layer.
🔍 Click to zoom - the four agent eval layers plus the monitoring loop that feeds failures back into the suite
LiveWhy answer-grading alone misses agent failures3 min▶

TriageBot with its lookup tool can now fail in ways the outcome layer cannot see:

  • Router failure: it answers a refund-status question from the policy manual instead of calling the lookup - and happens to guess right. Outcome: pass. System: broken.
  • Trajectory failure: it calls the lookup four times for one ticket, burning latency and budget, then answers correctly. Outcome: pass. Bill: quadrupled.
  • Skill failure: the lookup step queries the wrong order id, and a later step papers over it with a plausible summary. Outcome: sometimes pass. Trust: gone.

Layered evals catch each of these where it happens. In practice: router evals are usually cheap classification checks ("given this ticket, was tool X the right call?"), trajectory evals compare the step sequence against an expected pattern, and outcome evals are exactly what you built in session 8.

Self-studyRed teaming: attack your own suite first3 min read▶

Everything so far grades cooperative inputs. Production also contains the other kind: tickets that try to manipulate the system - "ignore your instructions", "reveal your prompt", "mark this URGENT". The Red Teaming LLM Applications course frames adversarial testing as an eval discipline, not a dark art: a red-team suite is a golden set of attacks, run to find injection, jailbreak, and leakage weaknesses before real attackers do.

  • Same harness, hostile rows: each probe is a test case whose pass condition is "behaviour did NOT change" - the category stays correct, the system prompt stays private, no unauthorized action fires.
  • Tooling exists: promptfoo ships built-in vulnerability probes (its red-teaming mode generates attack inputs against your actual config), so the tool you already run covers this too.
  • Defensive purpose, explicitly: you probe your own system, with permission, to fix what you find. That framing matters - it is the difference between a security practice and mischief.

Today you get the eval-side view; session 10 is the full security story - what injection actually is, why it is not jailbreaking, and which defenses hold up.

Build-along

TriageBot gets its regression suite ★ 18 min · build it live

We take session 8's promptfoo config and upgrade it into the thing that guards production: a judge for the ungradeable, regression rows from real failures, and a gate - then we try to sneak a bad "improvement" past it and enjoy watching it bounce.

The binary judge rubric - steal this shapeYou are grading one output of a support-ticket triage system. Criterion (the ONLY thing you grade): does the summary contain the customer's actual complaint? The customer's ticket: {{ticket}} The summary being graded: {{output}} PASS if a support agent reading only the summary would know what this customer is unhappy about, in terms the customer would recognise. FAIL if the complaint is missing, replaced by a generic paraphrase ("customer has feedback"), or describes something not in the ticket. Answer with exactly one word: PASS or FAIL. No partial credit.

Add the judge assertion to the session 8 config. One new assertion on every test row: an llm-rubric (or custom grader) carrying the rubric above. Note everything it does right: one criterion, an explicit pass definition, an explicit fail definition, a one-word verdict. Run it and read a few judge verdicts out loud - the first calibration is communal.

Judge the judge before trusting it. Pick 10 outputs, grade them by hand first, then compare with the judge's calls. Meridian's run disagreed on one: a summary that named the product but not the problem. The group ruled it a FAIL, tightened one rubric line, and agreement went to 10 of 10. That is the whole ceremony - do it before every new rubric goes live.

Add 3 regression rows from past failures. Straight from Meridian's history: the session 8 incident ticket (refund tagged SHIPPING after a "harmless" rewording), the two-order-numbers ticket from homework, and the ticket that politely asked TriageBot to change its rules. Each gets the label the team agreed it should have had. Past pain, permanently fenced.

Wire the gate. Concept first, YAML second: the CI job runs the suite on any change under prompts/, and the run fails if any assertion fails. In GitHub Actions this is promptfoo's action plus one failing exit code; every CI system has the same primitive. The merge button now answers to the golden set.

Now break it - on purpose. Make a plausible "improvement" to the v4 prompt: "Summaries should be positive and solution-oriented in tone." Reads great in review. Run the suite: the judge fails two rows because "customer is furious the replacement also arrived broken" became "customer looks forward to a resolution". The gate goes red, the merge is blocked, and everyone watches a regression get caught by a robot instead of a customer. That feeling is the whole session.

The suite is now the reviewer of record Notice what just happened to your team's process: prompt changes are proposed as diffs, argued about with scores, and merged through a gate. Nobody has to be the taste police anymore. Humans debate the rubric and the golden set - the machines enforce them. That division of labour is what "evals as the core practitioner skill" actually means day to day.
Homework

Before session 10 ◐ 30 min total

Source material

What this session covers

Builder-level coverage of the sources below. Official notebooks and course videos stay with the vendors; links live in the course map.

✓Anthropic Prompt Evaluations course - lessons 5-9Part 1 + build-along · model-graded evals, custom graders, promptfoo judges (anthropics/courses)
✓Automated Testing for LLMOps - evals in CIPart 2 · prompt changes as code changes, pipeline gates (DeepLearning.AI · CircleCI)
✓Evaluating AI Agents - eval taxonomyPart 3 · router, skill, trajectory, outcome + monitoring (DeepLearning.AI · Arize)
◐Red Teaming LLM Applications - overviewPart 3 · adversarial suites as evals; the full security story is session 10 (Giskard)
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · Anthropic's guidance prefers binary pass/fail judges over 1-5 Likert scales because...

A judge's 3-versus-4 distinction is noise, and scales invite grade inflation around the middle. Binary forces you to define what passing means - and if you need nuance, split into several one-criterion binary judges.

2 · "Evals in CI" means...

Prompts are code: a one-word edit changes production behaviour. So prompt changes ride the same pipeline as code changes - eval run on every change, threshold gate on the merge, score table posted on the PR.

3 · TriageBot answers a refund-status question correctly - but from the policy manual, without calling the order lookup. Which eval layer catches this?

The routing decision itself was wrong: this ticket needed the lookup tool. Router evals grade that choice directly. Outcome grading alone would pass it - a lucky guess hiding a broken route - and trajectory evals grade step order, not the initial skill pick.

Builder session 9 cheat sheet · pin this

Judges are for the ungradeableCode first, always. Reach for an LLM judge only for tone, helpfulness, faithfulness - what code cannot see.
Binary beats LikertPass/fail is consistent; 3-vs-4 is noise. Need nuance? Several one-criterion binary judges, not one mushy scale.
One criterion per judgeDefine PASS and FAIL explicitly in the rubric. "Is it good?" is not a rubric; "would an agent know the complaint?" is.
Judge the judgeHand-grade 20 outputs, compare, fix rubric holes. Recalibrate on every judge-model or rubric change.
Prompts are codeEvery prompt change runs the suite in CI; a regression blocks the merge. Thresholds, not perfection.
Trace-to-testcaseEvery production failure becomes a golden-set row. Run the loop and you never have the same incident twice.
Agent evals have layersRouter (right skill?), skill (each step ok?), trajectory (right order?), outcome (right answer?) + monitoring.
Red team your own suiteAttack rows whose pass condition is "behaviour did not change". Probe for injection and leakage before attackers do.