Why subagents
Sometimes the agent needs to go on a long detour — "search the whole repo for everywhere we read config" — that takes a dozen tool calls and reads thousands of lines. If all of that lands in the main conversation, the parent's context window fills with grep output and half-read files, and the thread you actually care about gets buried. A subagent solves this: you hand it the detour, it does the work in its own context window, and it hands back only the answer.
This is the Task tool. The parent spawns a child agent, the child runs its own loop to completion, and the parent receives a single text result — never the child's intermediate tool calls. This chapter builds it: parse an agent definition, run one in isolation, and dispatch several at once.
Context isolation
A subagent is not a function call into the parent's conversation. It is a separate agent loop with three walls around it:
- Fresh messages. The child starts with an empty history — just its own system prompt and the prompt the parent gave it. No parent turns, no parent file reads, nothing leaks in.
- Its own tool allowlist. The child can be restricted to a subset of tools (a research agent that may
GrepandReadbut neverBash), independent of what the parent is allowed. - Only the final message comes back. Whatever the child did — every
tool_use, everytool_result, every intermediate turn — stays inside the child's window. The parent sees one string: the child's last assistant text.
That is the whole point. The detour's cost is paid in the child's context, not the parent's. A 40-turn search that returns "config is read in 3 places: a.ts, b.ts, c.ts" costs the parent exactly that one sentence.
parent loop ──▶ Task(Explore, "where do we read config?")
│
▼ (fresh context, own allowlist)
child loop: Grep → Read → Grep → Read → … → end_turn
│
▼ only the final text crosses back
parent loop ◀── "config is read in a.ts, b.ts, c.ts" ← 1 message, not 40
The parent cannot inspect how the child reached its answer — there is no transcript handed back, only the last assistant text. That is a feature, not a limitation: it is what keeps the parent's window clean. If the child needs to surface a file path or a list, it must put it in that final message. Anything left in an intermediate tool result is gone the moment the child returns.