Trail content
9 minEnglish narration, Portuguese subtitlesPodcast (RSS)
Chapters
  1. 0:00Opening
  2. 1:03The idea
  3. 1:21How it works
  4. 2:10Three ways to grade
  5. 3:41A challenge
  6. 4:30Where cases come from
  7. 5:39Reading the numbers
  8. 6:19Try it
  9. 7:09In production
  10. 8:02Wrap-up
Transcript

Opening

The back office team has an invoice extractor that works well. One day, someone notices the prompt says: extract the total amount. And they change it to: extract the total amount, with two decimal places.

It looks harmless. The deploy goes out on a Friday.

On Monday, finance complains. Invoices with a discount are coming in at the gross amount. A one sentence change altered how the model read the field. And nobody could have known beforehand, because the only test was opening three files and looking at them.

With regular code, you'd have a unit test. With a model, the same input can produce different answers, and correct isn't always an exact match. The test built for that world is called an eval. In this first lesson of the evals and reliability trail, you'll learn what one is made of, how to grade it, and how to read its numbers without fooling yourself.

The idea

An eval is a test for model output. It has three parts.

A set of cases. Inputs, each with the expected result.

A way to run the system on all of them.

And a grading rule, that turns each output into a score.

How it works

The cases come from real data, anonymized, with the expected answer labeled.

The whole system runs, with the same prompt, model and tools as production.

Each case produces an output, stored together with the prompt version.

Grading compares the output with the expected result.

Each case gets a score. Pass or fail, or a value from zero to one.

And the report shows the overall rate, the rate per category, and the difference from the previous version.

Friday's three files failed at step one, and at step six. Three examples by eye aren't a set. And looking isn't a grading rule. On Monday, the team discovered a kind of invoice, one with a discount, that wasn't among the three.

Three ways to grade

There are three ways to grade. Exact match. Code compares field by field, or checks that the output fits a schema. Use it when there's a right answer, like a classification, an extraction, or a database query. On the invoice extractor, the total is an exact match against the labeled number.

A rule in code. Small functions in your code check properties of the output. Has a citation, stays under a hundred words, never names a competitor. Use it when the text varies, but there are objective criteria.

And a model as judge. Another model scores the output, with a written rubric. Use it for open-ended quality. Tone, helpfulness.

The rule is to start with the simplest one that does the job. Exact match is cheap, fast, and never wrong. A judge costs money, and it needs evaluating too. It inherits the model's variation, and it can agree with the mistake.

Here's a case where that matters. A tone eval for emails used only a model as judge. And the judge approved emails that promised a discount the store doesn't offer. A bigger judge wouldn't fix it. It can still find the promise helpful. Add rules in code first. Don't invent a price, don't name a competitor. Then use the judge on what remains.

A challenge

Here's one for you. The extractor gets forty-eight of fifty cases right. Both misses are discounted invoices, the only two of that kind in the set. The team celebrates ninety-six percent. What is that number hiding?

It's hiding the rate per category. On the kind of invoice finance fears most, the rate is zero for two. The overall number diluted exactly the case that breaks the accounting system.

And calling it noise doesn't help. It might be noise overall, and it's still a hundred percent failure on discounts. You need more of those cases, not a pat on the back. Fill that slice, fix it, and only then look at the overall number.

Where cases come from

There are three sizes of eval. A unit case. A bug seen in production becomes a case. It's the equivalent of a regression test.

An eval dataset. From fifty to a few hundred cases covering your product's categories. It runs on every change.

And a public benchmark. Well known sets that measure models in general. They help you pick a candidate model. They don't tell you whether your system works. If product wants to swap models because a public benchmark rose two points, and your internal eval dropped one point, your eval wins. You don't ship a benchmark. You ship your classifier.

And here's the beginner trap. Treating the dataset as a dead list. The best cases are born in production. The invoice finance sent back. The ticket the classifier routed to the wrong team. Each incident becomes one more line in the file. Six months later, that file is worth more than the prompt. You can rewrite a prompt in an afternoon. A good dataset takes months to gather.

Reading the numbers

Because output varies, a single run can mislead. For important cases, run three to five times, and look at the pass rate, not one round's result.

A drop from ninety-two to ninety percent on fifty cases is a single case. It may be noise.

