Chapter D1.2 established when to reach for a subagent and how to cut the work. This chapter drops one level — to the mechanics of actually defining and invoking one, and reading what crosses each way across the context boundary. The exam tests whether you can read an AgentDefinition, predict whether it will be invoked at all, and say what crosses into the subagent’s fresh context and what crosses back — and what silently does not.
The Agent tool is the invocation surface
A subagent is invoked through exactly one tool — the Agent tool — and there are three ways to give that tool something to invoke. [Official] Subagents in the SDK · AnthropicT1-official original Everything in this chapter hangs off that one tool: how you define what it runs, how you allow it to run, and what crosses the boundary in each direction.
One naming wrinkle is load-bearing on the exam and in tool-name filters. The tool was renamed from Task to Agent in Claude Code v2.1.63; current SDK releases emit Agent in tool_use blocks but still report Task in the system:init tools list and in result.permission_denials[].tool_name.
[Official]
Subagents in the SDK · AnthropicT1-official original Code that filters on the tool name must check both values.
AgentDefinition is the subagent’s contract
When you create a subagent programmatically, its AgentDefinition is a contract with two required halves: a description that says when to use it and a prompt that says how it behaves.
[Official]
Subagents in the SDK · AnthropicT1-official original Everything else is optional refinement.
| Field | Required | Purpose |
|---|---|---|
description | yes | Natural-language when to use this agent — drives automatic matching |
prompt | yes | The agent’s system prompt: its role and behavior |
tools | no | Allowed tool names; omit to inherit all of the parent’s tools |
model | no | Model override (sonnet / opus / haiku / inherit / full ID) |
maxTurns | no | Cap the subagent’s agentic turns (its own budget) |
The description does double duty — it is also how Claude decides to invoke the agent automatically (below), so write it specific and keyword-rich rather than generic.
[Official]
Subagents in the SDK · AnthropicT1-official original
Enabling invocation: Agent in allowedTools
A defined subagent will not run unless the Agent tool itself is approved. Always include "Agent" in allowedTools to auto-approve subagent invocations; without it, the call falls through to your canUseTool callback or — in dontAsk mode — is denied outright.
[Official]
Subagents in the SDK · AnthropicT1-official original
The prompt string is the only channel in
A subagent starts in a fresh context window, and the only thing that crosses from parent to child is the Agent tool’s prompt string. [Official] Subagents in the SDK · AnthropicT1-official original
“A subagent’s context window starts fresh (no parent conversation) but isn’t empty. The only channel from parent to subagent is the Agent tool’s prompt string, so include any file paths, error messages, or decisions the subagent needs directly in that prompt.” [Official] Subagents in the SDK · AnthropicT1-official original
What that means concretely — the subagent receives its own system prompt (AgentDefinition.prompt), the Agent-tool prompt, the project CLAUDE.md (loaded via settingSources), and its tool definitions. It does not receive the parent’s conversation or tool results, the parent’s system prompt, or any preloaded skill content.
[Official]
Subagents in the SDK · AnthropicT1-official original Permissions are part of what does not cross: a subagent does not inherit the parent’s permissions — each runs its own evaluation chain — so a tool the parent could use is not automatically usable by the child.
[Official]
Configure permissions · AnthropicT1-official original
What crosses back: the return channel
The boundary is asymmetric, and the exam probes the outbound side too. When the subagent finishes, the parent receives the subagent’s final message as the Agent-tool result — but the parent may summarize it rather than carry it through verbatim. If a downstream step depends on the subagent’s exact output (a precise list, a diff, a structured payload), instruct the main agent to preserve the subagent’s result verbatim.
[Official]
Subagents in the SDK · AnthropicT1-official original Two more facts ride the return path: every message generated inside the subagent carries a parent_tool_use_id linking it to the invoking Agent call,
[Official]
How the agent loop works · AnthropicT1-official original and the subagent’s transcript persists independently of the main conversation (it survives main-session compaction).
[Official]
Subagents in the SDK · AnthropicT1-official original
Invocation paths and the one-level limit
Once Agent is allowed, a subagent is invoked one of two ways.
[Official]
Subagents in the SDK · AnthropicT1-official original
- Automatic — Claude matches the subagent’s
descriptionto the task. This is why the description must be specific and keyword-rich. - Explicit — name the agent in the prompt (“Use the code-reviewer agent to check the auth module”), bypassing automatic matching.
There is a hard structural limit: subagents cannot spawn subagents. Don’t include Agent in a subagent’s tools array — delegation is one level deep.
[Official]
Subagents in the SDK · AnthropicT1-official original
Practice
Exercise solutions
Two faults, neither in the tools array. (1) "Agent" is not in the parent’s allowedTools, so the Agent-tool call is never auto-approved — it falls through to canUseTool (or is denied in dontAsk). Fix: add "Agent" to allowedTools. (2) description: "Reviews things" is too vague for automatic matching — descriptions must be specific and keyword-rich. Fix: rewrite it (e.g. “Review Markdown/docs for accuracy, broken links, and stale references; read-only”), or invoke the agent explicitly by name to bypass matching. The tools: ["Read", "Grep", "Glob"] set is exactly right for read-only review — leave it. The two faults map to the two gates: allowedTools is the run gate, the description is the match gate.
Programmatic (an AgentDefinition in the agents option) — the recommended path for SDK apps; filesystem (.claude/agents/*.md, loaded at startup); and the built-in general-purpose agent. The built-in needs no AgentDefinition because it ships with a default description and prompt — Claude can invoke it through the Agent tool with nothing defined, which is why it is the zero-config fallback.
The return channel is lossy by default: only the subagent’s final message returns to the parent, and the parent may summarize it. So the coordinator is acting on a paraphrase of the reviewer’s findings, not the exact file:line list the subagent produced. The fix is to instruct the main agent to preserve the subagent’s result verbatim (and have the reviewer return a structured, easily-quoted format). The subagent’s own transcript being correct is the tell that the loss happened on the way back, not inside the subagent.
Exam essentials
- One tool, three creation paths: subagents are invoked via the Agent tool (renamed from
Task— filters must match both), created programmatically (agentsoption, recommended), via filesystem (.claude/agents/*.md), or as the built-ingeneral-purposeagent. AgentDefinition=description+prompt(both required);tools/model/maxTurnsoptional. Thedescriptiondrives automatic matching, so make it keyword-rich.Agentmust be inallowedToolsor the subagent never runs. Two gates: description matches,allowedToolsruns.- The prompt string is the only inbound channel. A subagent gets a fresh context — no parent conversation, no parent system prompt, no preloaded skills — but does get project CLAUDE.md + its tools. Permissions do not inherit; each subagent has its own evaluation chain.
- The return channel is asymmetric and lossy: the parent receives the subagent’s final message but may summarize it; instruct the main agent to preserve it verbatim when fidelity matters.
parent_tool_use_idattributes a message to its subagent. - Delegation is one level deep: subagents cannot spawn subagents (no
Agentin a child’stools).