Chapter 7 · Capabilities built on the loop
Subagents
Handing part of a task to a second agent loop keeps the main context clean and can save time. But some information gets lost on the way, and the extra loop costs tokens.
A subagent is another loop
Suppose Patch needs every place in the code that checks whether a login token has expired. Finding them means searching and reading about thirty files, but the answer is three lines. If Patch searches itself, all thirty files land in its own context. In a simple loop they stay there until something compacts them (chapter 4).
Instead, Patch can call a tool named delegate with a short request. Behind that tool, your code starts a second agent loop. In the simplest design, that loop gets its own instructions, its own tools, and an empty history. When it stops, your code returns its final message to Patch as the tool result.
Main agent | | delegate("find every expiry check") v Second agent loop own instructions, own tools, empty history | searches, reads, repeats | result: three file:line references v Main agent sees only the result
For the main agent, called the parent, this is an ordinary tool call. Only the inside of the tool is new: it runs a whole agent loop, called the child, instead of a function.
def delegate(call): # a tool, like read_file
child = Agent(
system=EXPLORER_PROMPT, # its own instructions
tools=[search_files, read_file], # its own tools
)
report = child.run(call.args["objective"], max_steps=15) # a whole loop
return tool_result(call.id, report) # the parent sees only this
What a subagent can change
A research agent might start one child per source, each with the same instructions and tools as the parent and a different brief. A coding agent might start a reviewer with its own prompt, read-only tools, and a cheaper model.
So "subagent" names a set of choices, and only the separate loop is fixed.
| Choice | Options | Why change it |
|---|---|---|
| Instructions | The parent's, or a prompt for one job | Focus on that job |
| Tools | The same, fewer, or different | A reviewer that cannot write |
| Model | The same, or a cheaper one | Cost and speed for simple searches |
| Starting context | Only the brief, or a copy of the parent's conversation | A clean start, or a cheap one |
| State | Its own, or shared files and data | Pass big results by reference |
| Budget | Steps, tokens, time | Cap what one delegation can cost |
| Lifetime | The parent waits, or it runs in the background | Long tasks and parallel work |
The delegation contract
Suppose the parent writes the brief "look into the auth bug". If the child starts with no history, it does not know which bug, which files the parent already read, or what answer is wanted. So it will probably spend its budget rediscovering what the parent knew, then return a vague report.
A useful brief works like a contract between the two loops. It covers eight things:
brief = {
"objective": "List every place that checks token expiry. Do not fix anything.",
"constraints": ["skip tests/fixtures", "all datetimes are timezone-aware"],
"tools": ["search_files", "read_file"], # what it may do
"output": "path:line plus one sentence each, at most 900 tokens",
"budget": {"max_steps": 15, "max_tokens": 60_000, "timeout_s": 300},
"owns": ["notes/expiry-sites.md"], # the only file it may write
"cancel": "the parent can stop it; notes written so far stay",
"reconcile": "the parent re-reads each line before editing it",
}
Some of these fields are only requests, and some can be guarantees. The objective and the output format are text, so the child may drift from them. But your code starts the child, so it can enforce the tools, the budget, and the files the child may write. For example, "do not edit files" is a request, while read-only tools make editing impossible.
In practice, the parent model writes the objective and the facts it knows. Your code fills in the tools, the budget, and the owned files from a fixed template, so the model cannot loosen them.
Call and return, or hand off
A support agent receives "I was charged twice." It could call a billing subagent, wait for its findings, and answer the customer itself. Or it could hand the whole conversation to a billing agent, which then talks to the customer directly.
The first pattern uses an agent as a tool: the parent calls it, waits for the result, and stays in charge. The second is a handoff: the first agent passes control to another agent and steps out.
Agent as a tool Handoff Parent --delegate--> Child Support --hand off--> Billing Parent <--result---- Child | Parent answers the user v Billing answers the user
Use call and return when the parent has to combine results or keep one voice toward the user. Use a handoff to route a conversation to a specialist. A handoff usually moves the conversation itself to the new agent, while a called child usually starts with only its brief.
Context isolation, and its limits
In chapter 4, Patch's explorer read 31,000 tokens of code and returned a 900-token report. The parent's context grew by 900 tokens, not 31,000. That is context isolation: the child's reading stays in the child's context.
But isolation only covers what each model sees, not what each agent can change. People often blur four different arrangements.
| Arrangement | What is shared | Good for | Watch out for |
|---|---|---|---|
| Shared files | A folder or repo | Passing big results by reference: write notes, return the path | Two children editing one file |
| Shared data | One state object in your code, such as a todo list | Results that flow back without entering the parent's context | Parallel writes need merge rules |
| Shared conversation | A copy of the parent's message history | A cheap start for the child | No isolation: the child inherits the clutter |
| Nothing shared | Brief in, report out; its own worktree | Risky or fully separate work | Every fact must travel in the brief or the report |
If children write files, give each writer its own checkout or git worktree, so their edits cannot collide. A worktree is not an access limit, though, because an unrestricted process can still reach the others. To really block access, check paths in your tool code, or use mounts and OS permissions (chapter 10).
Specialization
Say a reviewer subagent's prompt says "you are a careful security reviewer", and it has no tool that can write. Only the missing tools are a guarantee. The prompt shapes what it tends to do, but the tools decide what it can do.
The cost is that a specialist knows less. For example, a reviewer that sees only the diff cannot tell whether the change matches the plan. Put what it needs in the brief.
Running children at the same time
Suppose three children take 2, 3, and 2.5 minutes. If the parent asks for all three in one reply, and nothing slows them down, they finish after 3 minutes. That is the time of the slowest one. One after another, they would take 7.5 minutes.
This saves time, but it does not save tokens. The extra tokens come from four places:
- each child sends its own instructions and tool definitions on every one of its calls;
- each child sends its brief on every call, too;
- children re-read files the parent already knew, because they start empty;
- and the parent makes extra calls to write the briefs and combine the results.
The time saving has limits too, because provider rate limits can make the children wait for each other.
Combining the results
In the simulator below, a child researching Redis reads a config file. It shows that the team's Redis server deletes old data when memory runs low. The child's short summary leaves that out. So the parent recommends Redis for a job queue, where losing jobs is a real problem.
This step, combining what the children send back, is called aggregation. Each result is a claim written by another model, not proof. Summaries drop details, and by the time the parent reads one, the child is usually gone. Results can conflict, and then the parent needs evidence, such as the original document or a test. Reports also go stale: a child says "the test passes", then another child changes a file the test depends on.
So design what comes back:
- Ask for references, such as file:line or a URL, so the parent can re-check claims cheaply.
- Ask for risks as a separate field, because a free-form summary drops them first.
- Have the child write full notes to a file it owns, and return the path.
Returning full transcripts instead would lose nothing. But the parent's context would fill up with everything every child read, which undoes the isolation you delegated for.
Try it: the subagent simulator
Patch's team needs a job queue for background work. The parent asks three children to research one option each: Redis Streams, RabbitMQ, and Amazon SQS. Try each scenario, then change what comes back and whether the children run at the same time.
When two children edit one file, each does what its brief says. The conflict comes from how the work was split.
Children that start children
Suppose every agent may start three children, and each of those may start three more. Three levels then give you 3 + 9 + 27 = 39 agent runs. Each level also passes along a summary of a summary, so details fade.
Most designs cap it with a maximum depth, a maximum number of children, and one budget shared by the whole tree. Hermes and Deep Agents both keep depth at one level by default, because their children get no tool for starting more children.
def delegate(call, depth, budget):
if depth >= MAX_DEPTH:
return error(call.id, "delegation depth limit reached")
share = budget.take(steps=15, tokens=60_000) # the whole tree shares one budget
tools = CHILD_TOOLS if depth + 1 < MAX_DEPTH else CHILD_TOOLS - {"delegate"}
report = run_child(call.args, tools, share, depth + 1)
budget.give_back(share.unused())
return tool_result(call.id, report)
When multiple agents help
Four problems justify a subagent most often:
- Independent parts, such as three sources to research, which can run at the same time.
- Noisy searching. Finding the answer means reading far more than the answer, and isolation keeps that reading out of the main context.
- Different permissions, such as a read-only explorer.
- A fresh review. A reviewer that never saw the author's reasoning judges the change itself.
Anthropic reports one result from its research system. A Claude Opus 4 lead with Claude Sonnet 4 subagents outperformed a single Claude Opus 4 agent by 90.2% on its internal research eval. The same post says multi-agent systems use "about 15× more tokens than chats", and that "most coding tasks involve fewer truly parallelizable tasks than research".
A complex task is not, by itself, a reason. It often needs one agent with a better context, not several agents that each see only part of it.
When they cost more than they give
Skip them in these cases:
- The parts are linked. Edits to the same files, or decisions that depend on each other, drift apart when made in separate contexts.
- The task is small, so the briefs, the extra instructions, and the merging cost more than the work.
- The parent needs the details that a summary would drop.
Pi takes the skeptical side on purpose. It has no built-in subagent tool, though its repository ships an example extension that adds one. Its creator, Mario Zechner, calls parallel subagents building separate features "an anti-pattern in my book".
So start with one agent. When you add a subagent, measure whether it helped (chapter 16). Then check that the gain came from the extra agents (chapter 18).
Running example: Patch gets two helpers
Patch version 7 gets two subagents, both called like any other tool. The explorer searches the code and returns file:line references. The reviewer can only read, and its brief carries the diff and the test results. Patch still makes every edit itself, because edits to the auth code depend on each other.
# Patch v7: two subagents, called like any other tool
+ explorer = Subagent(prompt=EXPLORE, tools=[search_files, read_file],
+ output="at most 900 tokens, path:line refs", max_steps=15)
+ reviewer = Subagent(prompt=REVIEW, tools=[read_file],
+ output="findings with path:line, no edits", max_steps=8)
+ tools += [delegate(explorer), delegate(reviewer)]
What goes wrong
The summary dropped what mattered
- Why it happens
- The child chooses what to report under a size limit, and a free-form summary keeps the headline but drops the warning.
- How to spot it
- The parent acts on a claim that has no reference, and later the child's notes show the missing fact.
- What to do
- Ask for risks as their own field, with references, and keep full notes in a file the parent can read.
Two children edit the same file
- Why it happens
- Each child follows its own brief and does not know the other exists, so the last write wins.
- How to spot it
- Two children's change lists touch the same file, or the tests pass for each child and fail after merging.
- What to do
- Give each writer its own worktree, or do linked edits in one agent. Where a write must be blocked, check paths in your tool code.
Children disagree
- Why it happens
- They read different sources or misread the same one, and a wrong claim can sound as sure as a right one.
- How to spot it
- Compare the same field across reports, and flag contradictions before merging.
- What to do
- Settle it with evidence, such as the original source or a test. Chapter 15 goes deeper.
You decide, AI builds
Decide yourself
- Whether a task needs a subagent at all.
- Each subagent's tools, budget, output format, and writable files.
- What parent and child share: files, data, the conversation, or nothing.
- How the parent checks results before acting on them.
Delegate to AI
- The delegate tool and the code that runs child loops.
- Checking results against an output format, with one retry.
- Counting tokens and steps across the whole tree.
- Saving and linking each child's transcript.
Check yourself
What is a subagent, mechanically? (Q12)
Answer
A tool whose code runs another agent loop, with its own context and usually its own instructions, tools, and budget.
When should you avoid splitting work across several agents? (Q13, Q14)
Answer
When the parts are linked. Separate contexts make separate choices, and the last write wins. The other two are good reasons to use subagents.
Three children take 4, 6, and 9 minutes, and nothing slows them down. How long do they take at the same time, and one after another?
Answer
9 minutes at the same time, because the parent waits for the slowest child, and 19 minutes one after another. The parent's own calls come on top.
Takeaways
- Ask children for references and risks, and check their reports before acting on them.
- Write the brief as a contract, and let your code enforce the tools, the budget, and the files each child may write.
- Add a subagent only when you can name the problem it solves.
Going deeper
- How we built our multi-agent research system (Anthropic, June 2025). A lead agent with parallel subagents, with numbers on cost and fit.
- Don't Build Multi-Agents (Cognition, June 2025). The case against: subagents that cannot see each other's decisions build parts that do not fit together.