Skip to main content
Subagents are separate agent instances that your main agent can spawn to handle focused subtasks. Use them to isolate context, run multiple analyses in parallel, and apply specialized instructions without adding to the main agent’s prompt. This guide explains how to define and use subagents in the SDK using the agents parameter.

Overview

You can create subagents in three ways:
  • Programmatically: use the agents parameter in your query() options. See the TypeScript and Python references
  • Filesystem-based: define agents as markdown files in .claude/agents/ directories. See defining subagents as files
  • Built-in general-purpose: Claude can invoke the built-in general-purpose subagent at any time via the Agent tool without you defining anything
This guide focuses on the programmatic approach, which is recommended for SDK applications. When you define subagents, Claude determines whether to invoke them based on each subagent’s description field. Write clear descriptions that explain when to use the subagent, and Claude automatically delegates appropriate tasks. You can also explicitly request a subagent by name in your prompt, for example “Use the code-reviewer agent to…”.

Benefits of using subagents

Context isolation

Each subagent runs in its own fresh conversation. Intermediate tool calls and results stay inside the subagent; only its final message returns to the parent. See What subagents inherit for exactly what’s in the subagent’s context. Example: a research-assistant subagent can explore dozens of files without any of that content accumulating in the main conversation. The parent receives a concise summary, not every file the subagent read.

Parallelization

Multiple subagents can run concurrently, so independent subtasks finish in the time of the slowest one rather than the sum of all of them. Example: during a code review, you can run style-checker, security-scanner, and test-coverage subagents simultaneously instead of sequentially.

Specialized instructions and knowledge

Each subagent can have tailored system prompts with specific expertise, best practices, and constraints. Example: a database-migration subagent can have detailed knowledge about SQL best practices, rollback strategies, and data integrity checks that would be unnecessary noise in the main agent’s instructions.

Tool restrictions

Subagents can be limited to specific tools, reducing the risk of unintended actions. Example: a doc-reviewer subagent might only have access to Read and Grep tools, ensuring it can analyze but never accidentally modify your documentation files.

Create subagents

Define subagents directly in your code using the agents parameter. Claude invokes subagents through the Agent tool, so include Agent in allowedTools to auto-approve subagent invocations without a permission prompt. Most examples on this page print only the final result. To confirm that Claude delegated to a subagent rather than answering directly, see Detect subagent invocation. This example creates two subagents: a code reviewer with read-only access and a test runner that can execute commands.

AgentDefinition configuration

In the Python SDK, multi-word field names such as disallowedTools and mcpServers keep their camelCase spelling to match the wire format rather than following Python’s snake_case convention. See the AgentDefinition reference for details. Two subagent behaviors changed in Claude Code v2.1.198:
  • Subagents run in the background by default. An Agent tool call that omits the run_in_background input launches a background subagent, and Claude sets run_in_background: false when it needs the result before continuing. Before v2.1.198, omitting run_in_background ran the subagent synchronously. Set the background field to true to force background execution for a specific agent regardless of what Claude requests.
  • A subagent inherits the main session’s extended thinking configuration. On earlier versions, extended thinking is disabled inside subagents regardless of the main session’s setting.
By default, subagents can’t spawn subagents of their own. To let them, set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH to the number of subagent layers you want below your main conversation, 2 or higher; see nested subagents. From Claude Code v2.1.172 through v2.1.216, subagents could nest by default, up to five layers.

Filesystem-based definition (alternative)

You can also define subagents as markdown files in .claude/agents/ directories. See the Claude Code subagents documentation for details on this approach. Programmatically defined agents take precedence over filesystem-based agents with the same name.
Even without defining custom subagents, Claude can spawn the built-in general-purpose subagent. This is useful for delegating research or exploration tasks without creating specialized agents. Include Agent in allowedTools so these invocations auto-approve without a permission prompt.

What subagents inherit

A subagent’s context window starts fresh, with no parent conversation, but isn’t empty. The only content you pass 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. A subagent that has the SendMessage tool starts with a list of the other named agents running in the session, so it knows which names it can send messages to. Claude Code adds the list to the subagent’s first turn automatically. A fork doesn’t get the list because it inherits the parent conversation instead. The list requires Claude Code v2.1.206 or later.
The parent receives the subagent’s final message as the Agent tool result, but may summarize it in its own response. To preserve subagent output verbatim in the user-facing response, include an instruction to do so in the prompt or systemPrompt option you pass to the main query() call.In v2.1.210 and later, Claude Code scans the final message for instruction-shaped patterns before the parent reads it. The scan treats three kinds of pattern differently:
  • Control-tag imitation: Claude Code neutralizes a tag that only the harness emits, such as a <system-reminder> block, in place. It inserts a backslash after the opening angle bracket and deletes nothing.
  • Permission-configuration mentions: Claude Code keeps references to the permission configuration, such as .claude/settings.json, bypassPermissions, or --dangerously-skip-permissions, as written.
  • Turn markers: a line that starts with Human: or Assistant: gets a backslash before the colon, so the message can’t imitate a conversation turn boundary.
For a control-tag or permission-configuration match, Claude Code prepends a [harness: ...] marker line naming the matched patterns; a turn-marker match doesn’t add the marker line. Those are the only modifications the scan makes: it never removes or rewords the subagent’s text.
An API error that ends the subagent early, such as a rate limit, is never delivered as its result. If a rate limit, overload, or server error cuts off a foreground subagent that already produced text output, the Agent tool returns that partial output with a note that the subagent didn’t finish. A subagent that produced nothing, or whose only output was tool calls with no text, fails with an error message, Agent terminated early due to an API error, followed by the error detail. See API errors in subagents for the foreground and background behavior. This partial-output handling requires Claude Code v2.1.199 or later. In v2.1.199, a rate limit, overload, or server error left the tool-calls-only shape with an empty partial result containing only the cutoff note.

