Every change to a Claude system is a hypothesis: this prompt is better, this cheaper model is good enough, this retrieval setting reduces hallucination. An architect’s job is to choose how much evidence a change needs before it reaches users, and to make the test cheap and reversible enough that the team actually runs it. The usual shape is a funnel. The offline eval (Lessons 3.1 and 3.2) is fast, cheap and safe but only tests the inputs you thought to include. Shadow or canary exposure shows real traffic with limited blast radius. A proper online A/B test measures real user outcomes. A staged rollout with rollback converts the winner into the default.
Anthropic’s agent-evals write-up is candid about the trade-off. Automated evals give fast iteration. A/B testing measures real outcomes but is slow, taking days or weeks to reach significance, needs sufficient traffic, and only tests changes you actually deploy. Production monitoring (Lesson 3.6) is reactive: problems reach users before you know. No layer is enough alone, so a sound experiment plan states which question each layer answers.
Offline comparison: change one thing, keep everything else fixed
A valid offline comparison holds the dataset, grader, rubric and judge model fixed and changes exactly one variable: the prompt, the model, the effort setting, a retrieval parameter. If you change a prompt and a model together, you cannot say which caused the difference. If you change the dataset between runs, you cannot say anything. Record the model ID, prompt version, dataset hash, effort and other parameters with every run so any two runs can be diffed.
Three refinements matter at the Professional level:
- Compare paired, not pooled. Run both variants on the same cases and look at per-case differences. Case difficulty varies far more than the effect of a small prompt change, and pairing removes that variation from the comparison.
- Respect noise. Output is not perfectly deterministic. Anthropic recommends multiple trials per case for exactly this reason. A change from one run to the next on a small set may be a few cases flipping. Report an interval or a distribution of differences, not a single delta.
- Look at slices, not just the total. An overall gain can hide a regression on the adversarial or long-input slice. Decide in advance which slices are gates.
Large offline evaluations are also a natural fit for the Message Batches API, which Anthropic lists as a use case: asynchronous, discounted, and results are keyed by custom_id rather than returned in submission order. Cost and caching mechanics are in Lesson 3.5.
Online A/B tests: design decisions that decide validity
- Randomise at the right unit. For multi-turn or agentic products, randomise per user or per conversation and keep the assignment sticky. Per-request randomisation would let one conversation mix variants, contaminating both arms and confusing the user.
- Pre-register the primary metric, the guardrails and the stopping rule. Decide before the test which single metric determines the winner (for example task-resolution rate), which guardrail metrics must not regress (safety flags, escalation rate, p95 latency, cost per completed task, error rate), and how long you will run. Checking results daily and stopping when a difference appears inflates false positives.
- Size the test deliberately. The traffic you need depends on the baseline rate, the smallest improvement worth detecting, and the metric’s variance; do a power calculation rather than quoting a rule of thumb. Rare-event guardrails, such as a safety incident that happens in a tiny fraction of conversations, may never accumulate enough events in a practical window to show a difference, so cover them with adversarial offline suites and by limiting exposure.
- Decide with a rule that includes guardrails. Ship if the primary metric improves by the pre-agreed margin and no guardrail regresses beyond its tolerance. A cheaper model that wins on cost but loses on resolution is a business decision, not an automatic pass.
- Beware novelty and segment effects. Early behaviour can differ from steady state, and an overall wash can hide a strong win in one segment and a loss in another. Analyse pre-declared segments, and treat surprises as hypotheses for the next iteration, not conclusions.
Key concept: decide the decision rule before you look
An experiment plan is complete when it states the hypothesis, the randomisation unit, the primary metric, the guardrails with tolerances, the sample or duration, the stopping rule, and the rollback trigger. Writing these down first is what separates an A/B test from picking whichever variant looked better on the day someone checked.
Claude-specific confounders to control
- Prompt cache warmth differs by variant. Caching matches an exact prefix. Two prompt variants have different prefixes and warm independently, so a variant with a small share of traffic may show worse latency and cost simply because its cache is cold. Changing the effort setting between requests also changes the prompt prefix and invalidates the cache on models that do not support per-message effort, so effort experiments inside one cached conversation distort cost. Compare after warm-up, and compare cost using the cache-read and cache-write fields from
usage. - Token counts are not comparable across models. Anthropic notes that newer tokenizers can produce roughly 30 percent more tokens for the same text than earlier models, so a “same prompt” costs differently on a different model. Count against the model you will actually run.
- Pin what you test. Every Claude model ID is a pinned snapshot, so an ID does not silently change behaviour under you. Model changes are deliberate migrations, and the retirement dates on the models page mean you will run more than one such comparison over a system’s life. Log the model ID, prompt version, variant name and parameters with each request so results can be attributed.
- Non-determinism applies online too. Two identical requests can yield different outputs; that is another reason to rely on aggregate outcomes over enough conversations, not spot examples.
Rollout, rollback and the iteration loop
Serve prompts, model IDs and effort settings from versioned configuration, not from code constants, so a change is a config flip and a rollback takes seconds. A safe path is: offline gate, then shadow mode (run the candidate on a copy of real traffic, log its output, serve the incumbent’s), then a small canary share, then a staged ramp with each step gated on the guardrails. Define rollback triggers up front (for example, any guardrail beyond tolerance, or a spike in a specific error type) and make them automatic where you can. Shadow mode doubles the model spend for the shadowed share, which is a cost to price in.
The iteration loop is: sample failures from production and review them (Lesson 3.6), classify the failure cause (Lesson 3.4), form a hypothesis, make one change, run the offline eval, run the online test if the change is user-visible, then add the failure that started the loop to the dataset. Any fix that comes from a production failure should leave a permanent test behind.
Common exam distractor
Three tempting answers: declaring a winner from a short run or a small sample, bundling a prompt rewrite with a model swap in one experiment “to save time”, and shipping on an equal offline score without any live-traffic stage. The exam favours single-variable changes, guardrail metrics alongside the primary metric, staged exposure, and a rollback path defined before launch.