---
title: "Claude Code Subagents: How to Define Them and When to Delegate"
excerpt: "Claude Code subagents are Markdown files with YAML frontmatter that run delegated tasks in their own context windows. This guide covers the file format, the built-in agent types, how delegation gets triggered, and three working recipes including a browser verification subagent."
metaDescription: "Claude Code subagents are Markdown files in .claude/agents/ with YAML frontmatter. How to define them, when Claude delegates, and how to verify their work."
publishedAt: 2026-08-03
author: Feng
categories:
 - Guides
 - Engineering
tags:
 - claude-code-subagents
 - claude-code
 - subagents
 - claude-agents
 - agent-delegation
 - context-engineering
 - claude-code-hooks
 - claude-code-skills
 - mcp
metaTitle: "Claude Code Subagents: Define and Delegate"
featuredImage: ./cover.png
featuredImageAlt: "Shiplight blog cover, light gradient, indigo accents, diagram of a main Claude Code agent delegating tasks to three subagent context windows defined by markdown files"
---

Claude Code subagents are specialized assistants defined as Markdown files with YAML frontmatter, stored in `.claude/agents/` for a project or `~/.claude/agents/` for your whole machine. Each subagent runs in its own context window with its own system prompt, its own tool list, and its own permissions. The main agent hands it a task, the subagent does the work in isolation, and only a summary comes back.

That last sentence is the whole reason subagents exist. A coding agent's context window is a budget, and side tasks like searching a codebase, running a test suite, or fetching documentation spend that budget on output you will never look at again. Delegation moves the spend into a disposable context. If you want the general argument for when splitting context helps, and when it does not, we cover that in [what is a subagent](/blog/subagent). And if what you actually want is several agents working in parallel on separate tasks with their own sessions, that is a different feature, covered in [Claude Code agent teams](/blog/claude-code-agent-teams).

This page is about the mechanics in Claude Code specifically: the exact file format and frontmatter fields, the built-in agent types, how the main agent decides to delegate, foreground versus background execution, preloading skills, and validating delegated work with hooks. The organizing principle throughout: a subagent definition is three decisions written into one file. What the worker knows (the system prompt and preloaded skills), what it can touch (tools and permissions), and when it gets used (the description the main agent reads). Get those three right and delegation mostly takes care of itself.

## The built-in subagents

Claude Code ships with subagents you get without writing anything:

- **Explore**: a fast, read-only agent for searching and analyzing code. Write and Edit are denied. It skips your CLAUDE.md files and git status to stay cheap, and the main agent specifies a thoroughness level (quick, medium, or very thorough) when invoking it.
- **Plan**: the research agent behind [plan mode](/blog/claude-code-plan-mode). Also read-only; it gathers context so exploration output stays out of the main conversation while a plan is being formed.
- **general-purpose**: inherits the main conversation's model and gets the full subagent tool set. Used when a task needs both exploration and modification, or multiple dependent steps.

Explore and Plan are one-shot: they return no agent ID, so they cannot be resumed. Everything else can be continued later, which matters for review workflows where you want to send follow-up questions to the same worker with its context intact.

## Defining a custom subagent

A subagent file is YAML frontmatter plus a Markdown body. The body becomes the subagent's system prompt; the subagent does not receive the full Claude Code system prompt, just this text plus basic environment details.

```markdown
---
name: code-reviewer
description: Reviews code for quality and security. Use proactively after writing or modifying code.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You are a senior code reviewer. Run git diff to see recent changes,
focus on modified files, and report issues by priority: critical,
warning, suggestion. Include a concrete fix for each issue.
```

Where the file lives determines who gets it. Higher rows win name conflicts:

| Location | Scope |
|---|---|
| Managed settings | Organization-wide, deployed by admins |
| `--agents` CLI flag (JSON) | Current session only, nothing on disk |
| `.claude/agents/` | Current project; check into version control |
| `~/.claude/agents/` | All your projects |
| A plugin's `agents/` directory | Wherever the plugin is enabled |

Only `name` and `description` are required. The fields worth knowing:

- `tools` is an allowlist; omit it to inherit everything available to subagents. `disallowedTools` is the inverse: `disallowedTools: Write, Edit` keeps everything except file writes. Both accept MCP patterns like `mcp__github` to grant or strip an entire server.
- `model` takes `sonnet`, `opus`, `haiku`, a full model ID, or `inherit` (the default). Routing high-volume, low-judgment work to a cheaper model is one of the main levers subagents give you.
- `permissionMode` sets how prompts behave inside the subagent (`default`, `acceptEdits`, `plan`, and others). A parent session's broader permission mode overrides this.
- `mcpServers` attaches MCP servers, either by name from your existing config or as an inline definition scoped to this subagent only. Inline is the interesting case: the subagent gets the tools, and the server's tool descriptions never consume context in the main conversation.
- `hooks` defines lifecycle hooks that run only while this subagent is active.
- `memory` (`user`, `project`, or `local`) gives the subagent a persistent directory that survives across sessions, so a reviewer can accumulate knowledge of your codebase's recurring issues.
- `isolation: worktree` runs the subagent in a temporary git worktree, so its edits land in an isolated copy of the repository.

