Business

How to Build a Shadow Test for a New Model Before You Switch

Antonio Evans10 min read

A split-screen control room: on the left, a live production pipeline labeled "current model" with green status lights; on the right, a mirrored "shadow" pipeline labeled "candidate model" receiving the same input stream.
Key points

Key points

  1. 1A shadow test sends a copy of real production requests to the candidate model while the current model still serves every user, so no unvalidated output reaches anyone.
  2. 2You need a recorded baseline of prompts, settings and responses before the test starts, or you have nothing to compare the candidate against.
  3. 3Score the candidate on task-specific quality plus cost and latency on the same traffic, and decide the pass marks before you look at results.
  4. 4Keep candidate failures from touching the user path: time limits, retries and logging must all be outside the response users see.

Define the question and the baseline first

A shadow test is an experiment, not a second API call. Before you write any harness code, write down the hypothesis: are you testing lower cost per resolved ticket, stricter JSON schema adherence, better handling of long documents, or a specific set of edge cases that the current model gets wrong? Yotta Labs' workflow makes the point that a vague "test the new model" is impossible to evaluate, and that you should decide upfront how you will judge the candidate.

Then capture the baseline. That means recording, for the current production model, the model identifier, the prompt template, system instructions, retrieval settings, temperature, output schema, timeout behavior and retry logic. If any of those change mid-test, the comparison stops being interpretable. This is the same discipline as regression testing for evolving LLM APIs: Ma, Yang and Kästner show that an API update changed which prompt was better by 8.7 percentage points of accuracy on a toxicity task, so prompt and model are a single unit of comparison, not two.

A useful baseline record looks like this:

{
  "request_id": "req_8f21c",
  "prompt_version": "support-v14",
  "baseline_model": "current-production",
  "candidate_model": "candidate-a",
  "input": {"messages": [...], "retrieval_context": [...]},
  "baseline": {"output": "...", "latency_ms": 1830, "input_tokens": 1240, "output_tokens": 310},
  "candidate": {"output": "...", "latency_ms": 2410, "input_tokens": 1240, "output_tokens": 288}
}

Keep the schema stable for the whole run. If you add fields halfway through, you will be unable to compute a single pass rate across the full sample.

Choose duplication or replay

There are two ways to feed the candidate. Duplication sends a sanitized copy of a live request to the candidate at roughly the same moment the current model handles it. Replay sends already-captured requests to the candidate later, from storage. Yotta Labs' comparison frames the tradeoff: duplication tracks current traffic more closely, while replay is easier to control, review and repeat.

DimensionLive duplicationRecorded replay
Traffic realismHighest, mirror image of today's requestsHigh, as long as the capture window is representative
Control over inputsLimited, you get what arrivesFull, you can pick a curated sample and rerun it
RepeatabilityLow, the same request rarely repeatsHigh, identical inputs every run
Cost controlHard, spikes appear in production timeEasy, budget a fixed sample size
Data review before the candidate sees itHard, needs fast automated scrubbingEasy, a human or classifier can approve the batch
Best forLatency and error behavior under real loadQuality scoring and regression checks

Most teams do both in sequence. Replay a curated sample of a few thousand requests to get quality scores you trust, then run duplication for a day or two to see how the candidate behaves on p95 latency, error rates and long-tail inputs that never made it into the curated set.

The mechanics of capture are well established. Mokapi's record and replay approach forwards requests to the real backend, records request and response pairs as JSON, then swaps in a replay script that matches incoming requests against the recordings. Keploy's kernel-level capture goes further, recording at the system call layer with roughly 1 to 3 percent overhead, so the application does not need to know it is being recorded. For an LLM shadow test you rarely need kernel-level capture: logging at your application's model gateway gives you the prompt, the settings and the response in a form you can replay directly.

One caution about replay realism. A production request may depend on retrieval context, tool results or conversation history that changes between capture and replay. Record the full assembled input, not just the user message, or your replayed prompt will differ from what production actually sent.

What to log

Log enough that you can reconstruct the decision a reviewer would make. The field list below is the minimum for a useful shadow run.

FieldWhy it matters
request_id and user or session hashJoins baseline and candidate records; supports per-user analysis
prompt_version and full assembled inputMakes every score reproducible
model identifier and parametersDistinguishes behavior changes from parameter changes
output text and structured fieldsThe thing you are comparing
input and output token countsThe basis for per-task cost
latency (total, plus time to first token if streamed)Prevents a quality win that ruins the experience
status code and error categorySeparates "wrong" from "failed"
schema or guardrail validation resultBinary pass/fail on format rules
downstream labels (human score, exact match, citation present, escalation taken)Your quality signal