And fifty typical cases won't cover a rare category. If discounted invoices are five percent of volume, and you sampled twenty files from the top of the folder, that kind may never get in. Stratify. Include some of every category the business fears, instead of only what shows up first.

Try it

On the page there's an eval that runs in a few seconds. Five customer messages, each labeled billing, order or other.

The model classifies each one, and code counts how many match the label exactly.

Now change the prompt to: answer with the category and a short justification. Run it again, and all five fail, even though the category at the front of the sentence is right.

That's not the model getting worse. Your grading is coupled to the old format. The eval and the prompt are the same contract. If the output gains a reason, grading reads the category field, not the sentence. That's the point. An eval turns I think it got better into a number, and shows you right away what a change broke.

In production

So what changes? No prompt, model or tool change ships without running the eval first.

Trying five questions by hand before a deploy isn't an eval. That's a smell called vibe check eval.

And the eval has to run on its own, in your pipeline, or with a single command. That pattern is called an eval harness.

One last case. Your pipeline runs eighty cases on every pull request. Someone also tried four more questions in a chat on Friday, and shipped. The pipeline passed. And finance still came back with a complaint. Where did it leak? In those four questions. If they were different from the eighty, they should have become cases before the merge. If they weren't, the chat added nothing but false confidence.

Wrap-up

So here's the idea to take with you. An eval is how you stop guessing. Real cases with the right answer, the real system running on them, and a grade that doesn't depend on anyone's mood. Read it per category, run it on every change, and feed it with every incident.

In the next lesson, we'll look at what happens when a team doesn't have one: the untested prompt. See you there.

Fundamental

What an eval is

O que é um eval

What an eval is is an AI engineering fundamental for people who work with LLMs. Tests for systems that never answer the same way twice, from unit case to benchmark.

Element
10/13
Level
Beginner
Read
4 min
Updated
On this page 5
  1. 01The situation
  2. 02The concept
  3. 03Try it
  4. 04What this changes
  5. 05Check your understanding
  6. ··Quick answers

The situation

The back-office team has an invoice extractor that works well. Someone notices the prompt says “extract the total amount” and changes it to “extract the total amount, with two decimal places”. It looks harmless. The deploy goes out on a Friday.

On Monday, finance complains: discounted invoices are coming in at the gross amount. A one-sentence change altered how the model read the field, and nobody could have known beforehand, because the only test was opening three PDFs and looking at them.

With regular code you would have a unit test. With a model, the same input can produce different answers, and “correct” is not always an exact match. The test built for that world is called an eval.

The concept

An eval is a test for model output. It has three parts: a set of cases (inputs with the expected result), a way to run the system on all of them, and a grading rule that turns each output into a score.

flowchart LR
  D[("1. Test cases")]:::store --> R["2. Run the system"]:::tool
  R --> S(["3. Model output"]):::llm
  S --> G{"4. Grade"}
  G --> N["5. Score per case"]:::tool
  N --> A(["6. Report and comparison"]):::io
  1. Cases come from real, anonymized data, with the expected answer labeled.
  2. The whole system runs, with the same prompt, model, and tools as production.
  3. Each case produces an output, stored together with the prompt version.
  4. Grading compares the output with the expected result.
  5. Each case gets a score: pass or fail, or a value from 0 to 1.
  6. The report shows the overall rate, the rate per category, and the difference from the previous version.

Friday’s three PDFs failed item 1 and item 6. Three examples by eye are not a set, and “looking” is not a grading rule. On Monday the team discovered a kind of invoice (with a discount) that was not among the three.

Three ways to grade

Type How it works Use it when
Exact match Code compares field by field, or checks that the output fits a schema The output has a right answer: classification, extraction, SQL
Rule in code Functions check properties: has a citation, stays under 100 words, never names a competitor The text varies, but there are objective criteria
LLM-as-Judge Another model scores the output with a written rubric Open-ended text quality, tone, helpfulness

Always start with the leftmost type that does the job. Exact match is cheap, fast, and never wrong. A judge costs money and needs evaluating too.

On a Brazilian NF-e invoice extractor, valor_total is an exact match against the labeled number. “Is the collection email polite?” has no equality. Then you add rules (stays under N words, contains the due date) and, if that still is not enough, a judge with a rubric. Do not start with the judge: it inherits the model’s variation and can agree with the mistake.