Claude Code watches the agent directories, so edits take effect within seconds without a restart. The one exception: creating a scope's first agent file in a brand-new `agents/` directory requires a restart, because the watcher only covers directories that existed at session start.

## How the main agent decides to delegate

Delegation is driven almost entirely by the `description` field. The main agent reads every registered subagent's description and matches tasks against it. This makes the description a routing rule, not documentation. "Reviews code" is weak; "Reviews code for quality and security. Use proactively after writing or modifying code" tells the main agent both what the subagent does and when to reach for it unprompted. The phrase "use proactively" is the documented idiom for encouraging automatic delegation.

When automatic routing is not enough, three escalating options exist. Name the subagent in your prompt ("use the code-reviewer subagent on my recent changes") and Claude usually complies. @-mention it (`@agent-code-reviewer`) to guarantee that specific subagent runs. Or pass `claude --agent code-reviewer` to run the entire session as that agent, replacing the default system prompt with its definition.

## Foreground vs background

Subagents run in the background by default: the main conversation keeps working while they execute, and results arrive as a completion notification in a later turn. The main agent runs a subagent in the foreground when it needs the result before continuing. You can steer this yourself by asking for foreground or background explicitly, or by pressing Ctrl+B to background a running task.

Two things change in the background. Permission prompts surface in your main session, named with the subagent asking, so nothing silently stalls. And background subagents get a smaller built-in tool set than foreground ones, so the same definition can resolve to different tools depending on where it runs. Setting `background: true` in frontmatter forces a subagent to always run in the background.

## Preloading skills

By default, a subagent starts blank: no conversation history, no skills already invoked, none of the files the main agent has read. The `skills` frontmatter field fixes the knowledge gap by injecting full skill content, not just descriptions, into the subagent's context at startup:

```yaml
---
name: api-developer
description: Implement API endpoints following team conventions
skills:
  - api-conventions
  - error-handling-patterns
---
```

This is the difference between a subagent that has to rediscover your conventions every run and one that starts already knowing them. If you have not built skills yet, [creating a Claude Code skill](/blog/create-claude-code-skill) covers the format; the field pairs naturally with the skills-in-subagents patterns in [Claude Code skills](/blog/claude-code-skills).

## Validating delegated work with SubagentStop hooks

Delegation has a trust problem: the subagent reports "done," and the main agent takes its word for it. [Hooks](/blog/claude-code-hooks) give you a deterministic check instead. The `SubagentStop` event fires when a subagent completes, and it supports matchers on the agent's name, so you can run a validation script only for specific agent types:

```json
{
  "hooks": {
    "SubagentStop": [
      {
        "matcher": "db-agent",
        "hooks": [
          { "type": "command", "command": "./scripts/verify-db-work.sh" }
        ]
      }
    ]
  }
}
```

Inside a subagent's own frontmatter, `PreToolUse` hooks act as guardrails during execution: a script that reads the tool input as JSON and exits with code 2 blocks the call and feeds its stderr message back to the subagent. The official docs use this to build a database agent that has Bash access but can only run SELECT queries.

## Subagent vs skill vs hook

These three features get conflated because all of them customize Claude Code with files in `.claude/`. They solve different problems:

| | Subagent | Skill | Hook |
|---|---|---|---|
| What it is | A worker with its own context window | Instructions loaded into a conversation | A script triggered by lifecycle events |
| Runs where | Isolated context, summary returns | The invoking agent's context | Outside the model entirely |
| Best for | Verbose side tasks, tool restriction, cheaper models | Reusable procedures and domain knowledge | Deterministic enforcement: lint, block, validate |
| Failure mode if misused | Lost context, re-explaining the task | Context spent on unused instructions | Brittle scripts blocking legitimate work |
| Reach for it when | Output would flood the main context | The knowledge must shape work in-context | The rule must hold 100% of the time |

Rule of thumb: knowledge goes in a skill, isolation goes in a subagent, enforcement goes in a hook. The three compose: a subagent can preload skills and carry its own hooks.

## Three practical recipes

### A code reviewer that cannot touch code

The reviewer above, plus `memory: project`, gives you a read-only critic that accumulates knowledge of your codebase's recurring issues in `.claude/agent-memory/code-reviewer/`, shareable through version control. The tool list excludes Edit and Write on purpose: a reviewer that can rewrite code will, given enough runs, quietly fix things instead of reporting them.

### A cheap explorer

