Back to UsageCut

How to change Claude Code's subagent model (and what pinning it actually saves)

10 min read

On this page

Four different settings can decide which model a Claude Code subagent runs on, and Claude Code checks them in a fixed priority order: the CLAUDE_CODE_SUBAGENT_MODEL environment variable beats everything, then a per-invocation model parameter on the Agent tool, then the subagent's own frontmatter, then it falls back to whatever model your main conversation is running. Get that order backwards and you'll edit a subagent file, watch nothing change, and assume the feature is broken - when really an env var you forgot about is silently winning every time.

TL;DR: Set model: sonnet or model: haiku in a subagent's YAML frontmatter (~/.claude/agents/<name>.md or a project's .claude/agents/<name>.md) for a permanent, per-agent pin. Set CLAUDE_CODE_SUBAGENT_MODEL as an environment variable to override every subagent, agent team, and workflow agent at once, regardless of what their own frontmatter says. Pinning only pays off on mechanical, delegatable work - this project's own measured subagent spend shows a real, defended judgment call to leave a creative subagent on Opus while pinning three others to Sonnet and Haiku. The honest savings: roughly 2.4-2.7% of total spend on the safe reclassification alone, up to about 9-11% with a rougher, more aggressive one - both a real slice of a bill, neither a headline number.

What actually controls which model a Claude Code subagent runs on

A subagent's model isn't one setting, it's a resolution chain, and Claude Code's own model configuration docs spell out the exact order it checks:

| Priority | Source | Set via | Scope | | --- | --- | --- | --- | | 1 (wins) | Environment variable | CLAUDE_CODE_SUBAGENT_MODEL | Every subagent, agent team, and workflow agent this session | | 2 | Per-invocation parameter | The Agent tool's model param | One specific call | | 3 | Subagent definition | model: in the agent's YAML frontmatter | That one subagent, every time it runs | | 4 (fallback) | Inherited | Nothing set, or model: inherit | Whatever model the main conversation is on |

The order Claude Code actually checks

Highest priority wins - each level only applies if nothing above it is set

#1CLAUDE_CODE_SUBAGENT_MODEL

Environment variable. Overrides every subagent, agent team, and workflow agent this session.

#2Agent tool model parameter

Set per invocation, usually by a script or the Agent SDK. Beats frontmatter, loses to the env var.

#3Subagent frontmatter model: field

The durable, per-agent pin you set once in the .md file. Lowest priority of the three you can configure.

#4Main conversation's model

The fallback when nothing above is set - same as an explicit model: inherit.

The model field accepts a model alias (sonnet, opus, haiku, fable), a full model ID (claude-sonnet-5, the same values the --model flag takes), or inherit. Omit the field entirely and it defaults to inherit anyway - a subagent file with no model: line isn't unconfigured, it's explicitly matching your main thread. One version-specific wrinkle to know before you debug a "why won't this change" problem: as of Claude Code v2.1.196, setting CLAUDE_CODE_SUBAGENT_MODEL to inherit is treated the same as leaving it unset entirely - resolution just continues down to the per-invocation parameter, then the frontmatter, rather than inherit itself becoming the forced value.

There's also an organization allowlist check sitting on top of all four levels. If availableModels blocks a requested family alias like opus, Claude Code runs the subagent on the newest version of that family the allowlist still permits; if it blocks something more specific, Claude Code falls back to the inherited model instead of failing the request. Interactive sessions show a warning naming both the requested and substituted model, so a mismatch here is visible rather than silent - unlike the resolution order itself, which fails silently if you don't know it exists.

Set it in the subagent's frontmatter

This is the permanent, per-agent version, and the one to reach for on anything you'll run repeatedly. Open the subagent's file - ~/.claude/agents/<name>.md for a personal one, .claude/agents/<name>.md inside a repo for a project one - and add or edit the model line in its YAML frontmatter:

---
name: my-mechanic
description: Handles mechanical edits - renames, formatting, boilerplate.
tools: Read, Grep, Glob, Edit, Write, Bash
model: sonnet
---

That's the whole change. No restart, no re-registration - the next time this subagent is invoked, it resolves to Sonnet unless something higher in the priority chain overrides it. Swap sonnet for haiku on anything that's pure execution rather than reasoning (running a command, reporting a result), or for a specific model ID if you need a pinned version rather than whatever the alias currently points to.

