5.3 Model Versioning, Snapshot Pinning & Migration
Key Takeaways
Every Claude model ID is a pinned snapshot, including the dateless IDs used from the Claude 4.6 generation on, so claude-opus-5 and claude-sonnet-5 name fixed weights rather than moving pointers.
For models before the 4.6 generation the dateless form is a convenience alias that resolves to the dated ID, for example claude-haiku-4-5 resolving to claude-haiku-4-5-20251001.
Claude 4.7 and later models use a newer tokenizer that produces roughly 30% more tokens for the same text, so a migration across that boundary changes token counts even when the prompt is byte-identical.
Model IDs must be externalized to environment variables, a config service, or a feature flag so canary rollout and rollback need no code deploy.
Anthropic publishes a retirement commitment date for each model on Anthropic-operated platforms, while Amazon Bedrock and Google Cloud set their own lifecycle dates.
Model Versioning, Snapshot Pinning & Migration
Exam Blueprint Focus: CCDV-F tests whether you can name a model deterministically and move production off one model onto another without a quality incident. The naming rules changed with the Claude 4.6 generation, and the current rules are what the exam grades.
Model Naming Anatomy: What a Model ID Actually Guarantees
The model parameter on POST /v1/messages takes a string. On the current Claude API there are two shapes of that string, and — this is the part most candidates get wrong — both of them are pinned snapshots.
+-----------------------------------------------------------------------------------------+
| MODEL IDENTIFIER TAXONOMY (CURRENT) |
+-----------------------------------------------------------------------------------------+
| Form | Example | Pinned? | Notes |
|-----------------+------------------------------+---------+------------------------------|
| Dateless ID | claude-opus-5 | YES | 4.6 generation onward. |
| (4.6 gen on) | claude-sonnet-5 | | Its own pinned snapshot; |
| | claude-fable-5-1 | | the alias row repeats it. |
|-----------------+------------------------------+---------+------------------------------|
| Dated snapshot | claude-haiku-4-5-20251001 | YES | Immutable weights. |
|-----------------+------------------------------+---------+------------------------------|
| Convenience | claude-haiku-4-5 | YES | Pre-4.6 style alias that |
| alias | | | resolves to the dated ID. |
+-----------------------------------------------------------------------------------------+
Every Claude model ID is a pinned snapshot, including the dateless IDs used from the 4.6 generation on. claude-opus-5 is not a pointer that silently re-targets when Anthropic ships Opus 5.1 — it names one set of weights. For models before the 4.6 generation, the dateless alias (for example claude-haiku-4-5) is a convenience pointer that resolves to the dated ID claude-haiku-4-5-20251001; the docs list it as the alias for that model and nothing else.
The rule that replaced "never use -latest"
Older Anthropic guidance told teams to avoid -latest aliases in production because they could re-point under you. That hazard class is gone from the current lineup: there is no -latest string in the current model table. The engineering discipline it protected, however, is still exam-relevant and still correct:
Core CCDV-F rule: Pin the exact model ID your evals ran against, externalize it as configuration, and treat a change to that string as a deployment event with its own rollout and rollback plan.
The threat has simply moved from "the provider changes my model" to "an engineer changes my model in a pull request without re-running evals," and from silent drift to a hard retirement date.
Why Changing the Model String Is a Behavioural Change
Whether the change is claude-sonnet-4-6 → claude-sonnet-5 or claude-opus-5 at high effort → claude-opus-5 at low effort, the same four hazards apply:
1. Prompt drift and semantic shift
Instruction-following improves between generations, which is not the same as staying identical. A prompt tuned to produce exactly three paragraphs may produce four. A persona framing calibrated on one generation may read differently on the next. Because nothing in your CI changed, root-causing the shift is expensive.
2. Output formatting and schema regressions
Downstream services parse Claude's output with Pydantic, Zod, or a plain JSON decoder. A new model may fence JSON in a markdown block where the previous one returned bare JSON, or change casing conventions, or add a preamble sentence. Each of those is a deserialization exception in production. Forcing a tool call with tool_choice (see the structured-outputs section) is the durable defence, because the schema is enforced by the API rather than by prompt convention.
3. Eval baseline invalidation
Your accuracy baselines are only meaningful against a fixed model. Change the model without re-baselining and you can no longer tell whether a metric moved because of your prompt edit or the model swap. Re-run the golden dataset and store the model ID alongside every recorded score.
4. Cost, latency, and tokenizer shifts
A new generation can change both price and token count. Two concrete facts to carry into the exam: Claude Sonnet 5 is $2/$10 per MTok against Claude Sonnet 4.6's $3/$15, so that particular migration is cheaper per token; and Claude 4.7 and later models use a newer tokenizer that produces roughly 30% more tokens for the same text. A migration that crosses that tokenizer boundary changes your token counts even when the prompt is byte-identical, so re-measure cost per transaction rather than assuming the price-per-MTok delta is the whole story.
Safe Model Migration: A Five-Stage Lifecycle
Stage 1 Offline golden eval -> Stage 2 Schema & safety diff -> Stage 3 Config externalization
|
Stage 5 Full cutover + sunset <- Stage 4b Canary 1% -> 10% -> 100% <- Stage 4a Shadow traffic
Stage 1 — Offline golden dataset benchmarking
Run the frozen golden dataset against both model IDs. Compare per-case pass rates, not just the aggregate: a migration that improves the mean while breaking one high-stakes category is a failed migration. Record the model ID in the results file.
Stage 2 — Schema and behavioural diffing
Validate every response against the production schema. Diff refusal behaviour, tool-call arity, and output length distributions. Length matters commercially: a model that is 15% more verbose raises output spend by 15% at the same quality.
Stage 3 — Configuration externalization
The model ID belongs in an environment variable, config service, or feature flag — never a string literal scattered across handlers. This is what makes Stage 4 and the rollback in Stage 5 possible without a code deploy.
import os
from anthropic import Anthropic
client = Anthropic()
MODEL = os.environ.get("CLAUDE_MODEL", "claude-sonnet-5")
CANARY_MODEL = os.environ.get("CLAUDE_CANARY_MODEL")
CANARY_PCT = float(os.environ.get("CLAUDE_CANARY_PCT", "0"))
def pick_model(request_id: str) -> str:
if CANARY_MODEL and stable_hash_pct(request_id) < CANARY_PCT:
return CANARY_MODEL
return MODEL
Hashing a stable request or tenant key keeps a given user on one model for the duration of the experiment, so you are measuring the model rather than measuring session-level noise.
Stage 4a — Shadow traffic
Send real production requests to the candidate model asynchronously, discard its output, and log it. You get production-distribution evidence with zero user risk. Shadowing doubles token spend for its duration, so run it on a sampled slice and set an end date.
Stage 4b — Canary rollout
Move 1% → 10% → 100% with an automated rollback trigger on schema-validation failure rate, refusal rate, p95 latency, and cost per request. Define the abort thresholds before you start; deciding them mid-incident guarantees you decide them badly.
Stage 5 — Cutover and sunset
Flip the default, keep the old ID available behind the flag for one release cycle, then remove it. Delete stale eval baselines so nobody compares against a retired model six months later.
Retirement Lifecycles and Sunset Windows
Anthropic publishes a retirement commitment date for each model on Anthropic-operated platforms — for example, not sooner than July 24, 2027 for Claude Opus 5 and not sooner than June 30, 2027 for Claude Sonnet 5. Partner-operated platforms (Amazon Bedrock, Google Cloud) set their own lifecycle dates, so a multi-cloud deployment has more than one clock to track.
Retirement is real, not theoretical: Claude 3 Opus, Claude 3.5 Sonnet, Claude 3.7 Sonnet, Claude Sonnet 4, Claude Opus 4, Claude Opus 4.1, and Claude Haiku 3.5 have all been retired from the first-party Claude API, some remaining available only on Bedrock or Google Cloud. Treat "we are still on a model that has a published sunset date" as scheduled work with an owner, not as a background risk.
Operational checklist: track the retirement date of every model ID in your config; keep the golden eval suite runnable on demand; keep the canary machinery wired up between migrations so it is not built under time pressure; and query the Models API programmatically if you need max_input_tokens, max_tokens, and capability flags at runtime rather than hardcoding them.
A developer ships a production support agent configured with model set to claude-opus-5. During code review, a teammate objects: "That is a floating alias - when Anthropic releases the next Opus it will silently re-point and break our evals. Use a date-stamped ID." Which response is correct?
The teammate is right; every dateless Claude model ID is a mutable pointer and must be replaced with a YYYYMMDD-suffixed snapshot before production
The teammate is wrong; from the Claude 4.6 generation on, dateless IDs are themselves pinned snapshots, so claude-opus-5 names one fixed set of weights
The teammate is right; dateless IDs are acceptable only when the request also sets output_config.effort, which locks the snapshot
Both are wrong; the model parameter is advisory and Anthropic routes to whichever model has capacity
A team is migrating a production pipeline from claude-sonnet-4-6 to claude-sonnet-5. Per-MTok pricing drops from $3/$15 to $2/$10. Finance asks for the projected monthly saving. What is the most important caveat the engineer must raise before quoting a number?
Prompt caching is unavailable on Claude Sonnet 5, so the cached portion of every prompt will now be billed at full input price
The 1M-token context window carries a long-context surcharge on Claude Sonnet 5 that offsets the lower base rate
Claude 4.7 and later models use a newer tokenizer that produces roughly 30% more tokens for the same text, so token counts must be re-measured rather than assumed constant
The Batch API discount does not apply to Claude Sonnet 5, so any batched workload becomes more expensive
A team wants production-distribution evidence about a candidate model before any user sees its output. Which technique provides that, and what is its main operational cost?
Canary rollout at 1%, whose main cost is that 1% of users receive untested output
Shadow traffic, which sends real requests to the candidate model asynchronously and discards the output; its main cost is that it roughly doubles token spend while running
A/B testing at 50/50, whose main cost is the statistical power needed to detect small effects
Replaying the golden eval dataset, whose main cost is that it must be regenerated for each model
Sections you finish are checked off in the contents.