Explore inherits your session's model. Define a project agent named `Explore` with `model: haiku` and it overrides the built-in, pinning exploration to a lower-cost model while your main conversation stays on something stronger. High-volume file searching is exactly the work where a fast model is good enough.

### A verification subagent with browser access

Agent-written code needs checking in a real browser, and browser output (screenshots, DOM snapshots, console logs) is the definition of context you do not want in your main conversation. A verification subagent with an inline MCP server keeps it contained:

```markdown
---
name: ui-verifier
description: Verifies UI changes in a real browser. Use proactively after frontend edits.
mcpServers:
  - playwright:
      type: stdio
      command: npx
      args: ["-y", "@playwright/mcp@latest"]
---

Navigate to the changed pages, exercise the modified flows, and report
what actually renders versus what was intended. Screenshot evidence
for every claim.
```

Because the server is defined inline, its tool descriptions cost nothing in the main conversation. [Playwright MCP](/blog/playwright-mcp) gives the subagent raw browser control; Shiplight (our product) installs the same way, as a browser MCP server plus skills, but the verifications it produces become intent-based YAML tests in your repo that transpile to standard Playwright, so a check the subagent ran once becomes a regression test your CI runs forever. The broader workflow is in [Claude Code testing](/blog/claude-code-testing). Either way, pair this subagent with a `SubagentStop` hook if the verification must gate the work rather than merely inform it.

## When delegation makes things worse

Subagents are not free, and the failure modes are predictable.

**Latency.** Every subagent starts cold and spends turns gathering context you already have. For a quick, targeted change, delegating is strictly slower than doing it in the main conversation.

**Lost context.** A subagent does not see your conversation history. If the task needs judgment calls you made twenty messages ago, the delegation prompt has to carry them, and it usually will not carry all of them. Tasks with heavy shared context across phases (plan, implement, test) belong in the main conversation.

**Over-orchestration.** A session that spawns ten subagents whose detailed reports all return to the main conversation has not saved context; it has laundered it. The docs warn about exactly this. If you find yourself building elaborate delegation chains, you likely want [agent teams](/blog/claude-code-agent-teams) with genuinely independent sessions, or just a simpler workflow.

The test worth applying before any delegation: will the intermediate output matter later? If yes, keep it in the main conversation. If no, that is what subagents are for.

## Frequently Asked Questions

### What are Claude Code subagents?

Subagents are specialized assistants defined as Markdown files with YAML frontmatter that handle delegated tasks in their own context windows. Each has its own system prompt, tool list, model, and permissions. The main agent delegates a task, the subagent works in isolation, and only its summary returns to the main conversation.

### Where do subagent files live?

Project subagents go in `.claude/agents/` and personal ones in `~/.claude/agents/`, with project definitions winning name conflicts. Both directories are scanned recursively, so you can organize files into subfolders. Managed settings, the `--agents` CLI flag, and plugins are additional sources.

### Which frontmatter fields are required?

Only `name` and `description`. Everything else is optional: `tools`, `disallowedTools`, `model`, `permissionMode`, `skills`, `mcpServers`, `hooks`, `memory`, `background`, `maxTurns`, and `isolation` among others. The Markdown body below the frontmatter becomes the subagent's system prompt.

### How does Claude decide when to use a subagent?

It matches your request against each subagent's `description` field. Descriptions that state both the job and the trigger, including the phrase "use proactively," get delegated to without being asked. To force a specific subagent, @-mention it or name it directly in your prompt.

### Do subagents see my conversation history?

No. A subagent starts fresh with its own system prompt, the delegation message, your CLAUDE.md files, and any preloaded skills. Built-in Explore and Plan agents skip CLAUDE.md too. The exception is a fork, which inherits the full conversation and is spawned with `/subtask`.

### Can a subagent run tests in a real browser?

Yes, by attaching a browser MCP server in its `mcpServers` frontmatter, either referencing an existing server or defining one inline so it stays out of the main conversation. Playwright MCP and Shiplight both work this way; Shiplight additionally turns the verifications into YAML tests kept in your repo.

## Related Reading

- [What is a subagent](/blog/subagent), the concept behind context isolation and when splitting work actually helps.
- [Claude Code agent teams](/blog/claude-code-agent-teams), for running multiple parallel sessions rather than delegating within one.
- [Claude Code hooks](/blog/claude-code-hooks), the full guide to the hook events used here for validating subagent work.
- [Claude Code skills](/blog/claude-code-skills), how skills work and why preloading them changes subagent quality.
- [Claude Code testing](/blog/claude-code-testing), the verification workflow a browser subagent plugs into.
- [Playwright MCP](/blog/playwright-mcp), the browser MCP server used in the verification recipe.

External references: [Claude Code subagents documentation](https://code.claude.com/docs/en/sub-agents), [Claude Code hooks documentation](https://code.claude.com/docs/en/hooks).