Check +20 XP on first tryFriday's change broke discounted invoices. The eval had three PDFs, all without discount, graded by eye. Which piece would have caught the regression before the deploy?

From unit case to benchmark

  • Unit case. A bug seen in production becomes a case. It is the equivalent of a regression test.
  • Eval dataset. From 50 to a few hundred cases covering your product’s categories. It runs on every change. The pattern that looks after it is the Golden Dataset.
  • Public benchmark. Well-known sets that measure models in general. They help you pick a candidate model, not tell you whether your system works.

A public benchmark score does not replace your cases. A model that shines at math can still miss the discount field on your invoice. The cases that matter are your product’s, with your schema, in your language.

The beginner trap is treating the dataset as a dead list. The best cases are born in production: the invoice finance sent back, the ticket the classifier routed to the wrong team. Each incident becomes a line in the file. Six months later, that file is worth more than the prompt.

Why run more than once

Because output varies, a single run can mislead. For important cases, run 3 to 5 times and look at the pass rate, not one round’s result. A drop from 92% to 90% on 50 cases is a single case, and it may be noise.

Fifty cases also fail to cover a rare category. If discounted invoices are 5% of volume and you sampled 20 “typical” PDFs, that kind may never enter. Stratify: some of every category the business fears, not only what shows up first in the folder.

Try it

This classification eval runs in a few seconds. It uses the Anthropic SDK (pip install anthropic and the ANTHROPIC_API_KEY variable).

import anthropic

client = anthropic.Anthropic()

PROMPT = "Classify the customer message in one word: billing, order, or other."

CASES = [
    ("I need a copy of my September invoice", "billing"),
    ("My order 4521 has not arrived yet", "order"),
    ("I was charged twice on my card", "billing"),
    ("Are you open on the holiday?", "other"),
    ("I want to swap the shirt for a bigger size", "order"),
]


def classify(message: str) -> str:
    reply = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=20,
        system=PROMPT,
        messages=[{"role": "user", "content": message}],
    )
    return reply.content[0].text.strip().lower().rstrip(".")


passed = 0
for message, expected in CASES:
    got = classify(message)
    ok = got == expected
    passed += ok
    print(f"{'ok  ' if ok else 'FAIL'} {expected:7} {got:10} {message}")

print(f"\n{passed}/{len(CASES)} cases passed")

Now change the prompt to “Answer with the category and a short justification” and run it again. Exact match will fail, and you will see right away what the change broke. That is the point: an eval turns “I think it got better” into a number.

Five cases are enough to feel the mechanism. They are not enough to ship. A real dataset starts when each category has examples, including the awkward ones: a bill about an order, a duplicate charge, a message in caps, a ticket with the national ID already masked.

Check +20 XP on first tryYou changed the prompt to ask for a justification and 5/5 cases failed exact match, even though the category at the front of the sentence is right. What is the diagnosis?

What this changes

  • No prompt, model, or tool change ships without running the eval first. This is the Untested Prompt smell and the Add Eval Before Changing the Prompt refactoring.
  • Trying five questions by hand before a deploy is not an eval. That is the Vibe-Check Eval smell.
  • The eval has to run on its own, in CI or with a single command. The pattern is the Eval Harness.
  • Every pattern in this catalog has a “How to evaluate” section. It says which metric to watch and how to build the first case.
  • Eval cases are the most valuable asset of an AI system. You can rewrite a prompt in an afternoon; a good dataset takes months of production to gather.

Check your understanding

Check +20 XP on first tryThe extractor gets 48 of 50 cases right. Both misses are discounted invoices, the only two of that kind in the set. The team celebrates 96%. What is the number hiding?

Check +20 XP on first tryProduct wants to swap the classifier model because a public benchmark rose two points. The internal eval dropped one point. Which number wins?

Check +20 XP on first tryA tone eval for emails uses only an LLM judge, with no rule in code. The judge approves emails that promise a discount the store does not offer. What is the next step?

Check +20 XP on first tryCI runs the 80-case eval on every pull request. Someone tried four more questions in Friday's chat and shipped the prompt. CI's eval passed. Finance still complained. Where did the process leak?

Quick answers

What is What an eval is?

What an eval is is an AI engineering fundamental for people who work with LLMs. Tests for systems that never answer the same way twice, from unit case to benchmark.

Go further

Relations

Part of the tracks 1
Search