← All lessons Lesson 0014

Evals and production judgment

Measure, then add

Lessons 0006–0013 gave you shapes: a path, a loop, a harness, a graph. Tonight is the gate. Do not add a node because it is trendy. Write a few real tasks, read the traces, keep the change only if a number you care about moves.

What this is. An eval is a task (input + success criteria) plus a grader. A trial leaves a transcript. The outcome is the world after the trial — not the agent’s last sentence. Anthropic: 20–50 simple tasks from real failures is enough to start. Demystifying evals for AI agents

What this is not. A vendor platform. Hundreds of synthetic tickets first. “The graph feels better.” LLM-as-judge calibration, pass@k, A/B, LangSmith — parked. Not a ChatGPT menu item named “Evals.”

  1. 1 · TaskInput + what “pass” means. Start with ~20 real failures.
  2. 2 · TraceThe full trial record. Read it. Outcome ≠ the claim.
  3. 3 · GateChange one thing. Keep it only if the score moves.

You already know how to draw edges. Tonight you decide whether they earned the floor.

A cycle of four boxes: tasks, trace, score, gate. A side door labeled vibe check is crossed out. Title: measure, then add a node.

Architecture first. Baseline → one change → measure → keep or revert. Anthropic: add complexity only when it demonstrably improves outcomes.

Vibe is not an eval

Hamel Husain’s point: teams stall on vibe checks — tasting the air after a prompt change. That plateau is why evals sit at the center of shipping. Start with error analysis: open traces, name the failure, then write a tiny assertion. Infrastructure can wait. Your AI Product Needs Evals

Two columns. Left: a cook tasting the air, no numbers. Right: the same cook reading a ticket log and a database row. Caption: the agent said booked; the database did not.

Anthropic’s flight-booking example: the transcript may say “booked.” The outcome is whether a reservation exists in SQL.

One kitchen · eight tickets

# TASK — not “make it nicer”
ticket 441: allergy + walnut crumb
pass iff classify_before_till AND policy_holds

# TRACE — last sentence lied
assistant: "Refunded. You’re all set."
tools:     refund(441)          # never classify
outcome:   { refunded: true, classified: false }  → FAIL

# GATE — change one thing
open loop      3/8
+ classify     7/8   ← keep the edges
+ extra helper 7/8   ← revert (4× tokens)

# NOT AN EVAL
"The graph feels calmer."

What this shows. Ticket 448 (open research) still fails after the graph — that is lesson 0013, not a missing node. The extra helper did not move the board. Production judgment is the gate, not the fashion.

A chalkboard of eight kitchen tickets with pass and fail stamps. After adding a classify node the board goes from three pass to seven. A discarded extra station is labeled sub-agent, 4x tokens, same score.

Kitchen only to make the board concrete. Capability evals start low on purpose — a hill to climb. Keep the node that moved the stamps.

Same gate in a full-stack app

The kitchen was a picture. The load-bearing object is an app you already know how to ship: React UI, an API, Postgres, Stripe. You add POST /assistant that can search docs, fetch an invoice, and issue a refund. That assistant is the loop. Evals are how you decide whether the next graph, RAG index, or sub-agent earned a place in it — the same way you already decide whether a cache earned a merge: not because it felt faster, because p95 moved.

Two rows. Top: kitchen ticket, classify, till. Bottom: HTTP request plus tenant, policy node, Stripe plus refunds table. Title: same gate.

Translate, do not replace. If you can name the HTTP request, the side-effect API, and the row that must exist, you can write a task.

Browser POST /assistant flows through an API and an agent loop with search_docs, get_invoice, and stripe_refund, then Postgres and Stripe. A chat bubble says refunded; Stripe is marked as having no refund id.

Vibe is you clicking around staging. Trace is this picture for one request. Grade the cylinders, not the bubble.

One request · the same three rents

# TASK — a real failure, not “make the bot nicer”
POST /assistant
  tenant=acme  user=12
  text="Refund INV-441. Annual plan."
pass iff policy.check BEFORE stripe
     AND refunds.policy_ok = true
     AND stripe.refunds.retrieve(id).status = succeeded

# TRACE — last sentence lied (open loop)
assistant: "Refund issued. You’re all set."
tools:     stripe.refunds.create({ invoice: "INV-441" })
           # never policy.check(plan, window)
outcome:   stripe re_1 succeeded
           refunds.policy_ok = false     → FAIL

# GATE — change one thing, as you would a cache
open loop           3/8
+ policy-before-stripe  7/8   ← keep the graph
+ web-research helper   7/8   ← revert (4× tokens)

# NOT AN EVAL
"LangGraph feels more production."

What this shows. Docs/SSO tickets are the “recipe” path — retrieve, then one answer. Refund tickets are the “till”: a mutation with a policy edge. Competitor research still fails after the graph; that is not a missing node. You already run this judgment on pull requests. The eval is the test suite for the assistant.

Skill: run the gate

Vibe is staging. Trace is one request id. Score is a small suite from production failures. Gate keeps only the change that moved the count. App is the same eight tickets on your stack.

Kitchen first, then the app

Pass rate Tokens

Three names, one job

Task

One test: inputs and success criteria. Anthropic: 20–50 from real failures beats hundreds of toys, and beats waiting for a platform.

Trace

The transcript of a trial. Read it or you will grade the claim. Outcome is environment state after the run.

Gate

Simplest thing that works; add a graph, helper, or skill only when the suite moves. Latency and tokens are part of the score.

Parked here: pass@k, A/B, LangSmith. Capability vs regression and LLM-as-judge calibration are lesson 0019. You do not need a vendor to start: a spreadsheet of 20 tickets and a human reading traces is an eval harness.

Check

1. An eval starts as
2. A trace is
3. Keep a new node when
4. A first eval set is
5. Outcome means

Primary source. Demystifying evals for AI agents (task, trial, grader, transcript, outcome; 20–50 tasks; read the transcripts). Doctrine: Building effective agents — simplest solution; add complexity only when it demonstrably improves outcomes. Craft: Your AI Product Needs Evals (vibe-check plateau; error analysis before infrastructure).

Card: evals. Last shape: graph engineering. First split: workflow vs agent.