The Siteimprove migration QA framework makes an argument that transfers directly: a single pre-launch sign-off is structurally blind to errors that appear at different stages, so validation should be continuous rather than a gate. A shadow run spanning a full week of traffic, including whatever peak load and unusual inputs that week contains, is the model-level version of that idea.

Build the replay harness

A practical harness has four moving parts: a sampler that pulls recorded requests, a runner that calls both models with identical inputs, a scorer that computes metrics, and a store that keeps every record.

Keep the candidate call strictly out of the response path. The DevOpsBoys shadow mode example shows the pattern: fire both calls in parallel, return the production response to the user, and send the paired records to a logging service asynchronously. Their code also shows the failure mode to avoid, where an exception in the shadow call could propagate into the user request; wrap the candidate call so a timeout or error is logged as a data point, never raised.

Two operational rules make the harness trustworthy:

  • Set the same timeout on both models and record timeouts as a category, not as missing data. A candidate that finishes slowly is different from one that fails.
  • Run the models in isolation from production dependencies. If the candidate is served from a different provider, a rate limit or outage should never touch the current model's availability. Mirror the environment: same retrieval index, same tools, same guardrails.

If you need a single endpoint across many candidate models, Quanta Inference exposes text, image, video, audio and embedding models through one OpenAI-compatible key, which simplifies pointing the same harness at several candidates without rewriting client code for each provider.

Metrics that actually decide the switch

Average quality alone is a poor switch signal. Compute four families of metric, each with a distribution rather than a mean.

Task quality. Define the success criterion for your task. For structured extraction, that is schema validity plus field-level agreement with a ground-truth sample. For support replies, it is a rubric score from human reviewers on a sample plus a check that required facts (policy numbers, refund amounts) match the retrieved context. For classification, it is exact match against a labeled sample. Yotta Labs recommends judging structured tasks by schema validity and field-level agreement, and conversational tasks by tone, completeness, citation behavior and escalation decisions.

Agreement with the current model. Compute how often the candidate's output matches the current model's on the same input, using a calibrated judge or exact match depending on task. This is not a quality measure, but a change measure. A 40 percent divergence on a stable task is a signal to look at the diff.

Cost per task, not per token. Token counts differ between models on the same input, so per-token pricing overstates or understates the real comparison. Pertama Partners' TCO guide notes that license fees typically represent only 20 to 40 percent of true AI implementation costs, and that comparison requires normalizing vendor pricing to actual usage patterns. The CodeAnt guide makes the same point in shadow-test terms: a cheaper model can cost more per completed task because it uses more tokens to finish the job.

Worked example. Suppose your current model averages 1,200 input and 400 output tokens per task at a blended rate, and a candidate averages 1,200 input and 290 output tokens at a rate one-third lower. Per task:

  • Current: 1,600 tokens at rate R.
  • Candidate: 1,490 tokens at rate R/3, so roughly 497 units against 1,600.
  • That is about a 69 percent reduction per task, before counting retries. If the candidate needs a retry on 8 percent of tasks and the current model needs one on 3 percent, the gap narrows but the candidate still wins on cost.

Latency and errors. Track p50 and p95 latency, timeout rate and error rate per model. A candidate with equal quality and half the cost but a p95 latency above your user-facing budget fails the threshold regardless.

Design the decision rule before you look

The most common failure in these tests is moving the goalposts after seeing results. Write the rule down first, in a short document that names the approval owner.

A workable rule:

  • Quality: candidate success rate at least equal to baseline on the labeled sample, with a confidence interval that excludes a regression larger than your tolerance (for instance, 2 percentage points).
  • Agreement: divergence rate on the stable task within an expected band, with every cluster of disagreement reviewed by a human.
  • Cost: candidate cost per successful task at or below baseline.
  • Latency: candidate p95 within the user-facing budget and no worse than 15 percent above baseline.
  • Reliability: candidate error plus timeout rate at or below baseline.
  • Safety: no increase in policy violations on the sensitive-prompt subset.

If any metric fails, the outcome is no-go, with the failing metric named and a follow-up action (prompt change, different candidate, more data). A mixed result is not a reason to switch and watch. It is a reason to fix the specific failure and rerun.

The CodeAnt comparison of shadow and A/B testing is a useful reminder of sequence: shadow testing validates model behavior with zero user exposure, while A/B testing measures user behavior and satisfaction. Shadow first to catch regressions, then a small canary or A/B step to confirm users respond no worse. The DevOpsBoys canary stages show a reasonable progression, starting at 1 percent of traffic and requiring manual approval at each step before full rollout.

Migration deadlines make this sequencing matter. Airia's deprecation guide argues that a 90-day window is often insufficient, because inventory, behavioral validation, compliance documentation and stakeholder communication each take weeks, and teams that start at the notice are already behind. The cross-vendor lifecycle calendar is a reminder that retirement dates differ by platform, so your shadow test should be complete well before the date on the vendor page you actually use.

