A subagent is a separate context window with its own tool access, spawned by the main session rather than run inline. When that isolation is worth having, how to define a custom subagent type in .claude/agents/*.md with its own tools and model, and the failure mode of spawning one for work that never needed isolating in the first place.
what a subagent actually is
A Claude Code subagent is a second context window. The main session spawns it through the Task tool, hands it a prompt describing what to do, and waits for a single result to come back. The subagent has its own conversation history, its own system prompt, and its own list of tools it is allowed to call. None of what it reads or does mid-task is visible to the main thread. Only the final report is.
That last property is the entire point. A subagent is not a way to run Claude Code twice as fast. It is a way to spend a large amount of context doing something and hand back only the small amount of it that mattered.
Think of it as calling a function that happens to think out loud while it runs, except the thinking-out-loud part is invisible to the caller and does not count against the caller's own context budget.
when to reach for one instead of doing it in the main thread
The decision is almost entirely about context, not speed. Ask whether the task would leave behind a large amount of material you do not need once it is done.
- Wide exploration, narrow answer. Searching a large codebase for every place a deprecated function is called, then summarizing the pattern. You want the pattern, not forty file reads sitting in your main context afterward.
- A self-contained sub-problem with its own tool needs. Running a test suite, parsing its output, and reporting pass or fail with the relevant failures. The main session does not need the full test log, it needs the verdict.
- Work that benefits from a different, narrower system prompt. A subagent defined specifically for code review can be told to be terse and skeptical, without that tone bleeding into the main session's own behavior.
- Anything you would otherwise open a second terminal for. If the instinct is to spin up a separate Claude Code session to go check something and report back, that is exactly the shape a subagent fills without leaving your current session.
defining a custom subagent type
Custom subagents live as Markdown files under .claude/agents/ in a project, or under ~/.claude/agents/ for ones you want available everywhere. Each file is one subagent type: YAML frontmatter describing it, followed by its system prompt as plain Markdown body text.
---
name: test-runner
description: Runs the project's test suite and reports failures concisely. Use after a code change that touches logic, before considering it done.
tools: Bash, Read, Grep
model: sonnet
---
You run tests and report results. Run the project's test command,
read any failure output, and summarize which tests failed and why
in three sentences or fewer per failure. Do not attempt to fix
failures yourself. Do not paste full stack traces; quote only the
line that identifies the actual assertion or error.That file is the whole definition. There is no separate registration step. Claude Code scans the agents directory, parses the frontmatter, and the subagent becomes available for the main session to invoke.
the frontmatter fields that matter
description does more work than it looks like it does. It is not documentation for a human reading the file later, it is the text Claude Code matches against the task in front of it when deciding whether this subagent is the right one to spawn. A vague description like "helps with code" will rarely get picked over a more specific one for a task that could plausibly match either.
Restricting tools is a real safety boundary, not decoration
A subagent whose tools list omits write access cannot write files, full stop, regardless of what its prompt says or what the task asks for. This is worth using deliberately: a subagent whose job is to investigate and report should usually not also be able to edit, because giving it edit access removes the one guarantee that made it safe to point at something you have not reviewed yet.
how invocation actually works
There are two paths. The main session can pick a subagent automatically, matching the task at hand against every defined subagent's description, or you can name one explicitly in your own instruction to Claude Code.
Use the test-runner subagent to check whether that refactor broke anything.Either way, what happens underneath is the same. The main session's Task tool spawns a fresh context, seeds it with the subagent's system prompt and the specific instruction for this invocation, lets it run with only its allowed tools, and receives back whatever it returns as a single tool result. That result becomes one message in the main thread's context. The subagent's own intermediate tool calls and reasoning do not.
This is why a subagent's output should be written as if it will be read once, cold, by someone with none of the context the subagent had while working. A subagent that returns "done, see above" has produced nothing useful, because there is no above from the caller's side.
the failure mode: spawning a subagent that did not need isolation
The mirror image of the reasoning in the second section is the mistake worth naming explicitly: reaching for a subagent when nothing about the task benefits from a separate context.
The tell is usually that the task is small, or that you actually want to watch it happen, or that it depends on turns of back and forth that a single fire-and-return call cannot carry. A subagent invocation is a round trip: spin up a context, run the prompt, collapse the result back to one message. If the task was going to cost you three tool calls and a short answer anyway, that round trip is pure overhead, plus you have introduced a report you now have to trust instead of output you watched get produced.
- Small, fast tasks. Reading one file and answering a question about it does not need isolation. It costs less context to just do it than to write and dispatch a subagent prompt describing how to do it.
- Anything interactive. If the task might need a follow-up question or a clarification partway through, a subagent cannot ask you one. It runs to completion on the instruction it was given and returns, so ambiguity gets resolved by guessing rather than asking.
- Work where you need to see the steps, not just the outcome. Debugging is the common case. If you need to know which of five things failed and in what order, hiding that behind a subagent's summary removes the exact information you were trying to get.
- Tasks that mutate shared state the main session is tracking. A subagent that edits files the main session also has opinions about can leave the main thread out of sync with what actually happened on disk, since it only sees the report, not the diff being produced.
The underlying rule is simple even though the judgment call is not: a subagent earns its overhead only when the thing you are protecting from context pollution is bigger than the overhead itself. When in doubt, do it in the main thread first. Reach for a subagent once the pattern of "this keeps burning a lot of context for one small answer" repeats.
common questions
What is a Claude Code subagent? A separate context window, spawned by the main session through the Task tool, with its own system prompt and its own restricted set of tools. It runs independently and returns a single result. It does not share the main conversation's history, and the main thread does not see its intermediate steps.
When should I use a subagent instead of doing the work in the main thread? When the work would otherwise pollute the main context with material you do not need afterward: wide exploration with a narrow answer, a self-contained sub-problem, or work that benefits from a different system prompt. If you need the intermediate steps yourself, keep it in the main thread.
How do you define a custom subagent? A Markdown file under .claude/agents/ with YAML frontmatter for name, description, and optionally tools and model, followed by the system prompt as the file body. Claude Code discovers it automatically and invokes it by name or by matching the description against the task.
What is the main failure mode? Spawning a subagent for a task that never needed context isolation: something small, something interactive, or something where you actually needed to see the steps rather than a summary of them. The round trip costs more than the isolation is worth.