Invoke subagents

Automatic invocation

Claude automatically decides when to invoke subagents based on the task and each subagent’s description. For example, if you define a performance-optimizer subagent with the description “Performance optimization specialist for query tuning”, Claude will invoke it when your prompt mentions optimizing queries. Write clear, specific descriptions so Claude can match tasks to the right subagent.

Explicit invocation

To guarantee Claude uses a specific subagent, mention it by name in your prompt:
This bypasses automatic matching and directly invokes the named subagent.

Dynamic agent configuration

You can create agent definitions dynamically based on runtime conditions. This example creates a security reviewer with different strictness levels, using a more powerful model for strict reviews.

Detect subagent invocation

Claude invokes subagents through the Agent tool. To detect when a subagent is invoked, check for tool_use blocks where name is "Agent". Messages from within a subagent’s context include a parent_tool_use_id field.
The tool name was renamed from "Task" to "Agent" in Claude Code v2.1.63. Current SDK releases emit "Agent" in tool_use blocks but still use "Task" in the system:init tools list and in result.permission_denials[].tool_name. Checking both values in block.name ensures compatibility across SDK versions.
The message structure differs between SDKs. In Python, you access content blocks directly via message.content. In TypeScript, SDKAssistantMessage wraps the Claude API message, so you access content via message.message.content. This example iterates through streamed messages, logging when a subagent is invoked and when subsequent messages originate from within that subagent’s execution context.

Resume subagents

You can resume a subagent to continue where it left off rather than starting fresh. A resumed subagent retains its full conversation history, including all previous tool calls, results, and reasoning. When a subagent completes, the Agent tool result includes a text block containing agentId: <id>. The built-in Explore and Plan agents are one-shot and don’t return an agentId, so use a custom agent or general-purpose when you need to resume. To resume a subagent programmatically:
  1. Capture the session ID: extract session_id from messages during the first query
  2. Extract the agent ID: parse agentId from the Agent tool result text
  3. Resume the session: pass resume: sessionId in the second query’s options, and include the agent ID in your prompt
You must resume the same session to access the subagent’s transcript. Each query() call starts a new session by default, so pass resume: sessionId to continue in the same session.When using a custom agent, pass the same agent definition in the agents parameter for both queries.
The example below defines a custom endpoint-finder agent. The first query runs it and captures the session ID and agent ID from the Agent tool result, then the second query resumes the session to ask a follow-up question that requires context from the first analysis.
Subagent transcripts persist independently of the main conversation:
  • Main conversation compaction: when the main conversation compacts, subagent transcripts are unaffected. They’re stored in separate files.
  • Session persistence: subagent transcripts persist within their session. You can resume a subagent after restarting Claude Code by resuming the same session.
  • Automatic cleanup: transcripts are cleaned up based on the cleanupPeriodDays setting, which defaults to 30 days.

Tool restrictions

Use the tools field to limit what a subagent can do:
  • Omit tools: the subagent gets every tool available to subagents
  • List tools: the subagent gets only those. A code reviewer that should never edit files, for example, gets ["Read", "Grep", "Glob"]
A tool you leave out isn’t in the subagent’s session at all: Claude works without it, with no permission prompt or error. This example creates a read-only analysis agent that can examine code but can’t modify files or run commands.

Common tool combinations

Scale up with dynamic workflows

Subagents work well for a few delegated tasks per turn. For runs that coordinate dozens to hundreds of agents, use the Workflow tool, which moves the orchestration into a script the runtime executes outside the conversation context. See dynamic workflows for how workflows differ from turn-by-turn subagent delegation. The Workflow tool is available in the TypeScript Agent SDK v0.3.149 and later. Include Workflow in allowedTools to auto-approve workflow runs. The tool input and output schemas are listed in the TypeScript reference.

Troubleshooting

Claude not delegating to subagents

If Claude completes tasks directly instead of delegating to your subagent:
  • Check Agent invocations are approved: include Agent in allowedTools to auto-approve subagent calls. Without it, Agent invocations fall through to your canUseTool callback or, in dontAsk mode, are denied
  • Use explicit prompting: mention the subagent by name in your prompt, for example “Use the code-reviewer agent to…”
  • Write a clear description: explain exactly when to use the subagent so Claude can match tasks appropriately

Filesystem-based agents not loading

Claude Code watches ~/.claude/agents/ and .claude/agents/ and picks up a new or edited agent file within a few seconds, with no restart needed. If a definition never appears, work through these causes:
  • New agents directory: the watcher covers only directories that existed when the session started, so the first file in a new directory needs a session restart. This is the most common cause.
  • Invalid frontmatter or a duplicate name: check the file’s YAML, and whether an existing agent already uses the name.
  • --disable-slash-commands: sessions started with this flag don’t watch these directories and always need a restart to load new files.
  • A programmatic agent with the same name: agents passed to query() override a filesystem agent with the same name.
For the file format, see how to write subagent files.

Long prompt failures on Windows

On Windows, subagents with very long prompts may fail due to the command line length limit of 8191 characters. Keep prompts concise or use filesystem-based agents for complex instructions.
  • Claude Code subagents: comprehensive subagent documentation including filesystem-based definitions
  • Dynamic workflows: orchestrate many subagents from a script for jobs too large for one conversation
  • SDK overview: getting started with the Claude Agent SDK