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?
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?
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?