Skip to main content
All posts 16 min read

Claude Code subagents
on cheaper models.

AI Claude Code

Claude Code, Anthropic's coding assistant, has a weekly limit, and in my first months of using AI for development I sometimes emptied mine three to four days before the reset. Everything ran on the strongest model, and in the weeks when planning, design and code all came together, that was more than the limit could carry. Running out of tokens turned out to be one of the most useful lessons of those first months. Before another long session, I stopped and read how other people dealt with token limits. What I found pointed to Claude Code subagents on cheaper models, and that became the setup this post describes.

The main session on Fable sends one brief to a lead on Opus, which runs Sonnet and Haiku agents and sends back one summary

Those articles on Claude Code subagents described the same agentic architecture, and two of them shaped what I built more than the rest. One argued for putting Fable, the strongest model, in the orchestrator's seat and letting Opus and Codex do the heavy lifting. The other was a Reddit comment describing a two-layer pattern, where the orchestrator hands a feature to a lead, and the lead briefs the workers, checks their work and sends back one summary.

The idea underneath both was the same. The strongest model sits where the decisions get made, and nowhere else.

I fed the articles to Claude, told it what I had taken from them and where I thought the ideas fit the way I work, and asked it for a deep-dive study on the subject. That is where the ideation started.

Between the study and the back and forth that followed, Claude and I arrived at two parts, an orchestrator and a set of subagents. The orchestrator is the main session, and it plans and decides. Each subagent is a separate session that takes one kind of work and runs on the model that does that job well.

The strongest model keeps the thinking. Smaller models take the rest. I call the setup multi-model agent routing, or model routing for short.

The shape

The main session runs on Fable at xhigh effort. Its job is to plan, decide whether something is a quick task or a feature, dispatch, read summaries and make the final call. It does not write code.

The rules file says so in one line, "Don't write code yourself." That file, ~/.claude/rules/model-routing.md, is a Markdown file of plain prose that Claude Code reads into every session as standing instructions. It sits at the user level, so it applies to every project on my machine; a rule that belonged to one repo would live in that repo's .claude/rules folder instead. The setup skill wrote it, and this post quotes its lines.

A tree of which Claude Code subagents do what. The main session on Fable branches into quick tasks, features and checks; quick tasks go to fast-worker, scout, judge, project agents or deep-reasoner, features go to deep-reasoner as lead, which hands out to fast-worker, scout, judge and project agents, and checks go to the verifier, which uses scout to find files. Codex is drawn dotted beside deep-reasoner, wired in and off.

The tiers

Most tiers are agent files in ~/.claude/agents/ with a pinned model and a pinned effort. The project agent lives in the project's own .claude/agents/ folder, Codex is a plugin, and the catch-all is a settings variable. This is who does what today, and why each one sits where it does.

RoleAgentModelEffortWhat it doesWhy this tier
Orchestratormain sessionFablexhighPlans, decides quick task or feature, dispatches, reads summaries and makes the final call. Never writes code.The strongest model belongs where the decisions get made, and nowhere else.
Leaddeep-reasonerOpushighTakes a feature or a single hard question. Reads the code, splits the work, briefs the workers, verifies and returns one summary with no worker transcripts.Planning takes real reasoning, and every task downstream depends on getting it right.
Workerfast-workerSonnetmediumImplements well-specified work, meaning edits that follow existing patterns, tests, multi-file changes and docs. Stops and flags a non-trivial decision instead of improvising.With a finished plan, the typing does not need the top tier.
JudgmentjudgeSonnetmediumSynthesis and judgment over what a scout gathered, editorial calls, and browser work in Chrome, which scout cannot do. Read-only on files and cannot dispatch.Weighing material takes judgment, not the strongest model.
ScoutscoutHaikulowCode search, inventories, test and linter runs, log and diff reading, vendor docs. Returns conclusions as path:line references or links, never file dumps.Most lookups are simple, and there are a lot of them.
VerifierverifierFablehighRead-only. Takes a plan or a report and checks it claim by claim against the project's docs, mockups and code, marking each one Verified, Wrong or Unverified.A different model from the lead, so the second look is independent.
Project agenttech-writerFablemediumDrafts anything someone else will read on this site and verifies every fact against a source. Cannot edit, write or delegate.Voice and accuracy are judgment work; medium effort keeps a draft quick.
PeercodexOff When on, a peer engineer on par with deep-reasoner, not a reviewer. Both take the same high-stakes problem without seeing the other's answer.Wired in so the switch is one line, off until a decision warrants it.
Catch-allanything unroutedOpusinherited (xhigh)Whatever the hook cannot see lands here through CLAUDE_CODE_SUBAGENT_MODEL.The work that slips through is usually the work that needs judgment.
Who does what

