Lesson 03 · Foundations · 12 min
Writing a grader
A grader is a function. It takes what the system produced and what you expected, and returns a score. Nothing about that requires a model, and the graders that need no model are the ones to write first: they are fast, they cost nothing, and they return the same answer every time.
export const exactMatch = (output, expected) => ({
score: output.category === expected.category ? 1 : 0,
passed: output.category === expected.category,
});The triage agent returns three things, and each needs a different treatment. The category is drawn from a closed set of five values, so a string comparison settles it. The order number either matches the one in the message or it does not. The customer-facing reply has no single correct wording, so no amount of code can score it — that one waits until lesson 6.
Before any of those, check the shape. A reply that cannot be parsed is a failure regardless of how sensible it reads, and separating shape errors from content errors saves a lot of confusion later. A model that returns prose around its JSON is failing differently from one that returns well-formed JSON with the wrong category.
Watch the empty case. On the order-number grader, returning nothing when there is nothing to find counts as correct. A grader that only rewards non-empty answers quietly teaches you to prefer a model that invents order numbers.
Checkpoint
Find a row that passes the shape check but fails the category check, and one that does the reverse.