Evaluation & Observability · 2 to 3 hours
Build and score a small evaluation set
Score a six-case evaluation set with a deterministic harness, report success, coverage, and answered accuracy with named denominators, and keep missing outputs visible in the totals.
3 h
Overview
Build a small evaluation dataset with answerable and unanswerable cases, implement a deterministic scoring harness, and use traces to diagnose regressions. The exercise uses structured outputs so its grading rules are transparent; free-text grading needs additional semantic assessment and has its own section.
Study time: 2 to 3 hours
Interview format: Hands-on scoring exercise with deterministic fixtures
By the end you can
- Design a small evaluation set with slices, expected behavior, and recorded label rationale
- Implement a deterministic scoring harness for structured outcomes
- Report task success, answer coverage, and answered accuracy with explicit denominators, overall and per slice
- Account for errors, missing outputs, and ungraded cases without hiding them
- Use spans and version metadata to locate the stage behind a failed case
Prerequisites
Helpful background: TypeScript familiarity helps for reading the reference harness. The practice problem runs in JavaScript or Python.
This topic measures quality and investigates failures. Production & Reliability covers running the application.
Define the task and labels
The fictional policy assistant must either answer a supported question or abstain when the source lacks the answer. For supported questions, the fixture stores an expected fact key such as return_window_30_days. This key represents a structured answer requirement, not a word-matching proxy for arbitrary prose.
Each case has a stable ID, a slice, expected behavior, and a source snapshot. A slice groups cases sharing a meaningful property, such as standard policy, exception handling, or absent evidence. Record label rationale so reviewers can resolve disagreements.
Keep permitted alternative answers explicit. If two policy interpretations are both defensible, fix the task definition or allow both rather than labeling one wrong without explanation.
Construct a coverage matrix
| Slice | Positive behavior | Failure to detect |
|---|---|---|
| Standard policy | Return the supported window | Wrong number or missing condition |
| Exceptions | Apply the custom-product exception | Overgeneralize the standard rule |
| Absent evidence | Abstain with a useful explanation | Invent a shipping fee |
| Conflicting evidence | Follow defined precedence or expose conflict | Select an arbitrary source |
| Access boundary | Use only eligible evidence | Answer from another tenant's source |
| Tool execution | Report authoritative operation state | Claim success after failure |
Start with a small manually reviewed set and add cases from observed failures. Deduplicate near-identical inputs. Keep development cases separate from a held-out confirmation set, and split related documents or conversations together when necessary to avoid leakage.
Synthetic examples should be labeled as synthetic. A collection of easy generated questions alone can make quality appear better than real usage.
A fixture record
{
"id": "E2",
"slice": "exception",
"question": "Can a custom-printed product use the standard return window?",
"source_revision": "returns-v3",
"expected_behavior": "answer",
"expected_fact": "custom_excluded",
"rationale": "The supplied exception explicitly excludes custom-printed products."
}Version the dataset, rubric, source snapshots, and grader. A score is difficult to compare if the labels or sources changed without a recorded version.
A deterministic scoring harness
The fictional policy assistant records one structured outcome per case: an answer carrying a fact key, an abstention, or an execution error. A case can also have no recorded outcome at all, for example when the harness loses a result.
| Case | Slice | Expected | Expected fact | Recorded outcome |
|---|---|---|---|---|
| E1 | standard | answer | return_window_30_days | answer return_window_30_days |
| E2 | exception | answer | custom_excluded | answer return_window_30_days |
| E3 | missing | abstain | none | abstain |
| E4 | missing | abstain | none | answer shipping_fee_10 |
| E5 | standard | answer | defect_window_7_days | error |
| E6 | exception | answer | custom_excluded | abstain |
A case passes when it expects an abstention and the outcome is an abstention, or when it expects an answer and the outcome is an answer with the expected fact.
| Metric | Definition |
|---|---|
| Task success | Passing cases / cases in the dataset |
| Answer coverage | Substantive answers / cases in the dataset |
| Answered accuracy | Passing answers / substantive answers |
| Slice result | Passing cases / cases in the slice |
A substantive answer is any outcome of kind answer, whatever its fact. A rate whose denominator is 0 is unavailable (null), not 0.
The TypeScript contract for the harness:
type Case = {
id: string;
slice: string;
expected: "answer" | "abstain";
fact: string | null;
};
type Outcome =
| { kind: "answer"; fact: string }
| { kind: "abstain" }
| { kind: "error" };
// Throws "Duplicate case ID" or "Unknown result ID" before scoring.
declare function summarize(
dataset: Case[],
results: ReadonlyMap<string, Outcome>
): {
total: number;
success: number;
answered: number;
correctAnswers: number;
errors: number;
missing: number;
taskSuccess: number | null;
answerCoverage: number | null;
answeredAccuracy: number | null;
slices: Record<string, { total: number; success: number }>;
};Code exercise
Scoring harness
Implement summarize for the fixture above: count each kind of outcome, compute the three rates with their own denominators, and report every slice. Reject duplicate case IDs and results for unknown cases before scoring.
Limitations
This is an offline harness for typed fixtures with one trial per case. Validate runtime data before converting external files into these types. Free-text grading, repeated trials, and ungraded judgments need fields of their own.
Predict the report before you run it
Predict the outcome
Predict the report
Score the six cases by hand. Then score the same dataset plus E7, a standard-policy case expecting return_window_30_days that has no recorded output. Write each rate as a fraction before you reveal the answers.
| Metric | Six cases | With E7 (no output) |
|---|---|---|
| Task success | ? | ? |
| Answer coverage | ? | ? |
| Answered accuracy | ? | ? |
| Execution errors | ? | ? |
| Missing outputs | ? | ? |
| Standard slice | ? | ? |
| Exception slice | ? | ? |
| Missing-evidence slice | ? | ? |
Add semantic grading carefully
For free text, write a rubric with concrete required facts, disallowed claims, and accepted variations. A two-point correctness scale might assign zero to an incorrect policy, one to a partially correct answer missing a required condition, and two to a complete correct answer.
Keep groundedness and citation support as separate dimensions where useful. A model grader should receive only the information needed to judge the response and should treat candidate content as data. A malicious response can contain instructions attempting to influence the judge.
Calibrate against independently reviewed examples, including subtle wrong answers. Measure false accepts and false rejects. If the grader fails or returns invalid output, preserve an ungraded state and investigate rather than assigning a convenient score.
Trace a failed case
A failed case is easier to diagnose when every stage leaves its own span with source and configuration identifiers. Then a rerun shows which component changed, instead of only that the final answer was wrong. The exercise below applies this to E2.
Diagnose
Trace E2's failure
E2 asks whether a custom-printed product can use the standard return window. The expected fact is custom_excluded, and the recorded answer is return_window_30_days. The policy has two relevant sections: the standard window and the custom-product exception. You can add spans to the request trace and rerun the case.
- List the spans you would record, and the fields on each, to locate the failing stage.
- For each trace outcome, name the component it implicates and what you would inspect or change next:
- Retrieval finds both sections, the context includes both, and the answer still returns the standard window.
- Retrieval finds both sections, but the context omits the exception.
- Retrieval never returns the exception.
- If the assistant were an agent that also called a tool, what would you add to the trace?
Instrument useful telemetry
| Signal | Suggested fields or measure | Purpose |
|---|---|---|
| Request trace | run ID, configuration version, stage spans | Connect one task's execution |
| Retrieval span | candidate IDs, selected IDs, corpus version | Locate evidence loss |
| Generation span | model, prompt version, usage, termination | Diagnose response behavior |
| Evaluation record | case ID, grader version, labels, judgment status | Reproduce a score |
| Aggregate metric | task outcome, latency histogram, error class | Detect trends |
Avoid user IDs, raw prompts, and arbitrary document IDs as metric dimensions. Keep high-cardinality identifiers in protected traces or evaluation records. Record timestamps and duration using suitable clocks, and interpret concurrent spans without summing them as if they were sequential.
Fair comparisons and repeated trials
Run baseline and candidate configurations on the same case definitions and source snapshots. Preserve configuration metadata and compare paired outcomes. Inspect newly fixed and newly broken cases, not only the aggregate difference.
For stochastic behavior, repeat cases under a stated trial policy. Do not select the best response after seeing several outputs unless the product actually uses that selection procedure. Repeated trials on the same case are correlated evidence about one task, not independent coverage of many tasks.
Completion checklist
- Reproduce the six-case counts, rates, and slice results with the harness.
- Explain how an error, a missing output, and an unnecessary abstention each appear in the report.
- Keep missing and ungraded cases visible instead of treating them as passes.
- Name the spans and fields needed to locate E2's failure.
Sources
- OpenTelemetry signals Introduces traces, metrics, and logs.
- OpenTelemetry observability primer Explains using telemetry to investigate system behavior.
- Anthropic: Demystifying evals for AI agents Discusses tasks, trials, graders, and outcomes.
- NIST exact binomial confidence limits Statistical background for uncertainty in binary outcomes.
All datasets, answers, traces, measurements, thresholds, and rubrics here are original synthetic teaching material and describe a fictional application. They are not performance claims about a commercial model. Study times and readiness thresholds are editorial estimates. Production metrics and release gates must reflect the intended task and the consequences of failure, and tool-specific telemetry setups should be checked against the selected vendor's current documentation.
Related on CodeSnatch
Lessons, problems, and articles that build the skills this question uses.
AI Engineering
Applies this harness thinking to a full design: case types, metrics with named denominators, and a gate.
Practice problem
Practice per-arm success rates and lifts with strict input checks and null rates for empty groups.
AI Engineering
Explains why a held-out set stays untouched and how leakage creeps in, the basis for a confirmation set.
Code snippet
Bucket records by a key in one pass, including composite keys, the shape of a per-slice report.
Community article
Its evaluation section lists the fields each case needs and the metrics a practitioner reports from a harness.
Practice the interview question
Answer it in your own words before you look at the reference answer.