Two details the table cannot hold. scout is read-only by instruction, with Read, Glob, Grep and Bash for read-only commands plus web search and fetch, and I use it instead of the built-in Explore agent, which would run on Opus under a Fable session. fast-worker and judge cannot delegate (disallowedTools: Agent), so a small task cannot quietly become a big one.

Quick task or feature

There are two ways to hand out work. A quick task is one brief I have already planned; it goes straight to a worker. A feature is anything that needs more than one brief; it goes to deep-reasoner as the lead, in one design brief, and comes back as one summary. I review the summary. I do not redo the work.

The lead layer exists because every subagent's report lands in the context of whoever dispatched it. If the main session ran a feature itself, it would read every worker and scout report. Handing the brief to the lead moves all of that one layer down. The lead absorbs the transcripts on Opus, verifies, and sends one summary up. Subagents can nest three layers below the main session, so main, lead, workers fits with room to spare.

The rules

The rules file is short, and most of it is rules. These are the lines this post leans on, in the file's own order, with the reason wherever the file gives one.

  • The main session plans, decides, dispatches and reviews summaries. It does not write code, so its context stays lean and the strongest model spends its turns on decisions.
  • A quick task goes straight to a worker. A feature goes to deep-reasoner as the lead in one design brief and comes back as one summary. Multi-step work shows the dispatch plan first, with task, agent and model.
  • Lookups and fact-gathering go to a scout. Synthesis and judgment go to judge. A job that needs both is two dispatches, the scout gathering with links and quotes and judge weighing what came back.
  • Project agents own their files. Work in those files goes to the owning agent at its pinned tier, raised or lowered for one dispatch when the task warrants it.
  • Every dispatch names a model or targets an agent with a pinned one. The hook blocks the rest, and the answer is to pass a model and continue.
  • Every agent file pins a model and an effort, Haiku agents included, since Haiku takes the same effort levels as the other models. An agent without an effort inherits the effort of the session that dispatched it, so the hook blocks it.
  • Work starts on the lowest tier that could plausibly do it. On failure it runs again one tier up.
  • Briefs are self-contained, with the goal, exact paths, constraints and the expected output, and they ask for structured results, lists and path:line references, not prose.
  • The main session stays direct only for tiny linked edits in files already in its context, or for debugging already in progress there.
  • Review findings are batched into one fix dispatch.
  • The verifier runs at three moments, after a plan is finalized and before it reaches me, after a milestone is complete, and when I ask. Not after every change, because a small, bounded fix is covered by the lead's own build and test run, and blanket verification compounds. It turned one-line fixes into hour-long rounds before anyone noticed.
  • One lead at a time. Two leads in the same working tree break each other's builds, report each other's failures as "not mine", and then need a verification pass just to prove neither clobbered the other.
  • Codex, OpenAI's coding agent, which Claude Code reaches through the codex plugin, is wired in and off, so every Codex step is skipped and deep-reasoner works alone. When it is on, Codex is a peer engineer on par with deep-reasoner, not a reviewer, and it is used for high-stakes decisions only. Both get the same problem, neither sees the other's answer, Codex works on its own with no Claude workers, and I combine the best of both. The point is a second answer from a different model, worked out on its own; if Codex used Claude's workers, its answer would share Claude's blind spots.

What enforces it

Rules in a CLAUDE.md are context, not enforcement. If two rules conflict, the model may follow either. So three pieces of configuration do the enforcing.

The dispatch hook, ~/.claude/hooks/require-agent-model.py, runs as a PreToolUse hook on the Agent tool. A hook is a small program Claude Code runs before the tool call, and the number it exits with is its answer. Exit code 0 lets the call go ahead. Exit code 2 cancels it, and whatever the hook printed to its error output goes back to Claude as the reason. Any other code counts as an error in the hook itself, so the call goes ahead and the message lands in my transcript, not Claude's.

If a dispatch passes no model and targets a built-in agent, an agent it cannot find, or an agent whose model is missing or inherit, mine exits 2 with one line that says what to do instead, such as pass a model, run /route-project to pin one, or use scout, fast-worker or deep-reasoner. Claude reads that line as the tool's error and can correct the dispatch.

Since October 17, 2026 it also blocks every use of the built-in general-purpose agent, pointing at judge, and any agent file it finds without an effort, even when the dispatch passes a model. A passed model skips the model checks only. An agent file with both a model and an effort goes through, and so does a plugin agent, which the hook never checks.

The effort check rests on how Claude Code resolves effort. The subagents docs say an agent's effort field overrides the session's effort level, and the environment variables page puts the CLAUDE_CODE_EFFORT_LEVEL variable above both. An agent file that has no effort field runs at the session's effort level. In my setup that level is xhigh.

The catch-all is CLAUDE_CODE_SUBAGENT_MODEL=opus in ~/.claude/settings.json. Model resolution goes in order. The model passed on the dispatch wins, then the agent file's model, then this variable, then the main session's model. Under a Fable session an agent set to inherit runs on Fable, and one with no model falls through to this variable.