Frontmatter sits at the bottom of the priority chain on purpose - it's your durable default, always in force unless a session-level override steps in above it. That's also its limitation: if a CLAUDE_CODE_SUBAGENT_MODEL export from an earlier debugging session is still sitting in your shell profile, this edit will do nothing and you won't get an error telling you why.

Override every subagent at once with CLAUDE_CODE_SUBAGENT_MODEL

Set the environment variable and it overrides every subagent's frontmatter and every per-invocation parameter, for every subagent, agent team member, and workflow agent in the session - not just one:

export CLAUDE_CODE_SUBAGENT_MODEL=haiku

This is the blunt instrument, and it comes with a real tradeoff: it doesn't distinguish your mechanical, safe-to-downgrade subagents from a creative or judgment-heavy one you deliberately left on a stronger model. Set it globally and you've pinned all of them, including the ones you didn't mean to touch. It's the right tool for a temporary session-wide test ("what does an all-Haiku pass on this task actually look like") or a hard cost ceiling in a CI or cloud-agent context, and the wrong one to leave sitting in a shell profile as a permanent default - use frontmatter for that instead, one agent at a time. Unset it, or set it to inherit, to hand resolution back to the per-invocation parameter and frontmatter.

Override a single invocation from the Agent tool

The third lever is the Agent tool's own model parameter, passed on one specific call rather than baked into a file or a shell session. This is mostly a programmatic lever - a script driving the Agent SDK, or Claude itself choosing to pass a model override when it decides one particular delegation should run on a specific model regardless of that subagent's usual pin. It sits above frontmatter and below the environment variable in priority, and as of v2.1.211 it's respected on resume too: sending a follow-up to that same subagent keeps it on the model the original call specified, rather than reverting to the frontmatter default the way earlier versions did.

Most people setting up their own subagents will only ever touch the frontmatter and the environment variable - this one matters more if you're scripting Claude Code or building on the Agent SDK than if you're just editing .md files by hand.

Which one should you actually set

Three settable methods, ranked by how broad and how permanent each one is

Frontmatter model:
Scope
One subagent, every run
Persistence
Permanent (a file)
Use it for
Your default setup
CLAUDE_CODE_SUBAGENT_MODEL
Scope
Every subagent, this session
Persistence
Until unset
Use it for
Session-wide test or cost clamp
Agent tool model param
Scope
One invocation
Persistence
That call only
Use it for
Scripts and the Agent SDK

Which subagents are actually worth pinning

Not every subagent is a good pinning candidate, and this project's own measured subagent spend is a real example of that split rather than a hypothetical one. Across 766 of its own subagent transcripts, custom subagents ran about 24% of total spend, and almost all of that inherited Opus by default rather than running on a model actually matched to the task. Three of those agent types - one that only executes mechanical edits, one that only runs commands and reports pass/fail, one that only does read-only exploration - are exactly the shape of work a cheaper model handles fine, and got pinned to Sonnet or Haiku. A fourth, a design-focused agent producing frontend/visual output, stayed on Opus on purpose: creative and judgment-heavy work is the kind a wrong downgrade quietly poisons, and that one agent alone represented a real, sizeable share of the measured subagent spend - too much to downgrade on a guess.

What's the subagent's job

The real split from this project's own measured subagent spend

Mechanical, execution, or read-only

Renames, formatting, running a build or test, read-only exploration - work with one obviously correct answer.

Pin it.Three of this site's own subagents fit here and run on Sonnet or Haiku.

Creative or judgment-heavy

Design and visual output, novel architecture calls, anything where a wrong answer is subtle rather than obviously broken.

Leave it on Opus.This site's own frontend-designer agent - $411 of measured spend, 25% of the subagent total - stayed there on purpose.

The pattern generalizes past this one project: a subagent whose job is "do the mechanical thing correctly" is a pinning candidate. A subagent whose job is "make a judgment call" is not, no matter how tempting the price gap looks. When a Claude Code subagent is worth its overhead in the first place covers the broader delegate-or-not decision this sits inside of - pinning only pays off on work you've already decided to hand off in the first place.

What pinning actually saves

Here's what npx usagecut apply actually writes when it applies this lever - real frontmatter, generated by this project's own code, not a paraphrase:

