choose-model
Use when writing a new agent or launching a one-off task and the model and reasoning budget have to be decided: Haiku for mechanical work, Sonnet by default, Opus for a gate or a judge, and the effort
SKILL.mdskills/choose-model/SKILL.md
GitHubchoose-model
Cross-cutting block (not a numbered pipeline step): applies every time an agent is created or a one-off task is launched without a model already imposed.
Two axes, not one. The model decides what class of reasoning is available; the effort level
decides how much of it gets spent on this task. They are independent frontmatter fields and the
second one is the cheaper lever: raising a reader from Sonnet to Opus multiplies its cost on every
diff it will ever read, where effort: xhigh on the four agents whose verdict blocks a merge buys
depth exactly where being wrong is expensive. The available levels, the aliases and what each one
resolves to are in references/claude-code-platform.md §1 — read it there rather than trusting the
grid below to be current on model names. A cost figure shown by a dashboard or a tracker is an estimate
(usage times a price table), not a bill: a subscription or free tier has no per-request price, so read
spend limits as in skills/spend-guard-fail-closed.
When
- While writing a new agent (
model:and, where the verdict is hard to walk back,effort:). - While launching a one-off task where the model isn't already set by an existing agent.
- When in doubt whether an existing agent is on the right model (over- or under-sized).
- When an agent is on the right model and still shallow: that is an effort decision, not a model one, and it is the case most often misdiagnosed as "we need Opus here".
Steps
- Characterise the task, not the agent's role:
- Is it mechanical/repetitive (extraction, formatting, short summary, simple classification)? → Haiku.
- Is it building work or normal reading (writing code, reviewing a diff, applying documented conventions)? → Sonnet, the default.
- Is the verdict hard to walk back once taken (blocks a merge, decides between two architectures, judges with a fresh context and no immediate second chance)? → Opus.
- Check the cost of being wrong, not just the apparent complexity: a task that looks simple but where an error is expensive to recover from (e.g. a gate that lets a bug through to production) moves up a tier rather than staying at the "perceived complexity" level.
- Never over-size out of reflex. Opus everywhere is expensive and improves nothing on a mechanical task: over-sizing is a choice error too, not just under-sizing.
- Then set the effort level, separately — and leave it out by default. An agent with no
effort:inherits the session's level, which is the behaviour you want almost everywhere: the operator who ran the session atxhighgets deeper readers for free, and the one who ran it cheap gets cheap readers. Declare a level only where the agent must not follow the session, and there are exactly two such cases.effort: xhighwhere step 2 said the cost of being wrong is high — a gate, a security audit, an architecture verdict — so it stays deep even in a session someone ran cheap. Andeffort: lowfor a genuinely mechanical agent — a classifier, a router — which has no use for a deep session's budget and would otherwise burn it on a decision with one right answer.maxis documented as prone to overthinking: test it on one case, keep it only if it demonstrably found whatxhighmissed, never a default.effort: highis almost always the wrong line to write. It reads like a small improvement over omitting the field and is a different rule: a declared level overrides the session in both directions, so it caps a session the operator deliberately ran deeper. Write it only when capping is the actual intent, and say so in the same sentence. - Write the reasoning down where the field cannot carry it.
model:is always declared, so a one-sentence note next to it is enough.effort:is usually absent, and an absent field cannot say whether it was decided or forgotten — an agent that needed a level and never got one reads identically to one where inheriting was the right answer. So the note says which: either "follows the session deliberately", or the reason for the level that overrides it. - Know what actually wins at runtime. For a subagent the model order is: the per-invocation
modelparameter, the agent file'smodel:,CLAUDE_CODE_SUBAGENT_MODEL, then the session's model — andCLAUDE_CODE_SUBAGENT_MODEL_FORCEoverrides all of it. An agent pinned toopusthat came back reasoning like Sonnet is usually that variable, not a badmodel:line. Effort resolves on its own axis: the frontmatter beats the session, and the environment variable beats the frontmatter — so an agent that ignores its owneffort: xhighis an environment question, not a file question (references/claude-code-platform.md§1).
Output / checkpoint
The agent frontmatter's model: field is filled in, with a choice justifiable in one sentence
against the grid above, and effort: either declared with the same one-sentence justification or
deliberately omitted. For a one-off task with no dedicated agent, the model is chosen before
launching, not changed halfway through unless there's a strong signal (timeout, repeated
failure).
Guardrails
- No rigid rule by agent name: an already "known" agent can change tier if the real nature of its work has changed.
- When in doubt between two tiers, take the lower one and move up only if a concrete failure justifies it: not the other way round. The lower tier plus a higher effort level is the first move up, not the next model.
- Never pin a full model ID in a block. Pin the alias. A hardcoded ID fails outright on a provider that doesn't carry it, where an alias degrades to the newest version that provider has — and this repo is meant to run on someone else's setup, which is exactly rule C applied to the frontmatter.
Origin
Internal decision grid: characterisation by the nature of the task (mechanical/building/hard-to-undo verdict) and by the cost of being wrong, not by perceived complexity. No specific external source retained: several market model-routing frameworks exist, but none was judged close enough to our stack/agent reality to be rewritten as-is; the grid above is a synthesis of our own.
The effort axis (steps 4 and 6, and the "lower tier plus higher effort" guardrail) was added
2026-09-07: effort levels are a platform feature this block predated, and its absence had turned
the grid into a single-axis one, which is how "this reader is shallow" kept resolving to "put it on
Opus". Facts read the same day from code.claude.com/docs/en/model-config and stamped in
references/claude-code-platform.md §1 — the aliases and the per-model level lists live there, not
here, so this block doesn't have to be re-verified every time a model ships.
Steps 4, 5 and 6 corrected 2026-09-07, same day. The rewrite earlier that day said an omitted
effort: was "inherited (high, the default)", conflating two different facts: high is the
session default, while a subagent with no effort: inherits whatever the session is at.
Re-verified against code.claude.com/docs/en/sub-agents, and the correction matters because it
inverts a recommendation — the obvious-looking move of declaring effort: high on the eight
readers is not a small improvement on omitting it, it is a cap on any session the operator ran
deeper. What the corrected step asks for instead is the two narrow cases: xhigh where a verdict
must stay deep in a cheap session, and low where the agent is mechanical enough that a deep
session's budget is waste (elrond, the only one that qualifies today).