The hook blocks both where it can see them; the variable catches what it cannot, such as agent teams or a session that never loaded my user settings. Whatever lands there runs at the session's effort, since nothing pins one.

The startup nudge, ~/.claude/hooks/check-agent-models.sh, runs on SessionStart. If the current project has agents with no pinned model, it adds one line to the session naming them and pointing at /route-project.

The rules file loads in every session, so it stays lean. Every line costs tokens on every turn. The explanations live in a reference doc that nothing imports.

Two skills, one global and one per project

The setup ships as two skills, and both have been in use since the start.

/setup-model-routing runs once. It checks the Claude Code version first and stops below the one its config facts were verified against. Then it audits ~/.claude/ with a Haiku subagent, which lists the existing agents, rules, settings and hooks, whether Python is available, and whether Codex is installed.

It shows me a proposal with the three tier agents, the rules file, the hook and its settings entry, the merged settings with every existing key kept, the optional nudge, and the reference doc. Nothing changes until I approve.

After applying, it re-reads every file, parses the settings file, and pipes sample dispatches through the hook from a shell to prove it allows a pinned agent, blocks a built-in with no model, and allows the same built-in with one.

/route-project runs once in each project. The global setup already gives every session the orchestrator, the three tiers, the rules and the hook. This skill tunes the agents that exist only in this repo. A scout inventories .claude/agents/, the project settings that could override the global ones, and any routing rules in the project's CLAUDE.md files.

The proposal is a tier map with one row per agent, giving the current model, the proposed model, the proposed effort, whether it may delegate, and a one-line reason. Read-only work goes to Haiku at low, well-specified implementation to Sonnet at medium, integration work with judgment calls to Sonnet at high, and architecture and risky code to Opus at high. The Haiku and Sonnet agents cannot dispatch other agents, and only a lead keeps the Agent tool.

Every agent gets an explicit model, never fable and never inherit. It keeps each agent's name, domain and ownership; it adds frontmatter lines, not a reorganization.

Verification runs the global hook against each agent to prove none is left unpinned, then does a routing dry run on three realistic tasks and shows the dispatch plan for each without executing anything.

An example taken from this site

This site has one project agent, tech-writer, pinned to Fable at medium effort. It drafts anything someone else will read, commit messages included, verifies every fact against a source, and cannot edit, write or delegate.

The best example is the move of the project and blog node pages, and then the listing sections on Home, the blog and the portfolio, into Drupal Canvas content templates and section components. The work ran in phases, each led by deep-reasoner, with my decisions made between them, and the session log shows the pattern working.

Every phase opened with a database snapshot and closed with a gate, the pages compared against a baseline with any difference accounted for. The lead sent theme work to two workers, Chrome checks to an agent in its own tab, and the docs prose to tech-writer while it ran a deploy rehearsal. The verifier caught things before they reached me, four fixes at the end of the listing milestone, one of them to the lead's own log entry.

And the plans carried estimates, not promises. The node page plan put phases 2 to 6 at about 19 hours; phases 1 to 6 ran in under four.

Between October 12 and 17, 2026, this project recorded 334 dispatches, and nothing went deeper than a lead's workers. The built-in general-purpose agent in this table has since been replaced by judge; the record keeps the name of what ran.

AgentFrom the main sessionFrom a leadFrom the verifierTotal
fast-worker54460100
tech-writer4533078
scout1952374
deep-reasoner300030
general-purpose721028
verifier240024
Total1791523334
Dispatches on this project, October 12 to 17, 2026

The leads sent more scouts than I did, which is the point of the lead layer. The reading happened one level down from me, and my own context stayed lean. deep-reasoner is the usual entry point for real work and hands out to fast-worker, scout and now judge, while quick tasks go straight from the main session. The 24 verifier runs all sat at a plan or milestone point.

Where it stops

All of this applies to the terminal command-line interface (CLI), and to the Desktop app's Code tab as far as the docs go, which say it reads the same settings files and the skills under ~/.claude/. Cloud sessions do not read ~/.claude/ at all, so none of it reaches them; they would need the same agents, rules and settings committed in the repo.

A resumed session keeps its model. I once changed the global model mid-session and kept resuming it with --continue, so the orchestrator kept the old model while everything below it ran as designed, because every agent pins its own model. A new session picks up the change.

Codex is built in but off.

The hook can be relaxed. Instead of blocking, it can fill in a fallback model through updatedInput and let the dispatch proceed. I keep it blocking.

The setup is small. The agents and the rules are a handful of Markdown files, the hook is one Python script, and the rest is one shell script and a few settings keys. Together they decide which model handles which kind of work, and the decision holds on every dispatch whether I am thinking about it or not.

Sources

Comments.

No comments yet. Be the first to write one.

Leave a Comment.

I never show your email.
Links and code are allowed.
Comments wait for my approval before they appear. I don’t store your IP address with your comment.