Choosing a model: a decision framework
Choose the right model for each AI feature with a repeatable framework that weighs quality on your evals, latency, cost per success, limits and effort settings.
On this page
Why this matters
Model choice affects nearly everything users notice: quality, speed and, through cost, whether the feature can exist at all. It’s also a decision you’ll revisit, because new models arrive regularly and old ones are retired. A repeatable way to choose saves you from re-arguing the decision every time, and from picking a model because of a benchmark headline.
This article gives you that process: start capable, measure on your own tasks, then trade down only where the evidence says you can.
The current lineup
These are the current Claude models, generated from the wiki’s model configuration:
-
Claude Fable 5.1
claude-fable-5-1- Context
- 1M
- Max output
- 128K
- Per 1M tokens
- $10 in / $50 out
The hardest reasoning and long-running agent work, where quality matters more than cost.
-
Claude Opus 5.5
claude-opus-5-5- Context
- 1M
- Max output
- 128K
- Per 1M tokens
- $4 in / $20 out
The default for product features: complex tasks, agents and anything quality-sensitive.
-
Claude Sonnet 5.5
claude-sonnet-5-5- Context
- 1M
- Max output
- 128K
- Per 1M tokens
- $2 in / $10 out
Everyday features at high volume where speed and cost matter.
-
Claude Haiku 5.5
claude-haiku-5-5- Context
- 1M
- Max output
- 128K
- Per 1M tokens
- $0.10 in / $0.50 out
For prompts up to 100K tokens; $0.50 input and $2.50 output per million beyond that.
Classification, routing, extraction and other small, latency-sensitive steps.
| Model | ID | Context | Max output | Per 1M tokens (in / out) | Good for |
|---|---|---|---|---|---|
| Claude Fable 5.1 | claude-fable-5-1 | 1M | 128K | $10 / $50 | The hardest reasoning and long-running agent work, where quality matters more than cost. |
| Claude Opus 5.5 | claude-opus-5-5 | 1M | 128K | $4 / $20 | The default for product features: complex tasks, agents and anything quality-sensitive. |
| Claude Sonnet 5.5 | claude-sonnet-5-5 | 1M | 128K | $2 / $10 | Everyday features at high volume where speed and cost matter. |
| Claude Haiku 5.5 | claude-haiku-5-5 | 1M | 128K | $0.10 / $0.50 For prompts up to 100K tokens; $0.50 input and $2.50 output per million beyond that. | Classification, routing, extraction and other small, latency-sensitive steps. |
First-party Claude API list prices, checked on October 17, 2026. Prices change: see the pricing page (opens in a new tab) and models overview (opens in a new tab) before budgeting. "Good for" is the wiki's recommendation, not a benchmark.
Within each model there’s another dial: effort, which controls how much the model reasons before answering. Lower effort is faster and cheaper; higher effort helps on hard problems. That means “which model?” is really “which model, at which effort?”
Start with the most capable model
When you’re proving a feature works, use a capable model at a sensible effort level. The default in this wiki’s examples is Claude Opus 5.5. There are good reasons to start there:
- It answers the feasibility question honestly. If the feature doesn’t work with a capable model, a cheaper one won’t save it. If it does work, you know the ceiling.
- It makes your eval set meaningful. Outputs from a strong model help you write reference answers and spot which cases are genuinely hard.
- Optimizing is easier than rescuing. Trading down from a working feature is a measured, low-risk step. Debugging a feature that might be failing because of the model is not.
The most capable tier, Claude Fable 5.1, is worth testing for the hardest reasoning and long-running agent work, where its cost can be justified.
Compare on your own evals
Public benchmarks tell you how models do on general tasks. Your feature succeeds or fails on your inputs and your quality bar. The reliable way to choose is to run candidate settings on your eval set and compare:
Show text descriptionHide text description
A sequence of 5 steps.
- Capable model : Prove the feature works and set the quality bar
- Lower the effort : Same model, less reasoning: often the cheapest win
- Smaller model : Try the next tier down for the whole feature
- Split by step : Smaller models for simple steps, larger for hard ones
- Re-check on upgrades : Rerun the comparison when new models ship
This script runs the same eval cases through several settings and prints pass rate, median latency and cost per success for each. The task here, extracting a date from a message, is deliberately simple so the code stays short; swap in your own cases and checks.
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
interface Setting {
name: string;
model: string;
effort: 'low' | 'medium' | 'high';
/** USD per million tokens, from the pricing page. */
inputPerMTok: number;
outputPerMTok: number;
}
const settings: Setting[] = [
{ name: 'Opus, medium', model: 'claude-opus-5-5', effort: 'medium', inputPerMTok: 4, outputPerMTok: 20 },
{ name: 'Opus, low', model: 'claude-opus-5-5', effort: 'low', inputPerMTok: 4, outputPerMTok: 20 },
{ name: 'Sonnet, low', model: 'claude-sonnet-5-5', effort: 'low', inputPerMTok: 2, outputPerMTok: 10 },
];
interface Case {
input: string;
expected: string;
}
// Real messages from your product, with the answer a careful human gave. Use dozens, not three.
const cases: Case[] = [
{ input: 'Can we move the review to next Tuesday? Today is Thursday 2026-10-15.', expected: '2026-10-20' },
{ input: 'Deadline is the last day of this month (it is 2026-02-03 today).', expected: '2026-02-28' },
{ input: 'Let us meet on the 3rd of March 2027.', expected: '2027-03-03' },
];
const SYSTEM = 'Extract the single date the message refers to. Reply with the date only, as YYYY-MM-DD.';
interface Result {
passed: boolean;
ms: number;
costUsd: number;
}
async function runCase(s: Setting, c: Case): Promise<Result> {
const start = performance.now();
const response = await client.messages.create({
model: s.model,
max_tokens: 2048,
output_config: { effort: s.effort },
system: SYSTEM,
messages: [{ role: 'user', content: c.input }],
});
const ms = performance.now() - start;
const { input_tokens, output_tokens } = response.usage;
const costUsd = (input_tokens * s.inputPerMTok + output_tokens * s.outputPerMTok) / 1_000_000;
// Only a complete answer can pass; truncated or declined responses count as failures but still cost money.
const text = response.content.flatMap((b) => (b.type === 'text' ? [b.text] : [])).join('').trim();
const passed = response.stop_reason === 'end_turn' && text === c.expected;
return { passed, ms, costUsd };
}
const median = (xs: number[]) => [...xs].sort((a, b) => a - b)[Math.floor(xs.length / 2)] ?? 0;
for (const s of settings) {
const results: Result[] = [];
for (const c of cases) results.push(await runCase(s, c));
const passes = results.filter((r) => r.passed).length;
const totalCost = results.reduce((sum, r) => sum + r.costUsd, 0);
const perSuccess = passes === 0 ? 'n/a' : `$${(totalCost / passes).toFixed(5)}`;
console.log(
`${s.name.padEnd(14)} pass ${passes}/${cases.length} median ${median(results.map((r) => r.ms)).toFixed(0)} ms cost/success ${perSuccess}`,
);
} Run it with npx tsx evals/compare-settings.ts. When reading the results:
- Quality first. Discard any setting that falls below your quality bar, however cheap or fast.
- Then cost per success, then latency. Among the settings that pass, prefer the cheapest per success that fits your latency budget.
- Use enough cases. Three cases can’t distinguish settings. With a few dozen real cases, differences start to mean something; see golden datasets.
Effort and other dials
Before switching to a smaller model, try lowering the effort on the model you have. It keeps one model, one set of prompts and one behavior to reason about, and on many tasks lower effort holds quality while cutting latency and cost. Anthropic’s guidance is to measure the most capable model at lower effort before building anything more complex, since lower effort on newer models often matches older models at higher effort (see the effort documentation (opens in a new tab)).
Effort guidance in short:
- Low: classification, extraction, short rewrites, chat. Fast and cheap.
- Medium: most product features. A sensible starting point.
- High and above: hard reasoning, complex code, long agent tasks, where correctness matters more than cost.
Effort is set per request with output_config: { effort }, so you can use different levels for different steps of the same feature.
Routing between models
Some features have steps of very different difficulty: a quick classification, then a hard answer. Using a small model for the simple steps and a larger one for the hard steps can cut cost substantially. It also adds complexity:
- More to evaluate. Each step needs its own eval, and errors in an early step (such as routing to the wrong path) cascade.
- More to maintain. Two models means two sets of prompt quirks and two upgrade paths.
- Less caching. Caches are per model, so splitting traffic across models reduces cache reuse.
Route between models when your evals show a clear cost win at equal quality, not as a default architecture. The ticket router in When not to use AI is a good example of a step where a small model fits.
Common mistakes
- Choosing by benchmark headlines. General benchmarks don’t predict your task. Compare on your own eval cases.
- Starting with the cheapest model. If it fails, you won’t know whether the feature or the model is the problem. Prove it works first, then trade down.
- Jumping to a smaller model before trying lower effort. Lower effort on the same model is often the simplest win.
- Building a multi-model pipeline by default. Routing adds evaluation, maintenance and cache costs. Do it when the numbers justify it.
- Treating the choice as permanent. Models and prices change. Keep the comparison script and rerun it.
Try it
Exercise
About 45 min
Compare two model settings on your eval set
- Collect at least 20 real cases for your feature, each with a check you can run in code (an expected value, a required phrase, a format).
- Adapt the comparison script to your task and checks.
- Run it with your current setting and one alternative: lower effort, or the next model tier down.
- Write a three-line decision record: settings tested, results, choice.
Show a hint
If your outputs are free text that’s hard to check in code, start with what you can check: length, required facts, forbidden phrases, valid JSON. Later, LLM-as-judge can grade the rest.
Show a worked solution
Example decision record (illustrative numbers):
- Tested: Opus at medium effort; Opus at low effort; Sonnet at low effort, on 40 extraction cases.
- Results: Opus medium 39/40; Opus low 39/40 with lower latency and cost; Sonnet low 36/40, the cheapest.
- Choice: Opus at low effort. It matches the quality bar of 38/40, and Sonnet’s failures were on the date formats users send most. Rerun when the next model ships.
Check your understanding
Key takeaways
- Choose a model and an effort level, not just a model.
- Start capable, prove the feature works, then trade down with evidence.
- Compare settings on your own eval cases: quality first, then cost per success, then latency.
- Try lower effort before smaller models, route between models only when it clearly pays, and rerun the comparison when models change.
Progress is saved in this browser and lights up the roadmap.
Related articles
- Estimating cost per task Estimate what an AI feature costs per task and per successful task, from token counts and model prices to retries and caching, with a reusable cost calculator. Level: Intermediate
- Why evals are product metrics Evals measure how often an AI feature is good enough for users. Learn why they belong with product metrics, not only in an ML notebook. Level: Advanced
- What LLMs are good and bad at A product-focused map of LLM strengths and weaknesses, from language tasks to tool use, and where models still fail, so you scope features realistically. Level: Intermediate