Sub-Agents
Specialised agents (Explore, Plan, claude-code-guide, general-purpose). Parallel and isolated execution, when to delegate, and context-window protection.
What it is#
A sub-agent is a child instance of Claude Code that runs inside its own context window with its own tool budget and (usually) a constrained tool allowlist. The parent session launches a sub-agent via the Task tool, hands it a self-contained prompt, and receives a single summary back when the sub-agent finishes.
Sub-agents are how Claude Code handles units of work that:
- Would otherwise bloat the parent’s context with intermediate findings.
- Benefit from a focused tool surface (Explore agents do not need Edit; a “build the docs” agent does not need WebFetch).
- Can run in parallel with the parent’s other work.
- Have a clear definition of done.
The built-in agent types — general-purpose, explore, plan, and project-defined variants — cover the common cases. Custom sub-agents are how you bake a recurring delegated workflow into a single Task call.
When to use it#
Delegate to a sub-agent when:
- The investigation is wide. “Find every file that touches the auth module” can read ten files internally and return a one-paragraph map. The parent never sees the ten files.
- The work is parallelisable. Three sub-agents mapping three independent modules run concurrently; the parent gets three summaries at once.
- The tool surface should be narrow. An Explore agent with no Edit/Write cannot accidentally modify the codebase, no matter what the prompt says.
- The work would otherwise eat 30% of the parent’s context. Long greps, multiple file reads, big WebFetch results — all great candidates for delegation.
Do not delegate when:
- The work is small. A single grep, a single file read — those are cheaper inline than as a Task.
- The work requires tight back-and-forth. Sub-agents return one summary. If the work needs clarifying mid-flight, do it in the parent.
- You need the intermediate findings later. A sub-agent throws away its own scratchpad on return. If the parent needs the per-file details, do the work inline.
- The parent has nothing else to do. A serial Task is just a slower synchronous call. Delegation pays off when the parent uses the wait time productively.
How it works#
Built-in agent types#
| Type | What it’s for | Typical tool surface |
|---|---|---|
general-purpose | Anything that doesn’t fit a specialised type | Full tool access |
explore | Search-heavy investigation, no modifications | Read, Grep, Glob, WebFetch |
plan | Drafting a multi-step plan without executing | Read, Grep, Glob — no Bash, no Edit |
| Project-defined | Workflows specific to the project (security audit, release prep, schema migration) | Whatever the project authorises |
The agent type determines two things: the system prompt the sub-agent runs under, and the allowed tool list. Both are configurable for custom agents.
Launching via Task#
{ "tool": "Task", "subagent_type": "explore", "description": "Map the auth module", "prompt": "List every file under src/auth/. For each file, return its absolute path and a one-line summary of its role. Do not modify any files."}The Task tool starts the sub-agent loop, runs it to completion, and returns the final message. The parent sees only that final message — none of the sub-agent’s intermediate turns leak through.
Context isolation#
A sub-agent’s context window is a fresh start. It contains:
- The sub-agent’s system prompt (built from the agent type’s config).
- The
CLAUDE.mdfiles for the project. - The user prompt passed in the Task call.
It does not contain the parent’s conversation history. This is the whole point: the parent stays clean, the sub-agent stays focused.
The implication is that the Task prompt has to be self-contained. “Continue what we were discussing” does not work — the sub-agent has no history. Pass concrete instructions and any necessary context inline.
Parallel execution#
The parent can launch multiple Tasks in the same turn. They run concurrently:
[ { "tool": "Task", "subagent_type": "explore", "description": "Audit billing module", "prompt": "..." }, { "tool": "Task", "subagent_type": "explore", "description": "Audit auth module", "prompt": "..." }, { "tool": "Task", "subagent_type": "explore", "description": "Audit data layer", "prompt": "..." }]Three sub-agents run in parallel, each in its own context window. The parent receives all three summaries when they complete.
Tool allowlist as the safety boundary#
Each agent type declares the tools it can use. The harness enforces this — a sub-agent without Edit cannot edit, even if the prompt asks. This is the difference between asking the model to be careful and structurally preventing the failure.
Custom sub-agents lean on this hard. A “search the docs and propose changes” agent might have Read, Grep, WebFetch — but no Edit. The proposed changes come back as a markdown summary; the parent applies them under user control.
Configuration#
Built-in agents#
Built-in agent types ship with the CLI. Their configuration is not user-editable beyond what settings.json and CLAUDE.md already control.
Custom agents#
A custom sub-agent lives at ~/.claude/agents/<name>.md (user-scoped) or <project>/.claude/agents/<name>.md (project-scoped). The file has frontmatter and a system-prompt body:
---name: exploredescription: Search-and-summarise agent for repository investigationtools: [Read, Grep, Glob, WebFetch]model: sonnet---
You are an investigation agent for a Claude Code session.
Goals:- Use Grep, Glob, and Read to answer the user's question.- Return a concise summary (under 200 words) plus absolute file paths.- Do not edit files. Do not run shell commands.
Style:- Reply with the conclusion first, then evidence.- Cite paths absolutely. Include line numbers when relevant.Fields:
name— what the parent passes assubagent_type.description— shown when the parent considers which agent to use.tools— the allowlist.model— optional override.
Project vs user scope#
Project-scoped agents committed to the repo travel with the team. A security-audit agent every contributor can launch with one Task call. User-scoped agents are personal — your everyday Explore, your favourite Plan variant.
Examples#
Single-agent investigation#
The parent needs a map of a module before refactoring it.
{ "tool": "Task", "subagent_type": "explore", "description": "Map the queue subsystem", "prompt": "Map every file under src/queue/. For each: absolute path, the symbols it exports, and a one-line role description. Return as a markdown list. Do not modify files."}The Explore agent runs ten greps and reads, the parent gets one paragraph.
Three-way parallel mapping#
Three independent investigations, fired in one turn.
[ { "tool": "Task", "subagent_type": "explore", "description": "Map src/queue/", "prompt": "..." }, { "tool": "Task", "subagent_type": "explore", "description": "Map src/api/", "prompt": "..." }, { "tool": "Task", "subagent_type": "explore", "description": "Map src/db/", "prompt": "..." }]All three return concurrently. Total wall-time is the slowest one, not the sum.
A custom security-audit agent#
<project>/.claude/agents/security-audit.md:
---name: security-auditdescription: Audit a diff for security issuestools: [Bash, Read, Grep, Glob]model: opus---
You are auditing a diff for security issues.
Steps:1. Run `git diff main...HEAD`.2. For each modified file, grep for risky patterns: `eval(`, `child_process.exec`, `dangerouslySetInnerHTML`, raw SQL.3. Read context around each match.4. Produce a report: - Verdict (pass / concerns / blocked). - Findings: file + line + risk + suggested fix. - Negative findings: patterns that did not appear.
Do not modify files. Do not commit.Invoked from the parent:
{ "tool": "Task", "subagent_type": "security-audit", "description": "Audit pending changes", "prompt": "Audit the diff between the current branch and main."}Bad: nested delegation without good reason#
A sub-agent that immediately delegates to another sub-agent without doing useful work first is overhead with no benefit. Either the parent should have delegated to the right type in the first place, or the sub-agent’s job is too broad.
// BAD pattern: sub-agent's only move is to launch another sub-agent{ "tool": "Task", "subagent_type": "general-purpose", "prompt": "Launch an explore sub-agent and then..."}Prefer flat delegation: the parent picks the right specialised agent for the job.
Gotchas#
- The Task prompt is the only context the sub-agent has. No history, no shared memory beyond
CLAUDE.md. Write self-contained prompts. - Sub-agents have their own turn budget. A very large task can exhaust the budget before completing. Either narrow the task or grant a larger budget if the agent supports it.
- Returns are summaries, not transcripts. If you need the full per-file detail, do the work inline. The sub-agent’s intermediate work is gone after return.
- Tool allowlists are strict. An Explore agent without Edit cannot Edit. If the parent realises mid-flight that Edit is needed, it cannot grant it retroactively — relaunch with a different agent type.
- Parallel Tasks racing on the same file produce undefined results. The harness does not lock. Partition the work or serialise it.
- Don’t poll Task completion. The harness fires a notification when the sub-agent finishes. Chaining a
sleep ; checkis waste — the parent should do other work and respond to the notification. - Sub-agents do not see TodoWrite from the parent. Each agent has its own todo list. The parent typically tracks delegation as a single todo item.
- The system prompt for a custom agent is text the model reads. Audit it like code. A malicious or careless prompt body can mislead the agent.
- Cost compounds with parallelism. Five parallel sub-agents cost roughly five times one sub-agent. The savings is wall-clock, not money. Be intentional about scale.
Sub-agent vs slash command vs skill at a glance#
- Invoked via the Task tool
- Runs in an isolated context window
- Tool allowlist is enforced
- Returns one summary on completion
- Right for investigations, isolated refactors, audits
- Slash: typed by name; Skill: invoked by name or by intent
- Both run inline in the parent’s context
- No isolation — they consume the parent’s context
- Right for in-line packaged workflows
- Use a sub-agent inside a slash/skill if isolation is needed
Related features#
- The Task Tool — Background Work
- Custom Sub-Agents
- Skills — User-Invocable Workflows
- Context Window and Token Budget
- Slash Commands
The delegation reflex that takes a month to internalise
Most engineers underuse sub-agents for the same reason they underuse async work in code: synchronous feels concrete, async feels speculative. The shift happens once you’ve watched a long session degrade because the parent ate three modules’ worth of context for an investigation. The next time, you delegate the investigation, the parent stays sharp, the work finishes faster, and the reflex sticks. The break-even is much earlier than it feels — usually after the third file read you would have done inline. Once you’re delegating reflexively, sub-agents become the default and inline work becomes the exception.