To create a subagent in Claude Code, save a Markdown file in .claude/agents/ (or ~/.claude/agents/ for every project) with YAML frontmatter holding name and description, and write the system prompt in the body. Restrict tools and pick a cheaper model when you can. Use a subagent for self-contained work that produces lots of output, like running tests or reading logs: it runs in its own context and only the summary returns to the main conversation.
This guide shows the file for a test-running subagent, where to save it, how to validate its YAML before opening a session, and the three ways to call it. At the end, a table of when to delegate and when not to. Everything follows the official subagents docs, and the file and validation were run on Claude Code 2.1.300.
What is a subagent in Claude Code?
It is a separate assistant that runs inside your session with its own context window, its own system prompt and its own permissions. It does not see the main conversation's history: it gets only the task message Claude writes when delegating, does the work and returns a summary.
Claude Code ships with a few built in. Explore and Plan are read-only (Write and Edit denied) and exist to search and understand code. general-purpose reads and edits. Yours sit next to these.
How do you create a subagent?
A subagent is a Markdown file with YAML frontmatter. The frontmatter configures it, the body becomes the system prompt. Create .claude/agents/test-runner.md at the project root:
---
name: test-runner
description: Runs the test suite and returns only the failures. Use proactively after editing code.
tools: Read, Grep, Glob, Bash
model: haiku
---
You run tests and summarize the result.
When invoked:
1. Find the project's test command (package.json, pyproject.toml or Makefile).
2. Run the whole suite once.
3. Return only the failing tests: name, file and error message.
Do not edit files. If everything passes, reply with the total test count.Only name and description are required. The fields that matter most:
| Field | What it does | If you omit it |
|---|---|---|
name | Unique identifier. The filename does not have to match. | The file is treated as documentation and skipped, with no warning. |
description | What Claude reads to decide when to delegate. | The file is skipped and the reason goes to the debug log. |
tools | Allowlist of tools. | Inherits every tool available to subagents. |
model | haiku, sonnet, opus, a full ID or inherit. | Follows the default order, which ends at the main conversation's model. |
Keep the description short and specific. All descriptions take up context in the main conversation, and Claude Code warns at startup when their total passes 15,000 tokens. Detail goes in the body, which only loads when the subagent runs. To encourage automatic delegation, the docs suggest phrases like "use proactively".
Where do you save the subagent file?
The location decides who sees the subagent. When two share the same name, the higher priority wins:
| Where | Scope | Priority |
|---|---|---|
| Managed settings | Whole organization | 1 (highest) |
--agents flag | Current session only | 2 |
.claude/agents/ | The project (goes into git) | 3 |
~/.claude/agents/ | All your projects | 4 |
a plugin's agents/ folder | Where the plugin is enabled | 5 (lowest) |
To try one without creating a file, pass the subagent as JSON. It exists only for that session:
claude --agents '{
"test-runner": {
"description": "Runs the tests and returns only the failures.",
"prompt": "You run tests and summarize the result. Do not edit files.",
"tools": ["Read", "Grep", "Glob", "Bash"],
"model": "haiku"
}
}'One catch: Claude Code reloads on its own when you edit a subagent file, but it only watches folders that existed when the session started. If .claude/agents/ was just created, restart the session.
How do you validate the subagent before using it?
Broken frontmatter does not raise an error in the session: the file just does not load. Run the validator against the folder. It works without logging in:
$ claude plugin validate .claude/agents
Validating components in: /home/you/project/.claude/agents
✔ Validation passedAnd with an unclosed quote in the description, the same command exits with code 1:
---
name: broken
description: "unclosed quote
---
$ claude plugin validate .claude/agents
Validating agent: .../.claude/agents/broken.md
✘ Found 1 error:
❯ frontmatter: YAML frontmatter failed to parse: YAML Parse error: Unexpected EOF. At runtime this agent does not load at all — with no frontmatter name it is treated as a co-located reference document and skipped.
✘ Validation failedThe validator does not flag a file without name, which is also skipped. Check the two required fields by eye.
How do you call a subagent?
There are three ways, from loosest to strongest:
# 1. Natural language: Claude decides whether to delegate
Use the test-runner subagent to run the tests
# 2. @-mention: guarantees this subagent runs
@"test-runner (agent)" run the auth module tests
# 3. The whole session as the subagent
claude --agent test-runnerWith the @-mention, your whole message still goes to Claude, which writes the task prompt. The mention picks which subagent runs, not the text it receives. With --agent, the subagent's system prompt replaces Claude Code's for the whole session.
When should you use a subagent, and when not?
The docs' rule: delegate what is self-contained and produces a lot of output you will not read again.
| Situation | Use |
|---|---|
| Running the test suite, processing logs, fetching docs | Subagent: the output stays in its context, only the summary comes back |
| Investigating three modules that do not depend on each other | Parallel subagents |
| Restricting tools, like a reviewer that cannot edit | Subagent with tools |
| Frequent back-and-forth, fine-tuning, a quick change | Main conversation |
| Planning, implementing and testing on shared context | Main conversation |
| A side task that needs everything said so far | A fork (/subtask), which inherits the conversation |
| A reusable prompt or workflow in the main context | A Claude Code Skill |
A subagent is not free. Its requests count toward the same usage limit as the main conversation, and a regular subagent does not reuse its prompt cache. That is why the example sets model: haiku. What it means for the bill is in how to save tokens in Claude Code.
How do you restrict what a subagent can do?
toolsis an allowlist;disallowedToolsis a denylist. With both, the denylist applies first.disallowedTools: Bash(git push *)removes Bash entirely, not just the push. To block one command and keep Bash, usepermissions.denyin settings, which applies to the main conversation and to subagents.- To stop Claude from using a subagent, deny
Agent(name). - Conditional rules (only SELECT on the database, say) go in a
PreToolUsehook in the subagent's frontmatter. The format is the same as Claude Code hooks.
{
"permissions": {
"deny": ["Agent(Explore)", "Bash(git push *)"]
}
}Two limits worth knowing: a subagent can spawn others up to three levels below the main conversation (CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH changes that), and with 20 running at once the next one fails with Concurrent subagent limit reached.
What was tested here
claude plugin validateon Claude Code 2.1.300, without login:test-runner.mdpassed and the file with an open quote failed with the message above.- Not tested: delegation in a logged-in session. The behavior described in the calling and restriction sections comes from the official docs.
Frequently asked questions
What is the difference between a subagent and a Skill in Claude Code?▼
A subagent runs in a separate context and returns only a summary. A Skill injects instructions into the main conversation, which keeps seeing everything. Use a subagent to isolate verbose work and a Skill to reuse a workflow.
Why doesn't my subagent show up?▼
Three common causes: the frontmatter does not parse (run claude plugin validate .claude/agents), name or description is missing, or the agents folder was created after the session started. In the last case, restart.
Does the subagent read CLAUDE.md?▼
Yes, custom subagents load CLAUDE.md unless the frontmatter sets omitClaudeMd: true. Explore and Plan start without it. The conversation history never reaches the subagent, only the task message.
Does the /agents command still create subagents?▼
Not in current versions. Since 2.1.198, /agents only reminds you to ask Claude or edit .claude/agents/ and ~/.claude/agents/ directly. The interactive wizard existed up to 2.1.197.
Read next
- Claude Code is a harness, the main Claude Code guide
- How to save tokens in Claude Code
- How to create a Claude Code Skill
- How to configure hooks in Claude Code
- How to configure MCP in Claude Code
Want AI agents working inside your team's workflow? Talk to Capiva.