$ node -e 'import("./packages/optimizer-cli/src/apply/levers/subagentPin.mjs").then(m => console.log(m.planSubagentPin({agentsDir:"/tmp/x"}).changes[1].after))'
---
name: uc-runner
description: Runs commands/tests/builds and reports just the result. Opus delegates execution here so cheap, no-reasoning runs do not spend Opus tokens.
tools: Read, Grep, Glob, Bash
model: haiku
color: yellow
---

The honest number behind that change, from this site's own measurement work: reclassifying just the high-confidence, safe subagent types (research, documentation, code review) off Opus saves roughly 2.4-2.7% of total spend - the underlying token consumption is measured, the model-choice classification behind that estimate is not, so it's reported as a range rather than a single figure. Widening the reclassification to also route a general-purpose agent's research and extraction runs off Opus - a rougher, less certain call - gets you to roughly 9-11%, with wider error bars because that classifier is coarser. Neither number is the "10-20x" or "50%" figures that circulate for other Claude Code cost levers; this one is smaller and more mechanical, which is exactly why it's safe to automate. It stacks additively with per-token model economics covered in the Opus vs Sonnet cost breakdown - that guide covers why a per-turn model flip loses money to the cache-miss penalty while a subagent pin doesn't; this one covers how to actually apply the pin. The subagent cost calculator prices out what spawning N subagents costs against doing the same work in one session, so you can see where your own numbers land before deciding whether pinning is worth wiring up.

When pinning isn't worth it

Skip it if your sessions rarely spawn custom subagents in the first place - there's nothing to pin, and adding subagents just to have something to pin them to defeats the purpose. Skip it on anything creative, ambiguous, or judgment-heavy, for the same reason a per-turn model flip on your main thread is a bad idea: a wrong downgrade doesn't just run slower, it can produce output you then have to catch and redo, which costs more than the pin ever saved. And skip it if your subagent spend is already a small slice of the bill - maintaining separate .md files per agent, each with its own pinned model, is real ongoing overhead, and single-digit-percent savings on a small base isn't worth chasing by hand. It's a lever worth automating (which is the whole reason npx usagecut apply exists) rather than one to hand-tune agent by agent.

FAQ

  • What's the actual priority order Claude Code uses to pick a subagent's model? CLAUDE_CODE_SUBAGENT_MODEL first, then the Agent tool's per-invocation model parameter, then the subagent's own frontmatter model field, then the main conversation's model as the fallback. Each level only applies if nothing higher in the chain is set.
  • How do I permanently pin one subagent to a cheaper model? Add model: sonnet or model: haiku to that subagent's YAML frontmatter in ~/.claude/agents/<name>.md (personal) or .claude/agents/<name>.md (project). It takes effect on the subagent's next invocation with no restart needed.
  • Does setting CLAUDE_CODE_SUBAGENT_MODEL affect every subagent, or just one? Every subagent, agent team member, and workflow agent in that session, regardless of their individual frontmatter. It's a session-wide override, not a per-agent one.
  • What does the Agent tool's model parameter actually do? It sets the model for one specific invocation, overriding that subagent's frontmatter but not the environment variable. As of Claude Code v2.1.211, a resumed or follow-up call to that same subagent keeps the parameter's model instead of reverting to the frontmatter default.
  • Is pinning subagents to a cheaper model actually worth doing? For mechanical, delegatable work, yes - this site's own measurement shows roughly 2.4-2.7% of total spend recoverable on the safe reclassification alone, up to about 9-11% on a broader, rougher one. For creative or judgment-heavy subagents, no - a wrong downgrade risks costing more in redone work than the pin saves.
  • Can I set a subagent's model to a specific version instead of an alias? Yes. The model field accepts a full model ID such as claude-sonnet-5, the same values the --model flag takes, alongside the sonnet / opus / haiku / fable aliases and inherit.

Checking all four of these by hand across a real .claude/agents/ directory and an unknown shell environment is exactly the kind of setup audit the free UsageCut scan automates - it reads your actual configured subagents and session history and shows which ones are already pinned, which are quietly inheriting Opus, and what changing that would actually save on your own numbers.

See your own numbers

These are aggregates from real sessions. Your setup is different - run the free scan and get the breakdown for your own Claude Code history. It runs locally; nothing about your code or prompts leaves your machine.

npx usagecutRun a free scan →

NeoMade by Neo

UsageCut by ClockedCode - not affiliated with Anthropic. The figures on this page are measured on real Claude Code sessions and labeled measured or estimated where it matters.