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.

FieldRequiredPurpose
descriptionyesNatural-language when to use this agent — drives automatic matching
promptyesThe agent’s system prompt: its role and behavior
toolsnoAllowed tool names; omit to inherit all of the parent’s tools
modelnoModel override (sonnet / opus / haiku / inherit / full ID)
maxTurnsnoCap 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

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

Solution ↑ Exercise

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.

Solution ↑ Exercise

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.

Solution ↑ Exercise

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