Handle sensitive data before the candidate sees it

Shadow traffic is production traffic, which means it carries the same personal and regulated data. Yotta Labs recommends sending a sanitized copy of the request to the candidate, and the CodeAnt guide advises applying the same data handling and encryption policies to shadow logs as to production data. KPMG's survey data underlines why this is not optional: 55 percent of companies cite data quality as a major barrier to AI adoption, and organizations report spending up to 80 percent of project time just preparing data (KPMG).

A practical sequence:

  1. Classify before copying. Run the request through the same PII detector you use for production logging. Redact or tokenize names, account numbers, addresses and free-text identifiers.
  2. Approve the batch for replay. For recorded replay, a human or classifier reviews the sample before the candidate model sees it. For live duplication, the scrubber runs inline and a rejected request is simply not shadowed.
  3. Separate the stores. Candidate outputs go to a table or bucket with its own access controls and retention period, not into your production response logs.
  4. Keep provider data terms in view. Whether the candidate provider can train on or retain your inputs is a contract question; query it before the first replay, not after.

If you would rather have this review done for you, Quanta Experts work from your context and hand back finished deliverables, which can include a scrubbed replay sample and a written scoring rubric.

A worked end-to-end run

Pull it together with a concrete plan for a support assistant migration.

  • Sample size. 2,000 recorded requests from a two-week window, stratified by intent category so low-volume intents are not drowned out. 200 of those have human-written reference answers.
  • Curated replay. Candidate runs on all 2,000. A judge model (calibrated against 100 human scores first) grades relevance, factual grounding and tone on a 1 to 5 scale. Schema validity and required-fact presence are checked programmatically.
  • Live duplication. Two days, all traffic, sanitized copies only. You measure p50 and p95 latency, error and timeout rates, and cost per request under real load.
  • Scoring. Compare success rate (score of 4 or above plus all required facts present) against baseline. Hold the sample fixed across both runs.
  • Decision. If the candidate meets the pre-written rule on all metrics, schedule a canary at 1 percent. If not, the failing metric names the fix.

The whole run is a few engineer-days plus evaluation cost. That is far less than the cost of a bad switch. The Pertama TCO analysis notes that exit costs from a vendor relationship are rarely considered and can be substantial, which is another reason to test thoroughly before committing rather than after.

If your team has never run a shadow test and wants a plan tailored to your stack, Quanta Consulting offers a free 30-minute discovery call to scope the work.

FAQ

FAQ

How much traffic do I need for a shadow test to be trustworthy?

Enough that every intent or input category you care about appears dozens of times, not just once. A curated replay of a few thousand requests, stratified by category, usually gives usable per-category scores, while a two-day live duplication run captures latency and error behavior under real load. Small categories may need deliberate oversampling, because uniform random sampling will leave them nearly empty.

Is a shadow test enough to approve a switch?

No. A shadow test shows how the candidate behaves on your traffic, but it cannot measure user satisfaction, because users never see the candidate's output. Plan a shadow test first to catch quality, cost, latency and safety regressions, then a small canary or A/B step so real users respond to the new outputs before you go to full traffic.

Should I test prompt changes at the same time as the model change?

No. Test the model first with the unchanged prompt, then tune the prompt. The regression testing research shows an API update can flip which prompt performs better, so changing both at once leaves you unable to attribute any change to the model or the prompt.

What do I do if the candidate wins on cost but loses on quality?

Treat it as a no-go and name the failing metric. The usual fix is a narrower task scope, a prompt change, better retrieval context, or a different candidate. Switching on cost alone and monitoring quality in production is a bet with your users' experience, not a validation.

How do I stop the shadow path from affecting production?

Run the candidate call in isolation: separate credentials, its own timeout, its own rate limit, and no shared state with the production path. Log failures as data rather than raising them, and confirm with a deliberate test that a candidate timeout leaves the user-facing response time unchanged.

Sources

Sources

  1. Shadow Test New AI Models
  2. (Why) Is My Prompt Getting Worse? Rethinking Regression ...
  3. Record and Replay Real API Traffic for Testing and Offline Development
  4. Record and Replay Testing Guide - Keploy
  5. The Enterprise Migration QA Framework: Pre-Launch ...
  6. LLM A/B Testing and Shadow Deployments in Production
  7. AI Total Cost of Ownership (TCO) Guide | Calculate True AI…
  8. How to Roll Out New LLMs Safely Using Shadow Testing
  9. AI Model Deprecation: What Enterprise Teams Need to ...
  10. AI Model Deprecation and Lifecycle Calendar - Anthropic, ...
  11. The Evolution of Build Vs Buy | KPMG UK
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles