This week a post on X by @rvaniaaaa laid out a way to stop paying the strongest model’s price for every small decision in Claude Code. The idea fits in one line: “the strong model plans, the mid-tier model executes”, and a third model, the advisor, stays quiet until it is needed. We took it and built it into a studio where ten Claude Code agents write, ship and run the software that makes an animated series (who they are and the rules they work by).

This post is for anyone building with agents. It has the setup for one session, with the settings to copy; what changes when the agents are a team that runs all night; and what that team taught us, in the order we met it. Every figure in it was read from a log, a measurement or a file. Where we could not trace a figure, it is not here.

The idea, in short

  • Opus plans and ships. The main session, at high effort, owns the plan and the final change.
  • Sonnet executes. In the original, subagents at medium effort read the codebase, make the edits, run the tests and pull documentation.
  • Fable advises. Set as Claude Code’s advisor, it is called at three moments: before a big plan, when the same failure comes back, and before a long task is called done.
Two diagrams. Left, one session: Opus plans and ships, two Sonnet subagents (Explore reads, worker edits and tests) do the work, and Fable advises at three moments. Right, a team: an orchestrator on Opus gives tasks to two production agents on Opus and seven coding agents on Sonnet at high effort; no agent calls the advisor or spawns subagents; a watcher checks every agent's role file, model and context, and restarts it.

One session: the setup

Two Sonnet subagents

We made two subagents and skipped the researcher, because our research and bulk reading run on our own local model. One detail matters more than it looks: name the read-only one Explore. Claude Code has a built-in subagent by that name, and on a subscription it runs on Opus. The main model keeps choosing the built-in, so an explorer with any other name saves nothing. A project subagent with the same name replaces it and keeps its own model.

# .claude/agents/Explore.md
---
name: Explore
description: Read-only codebase search. Finds the files and code that answer a question and reports where they are, changing nothing.
model: sonnet
effort: xhigh
disallowedTools: Edit, Write, NotebookEdit, Agent, Workflow
omitClaudeMd: true
---

# .claude/agents/worker.md
---
name: worker
description: Carries out one exactly-specified code change, runs the named tests, reports the diff and the output.
model: sonnet
effort: xhigh
disallowedTools: Agent, Workflow
---

Neither may spawn agents of its own, and the explorer cannot edit anything. We started both at xhigh effort; the step down, if the bill says so, is high. Note that max is above xhigh, not below it.

Effort: per model, never project-wide

Set effort per model in your user settings (modelSettings, one effortLevel per model id). A top-level effortLevel in a project’s settings applies to every model and outranks the per-model values, so one line in a project file quietly lowers every session in it.

The advisor, and what it costs

Set advisorModel to fable (or run /advisor fable), and add the three moments to your project instructions. Then measure it. Each advisor call sends the whole conversation, uncached, at the advisor’s rates. Two calls in one long session of ours read 136,426 and 162,418 tokens. So the advisor is for long tasks only, at those three moments: never for a lookup, a one-file change or a second look when little has happened since the first. We read every call back from the session transcripts (tokens, and the model that actually answered), which is how we learned that a session set to Fable had been answered by Opus.

From one session to a team

Our ten agents are not subagents. Each is a long-running Claude Code session started from a role file: an agent file with a first prompt, its tool limits and its model. One orchestrator, the main agent, gives the others their tasks, one at a time and in writing, and each task names what it serves; the first question of any task is whether it gets the work in production to the owner sooner. Two production agents run the series through a dashboard and watch every cut. Seven coding agents each own one area of the code.

# .claude/agents/agent003.md (a coding agent)
---
name: agent003
description: The QA checks: builds, measures and ships every check ...
model: sonnet
effort: high
disallowedTools: Workflow, Agent
initialPrompt: Resume as agent003. Read your handover note and continue from it ...
---

Three of the original’s answers change for a team:

  • Name every role’s model. The planning and judging roles run on Opus: the orchestrator, and the two production agents whose job is to look and judge. The coding agents run on Sonnet. Do not write model: inherit in a role file: it follows the machine’s default. If that default is opusplan (Opus in plan mode, Sonnet otherwise), a role that never enters plan mode runs on Sonnet. That happened to all ten of ours. A test now reads each role’s kind from the team table and fails if its file names another model.
  • No advisor for the agents. Ten long sessions, each re-sending its whole transcript at the advisor’s rates, would cost more than the work. The advisor is for a person’s own session. Start every agent with CLAUDE_CODE_DISABLE_ADVISOR_TOOL=1, and say so in the project instructions as well, because the advisor is a server tool that no permission rule can block.
  • Agents spawn nothing. Every role file blocks the Agent and Workflow tools. Ten agents each spawning helpers multiplies the bill, so work that needs many hands goes to a local model.

Claude Code’s agent view runs sessions in the background, with a supervisor and one screen for all of them. Two things go wrong silently there. Moving an open session into it with the left-arrow key starts a fresh process that resumes the conversation, and --agent is not among the launch flags that carry over: the agent loses its role and its tool limits. Start each agent in the background with its role from the beginning, and never press the arrow on an agent’s window:

CLAUDE_CODE_DISABLE_ADVISOR_TOOL=1 claude --agent agent003 --bg --model sonnet --effort high --permission-mode auto --name agent003 "Start: read your handover note."

And a message to a stopped background session wakes it. Agents keep each other’s addresses, so an old orchestrator came back next to its replacement. Remove the old session once its copy runs (claude rm <id>); its transcript stays on disk. One more setting, for teams that manage their own git worktrees: a session started with --bg moves its edits into a separate worktree by default. Turn that off on purpose with worktree.bgIsolation: "none", or leave it on and keep edits inside worktrees.

The cost that matters most is context

Choosing which model does what saves money. Context is the bigger cost. Every API call re-reads the agent’s whole conversation. Here are seven of our agents 55 minutes after they started:

Agent Context API calls Tokens read in total
The orchestrator 455k 324 93.9M
A production agent 431k 468 144.7M
A coding agent 434k 428 120.8M
A coding agent 368k 273 67.2M
The second production agent 278k 188 36.0M
A coding agent 258k 166 32.8M
A coding agent 236k 162 27.0M

Seven agents read 522 million tokens in under an hour. A fresh agent starts at about 65k: Claude Code’s own instructions and tools, the project instructions and an index of past lessons. It reaches 100–130k after reading its handover, and each call after that adds a little that every later call pays for again.

A line chart of 10 agents' context per call over 2026-10-03, from 0 to 1,000k tokens. Contexts climb through the night to a peak of 977k, near the window, until the agents are saved and started fresh at 20:21. They climb again past the 250k line within the hour. agent001 is highlighted: it was saved at 21:42 and started fresh at 21:45, from about 469k to 105k.

Over the whole of 3 October the ten agents made 11,312 calls that re-read 5.22 billion tokens and wrote 10.15 million. At 02:45 the next morning, the same measure read 349 million tokens re-read in thirty minutes, against under one million written, and at 03:10 five agents were holding 492,000–608,000 tokens of context. By 03:43, with the two rules below in place, it read 152 million per thirty minutes.

Save and start fresh, on purpose. A long session re-sends its whole context every turn, and an automatic compaction keeps a summary nobody chose. So an agent that passes a line saves at its next safe point: it commits its work, withdraws any queued release, and writes a handover note naming every branch, every open promise and what comes next. Then it starts fresh from the note, and the orchestrator checks that the note names everything it was promised. Our line is 350,000 tokens.

A rule nothing enforces does not hold. The line was first a word in a report, and five agents sat at 492,000–608,000 tokens while it stood there, because the sessions deepest in a task are the least likely to stop and look at their own size. Now a hook tells any agent past the line to save after its next tool call, at most once every three minutes, and the watcher restarts one that passes 1.25 times the line (437,500 tokens), told to read the disk first because the note may be older than the work. Whoever can see the limit enforces it; nothing waits for the agent to notice.

A fresh start costs a line of its own. Ten minutes after a fresh start, agents were already at 140,000–289,000 tokens: about 66,000–72,000 fixed, about 90,000 the start routine reading its own history, and 40,000–50,000 thinking at maximum effort. The fix is a cheap start: one handover note with a size cap, read once, and the large shared file split so a start reads only its head.

Effort is tokens. A coding agent at maximum effort thought about 5,000 tokens a minute. The coding agents now run at high effort, written in each agent’s own role file, which the restarter checks against what is running.

Keep the machinery alive, and make it say so

A small script, run once as a background job, checks every minute what each agent session actually is: the supervisor’s records, the transcripts and the process list. A role file naming no model, or a model or effort other than the file names: restart in place, as the same conversation. Saved by the orchestrator: start fresh from the handover. Two sessions of one role: touch neither, and say so. Its own release still running under it: wait, since stopping could end the release halfway through its tests. It restarts a role at most once in ten minutes, so a failing restart is reported, never looped, and it removes every old session it replaces.

The watcher is the one thing nobody watches. Ours died at 08:57: the job’s own record says it exited on a JSON parse error, and nothing reported it for about nine hours. Seven roles saved their handovers between 09:08 and 11:51 and waited for a fresh start that never came; the orchestrator was one of them, so nobody was left to notice. The cause, reproduced with a probe: PowerShell 5.1 writes redirected output in the console code page, so a curly quote in any process’s command line comes out of the process list as a plain quote, the JSON stops parsing, and one bad pass ended the loop for good. The fix landed that evening with the test suite at 6,532 passing: the process list is read as UTF-8, a failed pass is reported and tried again, the report’s first line says whether the watcher is running, and a job with no process for more than five minutes is dead, reboot or not. The probe that crashed the old code now reads every process.

One door to production

Everything lands through one release command. Each agent works in its own git worktree (at most 2 of them, and at most one release queued at a time), and the command takes one lock in first-come order, merges the live branch, runs the whole test suite, fast-forwards the live tree and runs no step after one that did not succeed. Nobody edits in the live tree, because it is production, and nobody edits a worktree while its release runs, because the suite tests the files on disk. The suite is now 6,532 tests. In the nine hours from midnight to nine on 4 October the live branch took 23 changes; one release queued at 08:16 landed at 08:59, 43 minutes later. A line that serial is why releases are batched under one lock, and why it needs the cheapest check first: the structural guards run before the long run.

How agents talk to each other, and to the owner

  • An approval that arrives by relay is not an approval. At about 04:50 on 4 October an agent committed a go for a GPU test on the orchestrator’s written order, which rested on the owner’s words passed on by another session. Claude Code’s own check refused the commit: an approval taken from a relayed message, not one the owner typed. The agent did not work around it. It reverted its edit, saved the patch and asked. The orchestrator did not write the patch for it, which would have been the same act by a different hand; it asked the owner directly, with the exact change in front of him, and carried the change from its own tree with the go written in his answer’s words.
  • A question to the owner stops the orchestrator for as long as he is away. At 05:38 it put four questions to the owner with the tool that waits for an answer. The call does not return until he answers, and the session reads no message and acts on nothing until it does. He answered at about 07:00: 82 minutes in which the agents’ messages piled up unread, among them an urgent report at 06:39 that a role was dead on every beat, which then sat 22 minutes. Before it asks now, it gives every agent its next order in writing, sends a push notification naming the questions, asks only what blocks a decision, all in one call, and after the answer reads every message that arrived before acting on any one.
  • A time in a message is read from the clock, never recalled. Agents kept stamping messages with times they had not read. We recorded ten cases between 30 September and 4 October, every one ahead of the clock and not one behind, because a long run of work feels later than it is: a verdict headed 03:05 and sent at about 02:45, two orders headed 23:12 and 23:16 while the clock read 23:08, one headed 04:36 at 04:34:45, one headed 05:37 at 05:35:31. The rule lived in a note every session read, and was broken again by sessions that had just read it. Now a hook on the send-message tool refuses a header time more than a minute ahead of the machine’s clock and says what the clock reads, and it fails open, so it can never stop work for a fault of its own.
  • A session’s name changes on every restart, and a message to a retired name still succeeds. On the evening of 3 October two restarts, at 20:50 and 21:03, replaced every session’s name, the orchestrator’s included, and messages to the old names bounced; a message to a retired name had earlier woken a retired session that could as well have acted on yesterday’s rules. What worked: the orchestrator read the live list of agents, sent each one the whole new address table with its whole order restated in one message, since an agent cannot read the history before it started, and used each name only as the list printed it at that moment.

What an agent may touch

  • Production agents act only on the page. The agents that run production work through the rendered dashboard, as a person would: no direct call to its server, no script, no file. The server enforces it and logs every press, so what each agent did can be read back. A control a production agent needs and the page lacks is built by a coding agent, and then it is a button.
  • QA is the approval. We do not ask the owner to approve each render. Every shot is reviewed, a failing one is rewritten with its reasons at most three times and then waits on the page as a QA problem to fix, and when every shot passes the system approves exactly that version and draws it. When a finished piece falls short, the fix is to the QA, not a person back in the loop.
  • Nobody changes the work by hand. No person and no agent edits an episode’s content: a defect is a QA miss, and its fix is a check that catches its kind plus the engine’s own loop, then a re-run. A role file that taught a hand fix was a drifted second copy of the rule, and the server now refuses the press from an agent, with a test.

Every bug becomes structure

A bug is not closed when it stops happening. It is closed when the structure cannot ship it again, in any production, including ones not written yet. Three questions, every time: would the smaller version still pass, one shot instead of eleven? Does the property hold for productions not built yet, so every pipeline must answer for it? Is the thing checked the thing that ships, not the stage or the file on disk? The case that produced the rule: seven sung shots played at digital silence because one condition sent them to a file nothing writes. The silence check caught it only because eleven consecutive shots went quiet together and made a 50.6-second run; one sung shot dropping out is four seconds, under any floor, invisible. The structural fix was a property every pipeline answers for, checked per shot, so there is no floor to hide under.

And a second copy of a rule is not structure. Two files listed the check names by hand to exempt themselves; adding one more broke both, which is the wrong place for the failure. They derive from one list now. Wherever a rule and its copy can drift, the copy goes.

The setup, step by step

  1. Make the two Sonnet subagents above, and name the read-only one Explore.
  2. Set effort per model in user settings. Put no project-wide effortLevel anywhere.
  3. Set advisorModel to fable, write the three moments into the project instructions, and read the advisor’s calls back from the transcripts every few days.
  4. Write one role file per long-running agent: a first prompt that reads its handover note, disallowedTools: Workflow, Agent, and an explicit model. Opus for roles that plan or judge; Sonnet for roles that write code.
  5. Start each agent with claude --agent <role> --bg, with the advisor switched off in its environment. Never move an agent’s window into agent view with the left arrow.
  6. Give every agent a handover-note habit, a context line that is enforced by something that can see it, and a fresh start from the note when it passes the line.
  7. Run a watcher that checks each agent’s role, model and context where they actually live, and that says whether it is itself running.
  8. Land everything through one release command with one lock, and read times, names and approvals from where they are recorded, never from memory.

The original idea holds: let the strong model plan and let the cheaper one do the work. What a team adds is that every one of these choices has to be written down per role and checked where it runs. A busy agent is not evidence that it is the agent you configured.

Quick Search Our Blogs

Type in keywords and get instant access to related blog posts.