Subagents
A subagent is a second Claude, started fresh, given one task, and asked to report back. It has its own context window. It reads whatever it needs, and none of that reading lands in your session; only its final answer comes back.
That is the entire pitch, and it is a real one. It is also narrower than most people assume, so this lesson measures it rather than describing it.
Measure it
Same question, twice, in a stockroom clone. Once directly:
Summarise what each file in src/ does, one line each.
Once delegated:
Use the Explore subagent to do this: summarise what each file in src/ does, one line each.
Both with --output-format json, reading the token count the main conversation ended up
carrying:
| Run | Main context | Cost | Turns |
|---|---|---|---|
| Direct | 180,796 | $0.2828 | 17 |
| Delegated | 42,469 | $0.2895 | 1 |
Read that table carefully, because the second column is the interesting one.
Your context is four times smaller. The reading happened in the subagent’s window, and what came back was a summary. Your session can keep going for a lot longer.
It did not save money. It cost slightly more. The files still got read; they just got read somewhere else, and somebody paid for it.
That is the honest shape of a subagent. It is a context management tool, not a cost management tool. Anyone who tells you delegation is cheaper is measuring the wrong thing.
What it can and cannot see
This is where the surprises live. A subagent starts with:
- its own system prompt, from the agent definition
- the task you or Claude handed it
- your
CLAUDE.mdhierarchy - a git status snapshot
- any skills its definition preloads
It does not get:
- your conversation history
- the files Claude already read
- the skills you already invoked
- anything you explained three turns ago
So the failure is predictable: you spend twenty turns establishing what you want, delegate the work, and get back something that ignores half of it. The subagent was never told. It was not being difficult; it was not there.
The fix is to write the handoff as though to somebody who just walked in, because that is exactly what happened.
Using one
Three ways, in increasing order of certainty:
Ask in English. “Use a subagent to find every place stock levels are computed.” Claude decides which one and what to say.
Name it. @agent-code-reviewer review the reports module guarantees that agent runs.
Run the whole session as one. claude --agent code-reviewer starts a session that is
that agent throughout.
There are built-in ones. Explore is the read-only search agent and the one you will use
most: it is for “find me all the places that do X” where you want the answer and not the
forty files it read to get it.
Writing your own
.claude/agents/report-reviewer.md:
---
name: report-reviewer
description: Reviews a new or changed report in stockroom against the conventions of
src/reports/index.ts. Use after adding or changing a report.
tools: Read, Grep, Glob, Bash
model: sonnet
---
You review report code in stockroom. You do not change anything.
Check the report against these, and say which ones it fails:
1. It takes `store: JsonStore` first and returns plain data, not formatted text.
2. It uses one of the file's three existing error conventions, and a comment says which
and why. The three are: `history` throws, `valuation` returns null, `variance`
returns `{ ok: false }`.
3. If it returns a list, it pages with `paginate()` rather than slicing.
4. Money is whole cents. There are no floats anywhere in the arithmetic.
5. There is a test in `test/reports.test.ts` that would fail if the report were wrong.
Report as a numbered list of failures, worst first, each with a file and line. If it
passes all five, say so in one line and stop.
name and description are required; everything else is optional. tools is an allowlist,
and leaving Write and Edit off it is what makes this agent structurally unable to change
your code rather than merely instructed not to. model lets a mechanical checker run on a
cheaper model than your session.
Files go in .claude/agents/ for the project or ~/.claude/agents/ for you.
When is a subagent the wrong call?
When the task needs conversation. A subagent gets one prompt and returns one answer. Anything that needs “no, not like that” belongs in your session.
When the context is the point. Planning, then implementing, then testing share everything. Delegating the middle one means re-establishing all of it.
For a small change. The subagent starts cold and has to find its way around before it can do anything. On a two-line fix that is all cost and no saving.
When you will not read the output. A subagent returns a summary, and a summary is the easiest thing in this course to accept without checking. Lesson 27.
Several at once, on the same files. Two subagents editing the same file is a race, and the loser’s work vanishes without an error.
The pattern that works
Reading, in parallel, when you know what you are looking for and not where it is.
Use three subagents in parallel: one to find everywhere in src/ that sums the movement
ledger, one to find everywhere that formats a date for display, and one to find
everything that reads from src/config.ts. Report file and line only, no explanation.
Three independent searches, three separate context windows, three lists come back. Your session ends up with the lists and not with the reading, which is exactly the trade in the table at the top.
The pattern that does not work is the same sentence with “and fix them” on the end.
Your turn
Reproduce the measurement, because the number for your setup is the one that matters.
Q="Summarise what each file in src/ does, one line each."
claude -p --output-format json "$Q" < /dev/null > /tmp/direct.json
claude -p --output-format json "Use the Explore subagent to do this: $Q" \
< /dev/null > /tmp/delegated.json
python3 -c "
import json
for n in ('direct','delegated'):
d = json.load(open(f'/tmp/{n}.json')); u = d['usage']
ctx = u['cache_read_input_tokens'] + u['cache_creation_input_tokens'] + u['input_tokens']
print(n, f'context={ctx:,}', '\$%.4f' % d['total_cost_usd'],
d['num_turns'], 'turns')
"
Check: the delegated run’s context is several times smaller than the direct one, and the two costs are within a factor of two of each other. If your delegated run is also much cheaper, read both answers: the subagent probably did less work, and the saving is not free after all. If the delegated context is not smaller, the subagent did not run and the phrasing did not land.
Then write the report-reviewer agent above into .claude/agents/, add a deliberately
sloppy report to src/reports/index.ts that slices instead of paging, and run
@agent-report-reviewer. It should name check 3.
Recap
A subagent is a fresh Claude with its own context window, one task, and no memory of your conversation. It keeps large reads out of your session, measurably: four times less context in the run above. It does not make the work cheaper, because the reading still happens.
It cannot see your history, so write the handoff for somebody who just walked in.
Use it for parallel reading where you know what you want. Avoid it for anything iterative, anything small, anything that shares context with what comes next, and anything where two of them would touch the same file.
Leaving Write and Edit out of an agent’s tools is the difference between an agent that
should not edit and one that cannot.
Next: making the harness do something every time, whether the model cooperates or not.