Claude Code Subagents: How They Work and How to Build Your Own (2026)
My main Claude Code session used to die the same way. I would ask it to find every place a function was used, it would read thirty files, and by the time it answered, half the context window was full of code I would never look at again. The answer was fine. The session after it was not.
Subagents fix that. They are the feature I reach for when a side task would bury the main conversation in output. This guide covers what they are, what ships built in, how to write your own, how Claude decides to use them, and where they cost you more than they save. I checked the details against the official subagents docs on code.claude.com, and where behavior depends on a Claude Code version, I say so.
What Are Claude Code Subagents?
A Claude Code subagent is a specialized assistant that Claude delegates a task to. It runs in its own context window with its own system prompt, its own tool access and independent permissions, then returns a result to the main conversation. Its requests count toward the same usage limits as your main session.
That is the whole idea. The main session stays clean, the subagent does the messy work, and you get a summary back.
The docs list five reasons to use them:
- Keep exploration and implementation out of the main conversation.
- Enforce constraints by limiting which tools a subagent can use.
- Reuse configurations across projects with user-level subagents.
- Specialize behavior with a focused system prompt.
- Control cost by routing work to faster, cheaper models such as Haiku.
One scope note. Subagents work within a single session. If you want parallel independent sessions, or separate sessions that message each other, that is a different feature (background agents, cross-session messaging, agent teams). I am only covering subagents here.
How Claude Code Subagents Work
Each subagent is defined by four things: a system prompt, a set of tools, a model, and permissions. A non-fork subagent starts with a fresh context window that contains:
- its own system prompt plus basic environment details (not the full Claude Code system prompt)
- the delegation message Claude wrote for it
- your CLAUDE.md files (except for the Explore and Plan built-ins, or agents with
omitClaudeMdset) - a git status snapshot (again, except Explore and Plan)
- any skills you preloaded through the
skillsfield
It does not see your conversation history, skills you already invoked, or files the main session already read. That last part is the one that bites people, and I come back to it in the pitfalls section.
Two more behaviors worth knowing:
- Model. Claude resolves the model in this order: the
modelparameter Claude passes for that invocation, then themodelin the subagent's frontmatter (inheritmeans the main model), then theCLAUDE_CODE_SUBAGENT_MODELenvironment variable, then the main conversation's model. - Tools. A subagent inherits the available tools unless you restrict them. Some tools are always removed for subagents, including
AskUserQuestionand the plan-mode tools, so a subagent cannot stop and ask you a question mid-run.
Built-in vs Custom Subagents
Claude Code ships with several subagents. Custom ones are files you write.
| Built-in agent | Tools | What it is for |
|---|---|---|
| Explore | Read-only (Write and Edit denied) | Fast codebase search. Claude picks a thoroughness level: quick, medium or very thorough. |
| Plan | Read-only (Write and Edit denied) | Research during plan mode. |
| general-purpose | Every tool available to subagents | Complex multi-step work that needs both exploration and action. |
| claude | Every tool available to subagents | Catch-all, and the default agent for dispatched background sessions. |
| statusline-setup | n/a | Runs when you use /statusline (Sonnet). |
| claude-code-guide | n/a | Answers questions about Claude Code features (Haiku). |
You will see Explore most often. It is what Claude uses when it needs to search a codebase without cluttering your session.
You can turn a built-in off with Agent(Explore) in permissions.deny. A custom subagent named Explore overrides the built-in.
Custom subagents are the ones worth writing. You define one when you keep spawning the same kind of worker with the same instructions: a reviewer with your standards, a test runner that only reports failures, a researcher that cannot write files.
How to Create a Custom Subagent
A subagent is a Markdown file. The frontmatter configures it, and the body is its system prompt.
The /agents command
Here is something I got wrong before checking the docs. I assumed /agents opens a creation wizard. On current versions it does not: running /agents prints a reminder to ask Claude or edit the agent directories directly. The interactive wizard (a Running tab and a Library tab) existed on Claude Code v2.1.197 and earlier.
So the current creation flow is plain. Describe what you want and where to save it, and Claude writes the file:
Create a personal code-improver subagent in ~/.claude/agents/ that scans
files and suggests improvements for readability, performance, and best
practices. Make it read-only and have it use Sonnet.That is the documented quickstart. Or you skip Claude and write the file yourself, which is what I do once I know what I want.
Where subagent files live
When two subagents share a name, the higher-priority location wins.
| Location | Scope | Priority |
|---|---|---|
| Managed settings | Organization-wide | 1 (highest) |
--agents CLI flag | Current session | 2 |
.claude/agents/ | Current project | 3 |
~/.claude/agents/ | All your projects | 4 |
A plugin's agents/ directory | Where the plugin is enabled | 5 (lowest) |
Project subagents are discovered by walking up from the working directory to the repository root, and both agent directories are scanned recursively. Identity comes only from the name field, not the file path, so keep names unique. Claude Code watches these directories and picks up edits within seconds. The one exception: creating the first agent file in a brand-new agents directory needs a restart.
Check project subagents into version control. That is how your team shares them.
Frontmatter fields
Only name and description are required. Field names are case-sensitive camelCase, and unknown fields are ignored silently, so a typo will not throw an error. It just does nothing.
| Field | Required | What it does |
|---|---|---|
name | Yes | Unique identifier, at most 256 characters. No :, and it cannot start with -. |
description | Yes | When Claude should delegate to this subagent. |
tools | No | Allowlist, comma-separated or a YAML list. Inherits all available tools if omitted. |
disallowedTools | No | Denylist. Applied before tools. |
model | No | sonnet, opus, haiku, fable, a full model ID, or inherit. |
permissionMode | No | default, acceptEdits, auto, dontAsk, bypassPermissions, plan, or manual. |
maxTurns | No | Maximum agentic turns. At the limit, output returns marked as partial. |
skills | No | Skills whose full content is preloaded at startup. |
mcpServers | No | A configured server name, or an inline server definition. |
hooks | No | Lifecycle hooks scoped to this subagent. |
memory | No | user, project or local. Gives the agent a persistent memory directory. |
isolation | No | worktree runs it in a temporary git worktree. |
The docs list more (effort, color, background, omitClaudeMd and others). Some fields are ignored for plugin subagents (permissionMode, mcpServers, hooks).
Two things from that table I use constantly. First, description does double duty: it is the routing rule Claude reads to decide when to delegate, so it is the most important line in the file. Second, tools is how you make a reviewer that physically cannot edit code. A prompt that says "do not edit files" is a request. A tool allowlist without Edit and Write is a wall.
Example subagent files
These three are my own examples, built on the file format above. They are starting points, not official templates. Save them in .claude/agents/ and adjust.
Example: code reviewer (read-only).
---
name: code-reviewer
description: Reviews recent changes for bugs, security issues and maintainability. Use proactively after code is written or modified.
tools: Read, Grep, Glob, Bash
model: inherit
---
You are a senior code reviewer.
When invoked:
1. Run git diff to see what changed.
2. Read the modified files.
3. Review the changes before suggesting anything else.
Report findings in three groups: critical (must fix), warnings (should fix),
suggestions (optional). For each one, name the file and line and show how to fix it.
Do not edit files.Bash stays in the allowlist because the reviewer needs git diff. If that bothers you, you can add a PreToolUse hook to restrict what Bash can run, which is the pattern the docs use for their read-only database example.
Example: test runner.
---
name: test-runner
description: Runs the test suite and reports failures. Use when tests need to be run or a change needs verifying.
tools: Read, Grep, Glob, Bash
model: haiku
maxTurns: 15
---
You run tests and report results. Do not fix anything.
1. Run the project's test command.
2. If everything passes, say so in one line.
3. If tests fail, list each failing test with the file, the assertion that
failed and the relevant error lines. Skip passing output.
Keep the report short. The caller only needs what is broken.This is the cheapest and most useful subagent I can think of. Test output is long, noisy and almost never needed in full. A cheap model plus maxTurns keeps it fast and bounded.
Example: researcher.
---
name: researcher
description: Investigates how a part of the codebase works and reports back. Use for questions like where something is defined, how a flow works, or what depends on what.
tools: Read, Grep, Glob
model: sonnet
---
You investigate code and answer questions about it. You cannot modify anything.
Answer in this shape:
- Short answer first, two or three sentences.
- Then the evidence: file paths with line numbers.
- Then anything you could not confirm.
Never guess. If you could not find something, say that.The "anything you could not confirm" line matters. A subagent returns a summary, and a confident summary built on a missed file is worse than an honest gap.
How Claude Delegates to Subagents
There are four ways a subagent gets invoked.
- Automatic. Claude delegates based on your request, each subagent's
description, and current context. Phrases like "use proactively" in the description encourage it. - Natural language. You name it: "Use the test-runner subagent to fix the failing tests."
- @-mention. Type
@"code-reviewer (agent)"or the form@agent-<name>. Your full message still goes to Claude, which writes the subagent's task prompt. - Whole session.
claude --agent code-reviewerruns the entire session as that agent, replacing the default system prompt. Anagentkey in.claude/settings.jsonsets a project default.
Automatic delegation depends on descriptions, and descriptions cost context. When the combined descriptions of your custom subagents pass 15,000 tokens, Claude Code shows a warning at startup (it still loads them all). Keep descriptions short and specific, and move detail into the system prompt, which only loads when that subagent runs.
Foreground and background
Foreground subagents block the main conversation, and permission prompts pass straight through. Background subagents run concurrently, and their permission prompts surface in your main session labeled with the subagent's name. You can approve, or press Esc to deny that one call.
Per the docs, subagents spawned from the main conversation start in the background by default. Press Ctrl+B to push a running one to the background.
Running subagents in parallel
Parallel research is the easiest win. Ask Claude to investigate several areas with separate subagents, and each explores independently while Claude synthesizes the results.
Research the auth, billing and notification modules in parallel using
separate subagents, then summarize how they depend on each other.The limits, from the docs:
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTScaps concurrent subagents (default 20). Spawning past it fails withConcurrent subagent limit reached. There is no cap on the total per session.- A subagent can spawn subagents up to three layers below the main conversation.
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHchanges that, and1disables nesting. To stop one subagent from spawning, leaveAgentout of its tools.
Parallel subagents all read the same repo, so parallel reading is safe. Parallel writing is where it goes wrong, because two agents editing the same files will collide. For that, set isolation: worktree so a subagent works in a temporary git worktree, and see my git worktree guide for the underlying mechanics. Whether the work should be split across agents at all is a separate question, which I cover in multi-agent vs single-agent architecture.
Resuming and forks
Each invocation creates a new instance. To continue earlier work, resume it by agent ID or name with SendMessage. A fork is the related option: it inherits the entire conversation and the main session's system prompt, tools and model, and only its final result comes back. Start one with /subtask <task>. It reuses the parent's prompt cache, so it is cheaper than a fresh subagent when the task needs the same context.
Subagents vs Skills vs Hooks vs MCP
These four get confused constantly, because all of them extend Claude Code. They answer different questions.
| Subagent | Skill | Hook | MCP server | |
|---|---|---|---|---|
| What it is | A separate model run with its own context | Instructions Claude reads for a class of task | A command Claude Code runs on a lifecycle event | Tools that reach external systems |
| Runs in | Its own context window | The current conversation | Outside the model | Its own process, called by the model |
| Who decides | Claude (or you, by name) | Claude (or you, with a slash command) | Claude Code, not the model | Claude |
| Best for | Noisy side tasks and parallel research | Repeatable procedures | Rules that must always run | Databases, tickets, APIs |
The one-line version: a skill changes how Claude does something, a subagent changes where it does it, a hook guarantees that something happens, and an MCP server changes what Claude can reach. I wrote up the skill side, including the SKILL.md format, in how to write Claude Code skills, and the install side in the plugin marketplace post. Hooks get their own breakdown in the Claude Code hooks guide.
They also combine. A subagent can preload skills through its skills field, carry its own hooks in frontmatter, and get its own MCP servers through mcpServers. The docs' read-only database agent is the best example: a subagent with only Bash, plus a PreToolUse hook that blocks write queries. The prompt tells it to refuse writes, and the hook is the backstop in case it tries anyway.
My rule for picking: if the problem is "this output is too big for my main context," it is a subagent. If the problem is "I keep re-explaining the same procedure," it is a skill. If the problem is "this must happen every time," it is a hook.
Subagent Costs and Pitfalls
Subagents are not free, and they are not always better than just doing the work in the main session.
They use tokens. Each subagent has its own context and its own usage, and the docs say plainly that each one consumes its own tokens while its returned results consume space in your main context. Five parallel subagents is five contexts being filled. Route cheap work to cheap models: the test runner above does not need Opus.
They start cold. A subagent does not see your conversation. Everything it needs has to be in the delegation message Claude writes, or in its system prompt, or in CLAUDE.md. If you spent twenty minutes explaining a bug to the main session and then delegate "fix it," the subagent knows none of that. Say it in the task, or use a fork when the task needs full context.
They are the wrong tool for back-and-forth. The docs recommend the main conversation for iterative work, shared multi-phase context, quick targeted changes, and anything where latency matters. A subagent adds startup overhead. A one-line fix does not need one.
Silent typos. Unknown frontmatter fields are ignored, and files with an invalid name, no description or broken YAML are skipped (the reason goes to the debug log). If a subagent is not showing up, check those first.
Frequently Asked
What is a Claude Code subagent? A specialized assistant that Claude delegates a task to. It runs in its own context window with its own system prompt, tool access and permissions, and returns a result to your main conversation.
How do I create a subagent in Claude Code? Ask Claude to create one and say where to save it, or write a Markdown file in .claude/agents/ (this project) or ~/.claude/agents/ (all projects). It needs name and description frontmatter, and the body is the system prompt.
Does the /agents command still create subagents? Not on current versions. The docs say /agents now prints a reminder to ask Claude or edit the agent directories directly. The interactive wizard existed on v2.1.197 and earlier.
What are the built-in Claude Code subagents? Explore, Plan, general-purpose, claude, statusline-setup and claude-code-guide. Explore and Plan are read-only, and Claude uses Explore for fast codebase searches.
Can Claude Code subagents run in parallel? Yes. Ask Claude to investigate separate areas with separate subagents. The default cap is 20 concurrent subagents, set by CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS.
Do subagents see my conversation? No. A non-fork subagent starts with its system prompt, the delegation message, CLAUDE.md files, a git status snapshot and any preloaded skills. It does not see your history or files the main session already read.
What is the difference between a subagent and a skill? A skill is instructions Claude reads in the current conversation. A subagent is a separate run with its own context that returns a summary. Skills shape how Claude works, and subagents keep noisy work out of your main context.
Sources: Claude Code documentation, "Create custom subagents" (code.claude.com/docs/en/sub-agents), checked 2026-10-23. Version-specific behavior noted in the text follows that page.