Dev.to AI ๐Ÿค– Ai ๐Ÿ‘ 0 ๐Ÿ“– 4 min read

Your Claude Code subagents probably pick their own model. I built a mod to take that back

Subagents are where a lot of a Claude Code session's work, and money, goes. And the question "which model runs this subagent?" is answered in a place you rarely look. The problem Claude Code resolves a subage

Your Claude Code subagents probably pick their own model. I built a mod to take that back

Subagents are where a lot of a Claude Code session's work, and money, goes. And the question "which model runs this subagent?" is answered in a place you rarely look.

The problem

Claude Code resolves a subagent's model in a fixed order. As the sub-agents docs describe it, the model the calling agent puts on the call itself comes first, then the agent definition's frontmatter, then the CLAUDE_CODE_SUBAGENT_MODEL environment variable, then your main model. (Before v2.1.251 the environment variable came first; now it sits below the call.)

That first rule is the catch. Whatever the agent writes into the call wins over everything you configured.

I noticed it because I had asked for it. My own CLAUDE.md said, roughly, "for reviews and audits, pass model: "opus"". I then set a default of Sonnet and was surprised that subagents were still on Opus. I checked two of my sessions that day: 21 of 25 Agent calls carried model: "opus" explicitly. Nothing was broken. The agent was doing exactly what my rule told it to, and a rule in a file I'd forgotten about was outvoting my setting.

Frontmatter and env vars can't fix that, because they sit below the call.

What the mod does

subagent-tuner is a Claude Code mod: a plugin with a hooks module. It hooks the Agent tool call and adds a small band above the prompt:

Tuner  [ Manual ][ *Auto ] ยท default [ sonnet ]/[ high ] [ Reset ]

Click Manual or Auto to switch, click the model or effort to cycle your saved default (rec. means "use the recommendation"), Reset clears it. The mode and the default are kept across sessions.

Recording of a real Claude Code session on Windows 11: Manual asks, Auto's default wins

Manual: it asks

Before a subagent starts, you get a pane (on a terminal 144 columns or wider) or a short chain of dialogs:

general-purpose ยท review the diff
Model: opus โ–พ   Effort: high โ–พ
r: Run   d: Run and save as default   c: Cancel

Run it as is, change the model or effort for this launch, or save the choice as your default. If you dismiss the question, the subagent starts anyway with what was shown. The tuner never holds work back.

Auto: your default wins

Auto never asks. It applies your saved default, even over a model or effort the agent set itself. That is the part the built-in order doesn't give you.

Here is a real run. Default saved as sonnet / high, Auto on, then I asked the agent to start a subagent with model: opus:

Agent(review the diff again) Sonnet 5.5

The subagent's metadata confirms it, and not just the model:

{"description":"review the diff again","model":"sonnet","effort":"high"}

The first launch, in Manual with the agent's choice accepted, shows "model":"opus","effort":"high". I included the effort check on purpose. Seeing the right model on screen proves less than reading what the engine recorded for the subagent.

Rules of the road, so it never surprises you:

  • A field you leave at rec. keeps what the call set; if the call set nothing, the tuner recommends by task kind: review on Opus, implementation on Sonnet, search on Haiku.
  • With no saved default, Auto only fills the fields the call left open.
  • A toast tells you when it overrode the agent: Subagent (overridden) -> sonnet/high.

Where it stays out of your way

  • claude -p and SDK hosts: untouched. If you run evals, your subagents keep the model they asked for, so the numbers still measure what you think they measure.
  • Forks: untouched.
  • Manual: a call that already set both its model and its effort goes through as set. (In Auto your default replaces them, as above.)
  • No network calls. It rewrites only the model and effort of Agent calls. For the pane it runs sh (macOS, Linux) or powershell.exe (Windows) to wait for your answer.

A bug I'd rather you hear from me

The first version of the pane relied on mktemp, touch and sh. Git for Windows doesn't put those on the PATH by default, so on Windows the pane never opened and the mod quietly fell back to dialogs. I only found out because I stood up a Windows 11 VM and ran the real thing. The fix writes the signal file through the mod API and waits in sh or powershell.exe, whichever exists. It's tested on macOS and on Windows 11.

Install

Inside Claude Code 2.1.287 or later:

/plugin install subagent-tuner --marketplace Kruhlikau/subagent-tuner

Pick the user scope. It starts working in that session.

Repo, with the source and the tests: https://github.com/Kruhlikau/subagent-tuner (MIT). Read it before installing, as you would any package. A CI job scans it on every push.

What I haven't measured

I'm not going to quote a "saves X%" number, because I haven't measured one. What I can say is narrower: the setting you choose now beats the one an agent picks for you. Whether that is cheaper depends on your work. If you try it, I'd like to hear what your subagents actually ran on before and after.

๐Ÿ“ฐ Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.