> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 04-5 Subagents: Purpose, Format, Authoring, and How They Pair with Skills

> A subagent is an isolated context window container for sub-tasks: you assign it a model, constrain its tool permissions, optionally isolate it in a git worktree, and it returns only its conclusion to the main flow. This unit teaches you to write a working subagent from scratch and clarifies the division of responsibility between subagents and skills.

export const ArchFlow = ({nodes = [], lang = "zh"}) => {
  const t = lang === "en" ? {
    flow: "Data flow",
    hint: "Click any stage to see what it does",
    stage: "Stage"
  } : {
    flow: "資料流",
    hint: "點任一階段看它做什麼",
    stage: "階段"
  };
  const safe = Array.isArray(nodes) ? nodes : [];
  const [active, setActive] = useState(0);
  if (safe.length === 0) return null;
  const idx = Math.min(active, safe.length - 1);
  const current = safe[idx];
  const css = `
  .af-root{--af-bg:#FAF8F3;--af-surface:rgba(191,117,81,0.06);--af-surface2:rgba(0,0,0,0.025);--af-border:rgba(0,0,0,0.09);--af-text:#2b2722;--af-dim:#6f6a62;--af-faint:#8a8378;--af-rail:rgba(0,0,0,0.12);--af-accent:#bf7551;border:1px solid var(--af-border);border-radius:14px;background:var(--af-bg);color:var(--af-text);overflow:hidden;}
  .dark .af-root{--af-bg:#1b1a18;--af-surface:rgba(207,138,104,0.09);--af-surface2:rgba(255,255,255,0.03);--af-border:rgba(255,255,255,0.08);--af-text:#e7e3da;--af-dim:#a8a299;--af-faint:#8a8378;--af-rail:rgba(255,255,255,0.13);--af-accent:#cf8a68;}
  .af-head{padding:13px 18px 11px;display:flex;align-items:center;gap:9px;flex-wrap:wrap;border-bottom:1px solid var(--af-border);}
  .af-head-ic{color:var(--af-accent);flex-shrink:0;}
  .af-head-t{font-size:12px;font-weight:700;letter-spacing:.6px;color:var(--af-dim);text-transform:uppercase;}
  .af-head-h{font-size:12px;color:var(--af-faint);}
  .af-grid{display:flex;gap:0;align-items:stretch;}
  .af-list{flex:1 1 0;min-width:0;padding:12px 12px 16px;}
  .af-node{display:flex;align-items:stretch;gap:10px;width:100%;text-align:left;background:transparent;border:none;cursor:pointer;padding:0;color:inherit;font:inherit;-webkit-tap-highlight-color:transparent;}
  .af-railcol{width:22px;flex-shrink:0;display:flex;flex-direction:column;align-items:center;}
  .af-dot{width:9px;height:9px;border-radius:50%;margin-top:14px;background:var(--af-faint);opacity:.5;flex-shrink:0;transition:background .15s,box-shadow .15s,opacity .15s;}
  .af-line{width:2px;flex:1 1 0;background:var(--af-rail);min-height:10px;}
  .af-body{flex:1 1 0;min-width:0;padding:9px 12px;margin:2px 0;border-radius:9px;border:1px solid transparent;transition:background .15s,border-color .15s;}
  .af-node:hover .af-body{background:var(--af-surface2);}
  .af-node-on .af-body{background:var(--af-surface);border-color:rgba(191,117,81,.30);}
  .af-node-on .af-dot{background:var(--af-accent);opacity:1;box-shadow:0 0 0 4px rgba(191,117,81,.15);}
  .af-label{font-size:14.5px;font-weight:550;line-height:1.45;}
  .af-node-on .af-label{color:var(--af-accent);}
  .af-detail{width:300px;flex-shrink:0;border-left:1px solid var(--af-border);padding:16px 18px;background:var(--af-surface2);}
  .af-detail-k{font-size:11px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--af-accent);margin-bottom:7px;}
  .af-detail-l{font-size:16px;font-weight:600;margin-bottom:9px;line-height:1.35;}
  .af-detail-d{font-size:13.5px;line-height:1.65;color:var(--af-dim);}
  @media (max-width:640px){.af-grid{flex-direction:column;}.af-detail{width:auto;border-left:none;border-top:1px solid var(--af-border);}}
  `;
  return <div className="af-root">
      <style>{css}</style>
      <div className="af-head">
        <svg className="af-head-ic" xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect width="8" height="8" x="3" y="3" rx="2" /><path d="M7 11v4a2 2 0 0 0 2 2h4" /><rect width="8" height="8" x="13" y="13" rx="2" /></svg>
        <span className="af-head-t">{t.flow}</span>
        <span className="af-head-h">{t.hint}</span>
      </div>
      <div className="af-grid">
        <div className="af-list">
          {safe.map((n, i) => <button key={i} type="button" className={"af-node" + (i === idx ? " af-node-on" : "")} onClick={() => setActive(i)} onMouseEnter={() => setActive(i)}>
              <div className="af-railcol">
                <div className="af-dot" />
                {i < safe.length - 1 && <div className="af-line" />}
              </div>
              <div className="af-body">
                <div className="af-label">{n.label}</div>
              </div>
            </button>)}
        </div>
        <div className="af-detail">
          <div className="af-detail-k">{t.stage} {idx + 1} / {safe.length}</div>
          <div className="af-detail-l">{current.label}</div>
          <div className="af-detail-d">{current.detail}</div>
        </div>
      </div>
    </div>;
};

export const LearnerPrimer = ({items = [], lang = "zh"}) => {
  const t = lang === "en" ? {
    title: "Before this unit, be honest with yourself",
    sub: "If you can't answer these, that gap is exactly what this unit closes."
  } : {
    title: "讀這個單元前，先誠實面對",
    sub: "這幾題答不出來，正是這個單元要替你補的洞。"
  };
  const css = `
  .lp-root{--lp-bg:#FAF7F1;--lp-surface:rgba(191,117,81,0.05);--lp-border:rgba(0,0,0,0.09);--lp-edge:rgba(191,117,81,0.42);--lp-text:#2b2722;--lp-dim:#6f6a62;--lp-accent:#bf7551;border:1px solid var(--lp-border);border-left:3px solid var(--lp-edge);border-radius:13px;background:var(--lp-bg);color:var(--lp-text);overflow:hidden;margin:1.25rem 0;}
  .dark .lp-root{--lp-bg:#1b1a18;--lp-surface:rgba(207,138,104,0.07);--lp-border:rgba(255,255,255,0.08);--lp-edge:rgba(207,138,104,0.5);--lp-text:#e7e3da;--lp-dim:#a8a299;--lp-accent:#cf8a68;}
  .lp-head{display:flex;align-items:center;gap:9px;padding:13px 18px 11px;border-bottom:1px solid var(--lp-border);background:var(--lp-surface);}
  .lp-ic{color:var(--lp-accent);flex-shrink:0;}
  .lp-htx{display:flex;flex-direction:column;gap:1px;min-width:0;}
  .lp-title{font-size:14px;font-weight:650;line-height:1.3;letter-spacing:.01em;}
  .lp-sub{font-size:12px;color:var(--lp-dim);line-height:1.4;}
  .lp-list{list-style:none;margin:0;padding:10px 18px 14px;display:flex;flex-direction:column;gap:0;}
  .lp-item{display:flex;align-items:baseline;gap:11px;padding:7px 0;font-size:14px;line-height:1.6;border-top:1px solid var(--lp-border);}
  .lp-item:first-child{border-top:none;}
  .lp-mark{flex-shrink:0;color:var(--lp-accent);font-size:13px;font-weight:700;line-height:1.55;font-variant-numeric:tabular-nums;opacity:.85;}
  .lp-q{flex:1 1 0;min-width:0;color:var(--lp-text);}
  @media (max-width:620px){.lp-head{padding:12px 14px 10px;}.lp-list{padding:8px 14px 12px;}}
  `;
  return <div className="lp-root">
      <style>{css}</style>
      <div className="lp-head">
        <svg className="lp-ic" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="6" /><circle cx="12" cy="12" r="2" /></svg>
        <span className="lp-htx">
          <span className="lp-title">{t.title}</span>
          <span className="lp-sub">{t.sub}</span>
        </span>
      </div>
      <ul className="lp-list">
        {items.map((q, i) => <li className="lp-item" key={i}>
            <span className="lp-mark">{String(i + 1).padStart(2, "0")}</span>
            <span className="lp-q">{q}</span>
          </li>)}
      </ul>
    </div>;
};

<LearnerPrimer
  lang="en"
  items={[
"Subagents isolate context; the main conversation pays only for the summary.",
"Throwing an exploratory task into a subagent dilutes the main conversation's attention.",
"Using Opus for every subagent means costs compound linearly.",
"Giving a read-only task Write access defeats the purpose of isolation entirely.",
"isolation: worktree is waste on a read-only task.",
"You are using subagents as threads; they are one-shot containers.",
"Expecting automatic triggering from a vague description is expecting randomness.",
"Inheriting all tools by default means your allowlist has failed.",
]}
/>

<Info>
  **What this unit solves**

  A subagent is an isolated context window container for sub-tasks: you assign it a model, constrain its tool permissions, optionally isolate it in a git worktree, and it returns only its conclusion to the main flow. Claude Code v2.1 introduces a two-layer structure: built-in sub-agents (Explore, Plan, general-purpose invoked automatically) plus custom sub-agents (defined by Markdown frontmatter you write). This unit covers how to write a working subagent from scratch, how to choose a model and the minimum tool set, when to use `isolation: worktree` to prevent parallel conflicts, and how to clarify the division of responsibility with skills.
</Info>

## Learning objectives

* [ ] Describe the two-layer subagent structure introduced in Claude Code v2.1: built-in (Explore, Plan, general-purpose) and custom (Markdown files), and explain when each applies.
* [ ] Write a correct subagent frontmatter including `model`, `tools`, `permissionMode`, `skills`, and `isolation`, and explain the reasoning behind each field's value.
* [ ] For a given sub-task, decide which model to use, which tools to grant, whether `isolation: worktree` is needed, whether to preload `skills`, and whether `permissionMode` is appropriate.
* [ ] Explain the division between subagents and skills: a skill is a procedure; a subagent is an execution container. A skill uses `context: fork` to run a procedure inside a subagent; a subagent uses `skills:` to preload procedures into its own context.
* [ ] Correctly invoke a subagent from the main-flow prompt (via description matching or explicit `@`-mention) and retrieve the result.

***

## 1. What a subagent is

A subagent is a **sub-task execution unit with its own isolated context window, assignable model, and tool set**. The main conversation hands work to it, the subagent completes the entire task inside its own context, and returns only the conclusion to the main conversation (as of 2026-06, per the official subagents documentation \[1]).

The core problem it solves: **confine the side-effects that would flood the main conversation context into an isolated context**. Scanning 200 files for deprecated imports, running bulk grep to gather information, running a ten-minute test suite and returning a failure summary. If all that happens in the main conversation, tens of thousands of tokens get consumed by search results, and the model pays attention costs to scan over them in every subsequent turn. The subagent does all of it inside its own context and returns the summary. **The main conversation pays only once for the summary.**

Two key facts to internalize first:

* **A subagent cannot spawn another subagent** (no nesting). When parallel delegation is needed, the main conversation invokes multiple subagents in parallel, or uses an agent team (see [04-11](/en/code-agent/customization/team-vs-subagent)).
* **The subagent's system prompt is the Markdown body you write after the frontmatter**, not Claude Code's full system prompt. The quality of your instructions directly determines the subagent's behavior.

<Tip>
  **Connecting back to 01-4 context engineering**

  [01-4](/en/code-agent/foundations/context-engineering) compares the context window to RAM: cost accumulates linearly over the conversation. A subagent is "putting a large task into swap space." Main RAM sees only the final conclusion, not the intermediate search noise. The distinction from a skill is that a skill puts "a procedure description" into the current context, while a subagent puts "the entire execution" into an isolated context.
</Tip>

<ArchFlow
  lang="en"
  nodes={[
{ label: "Main conversation", detail: "The primary context window. When a sub-task is detected, it matches the subagent description semantically or delegates explicitly via @-mention." },
{ label: "Agent tool call", detail: "The main conversation creates the subagent via the Agent tool (called Task before v2.1.63), passing the task description and parameters." },
{ label: "Isolated context", detail: "The subagent gets its own independent context window. frontmatter fields model, tools, permissionMode, and skills take effect here; with isolation: worktree an independent git worktree is also created." },
{ label: "Sub-task execution", detail: "The subagent completes all tool calls, searches, and modifications inside its own context. These intermediate costs do not pollute the main conversation." },
{ label: "Result returned", detail: "The subagent returns its summary or final result to the main conversation. The main conversation sees only this summary, not the intermediate steps." },
]}
/>

## 2. Two-layer structure: built-in and custom

Claude Code v2.1 introduces a two-layer subagent structure (\[1]):

| Layer        | Contents                                                                                                                                            | How triggered                                                                                             | Purpose                                         |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| **Built-in** | Explore, Plan, general-purpose, plus auxiliaries such as statusline-setup and claude-code-guide                                                     | Automatically invoked by the model based on task semantics; the user does not interact with them directly | Exploration, planning, complex multi-step tasks |
| **Custom**   | Markdown files you write, stored in `~/.claude/agents/`, `.claude/agents/`, plugin `agents/`, managed settings, or passed via `claude --agents` CLI | Automatically invoked by the model based on `description`, or explicitly via `@subagent-name`             | Specialized workers for specific domains        |

### 2.1 Built-in subagents

| Name                | Model                      | Tools                            | Purpose                                                      |
| ------------------- | -------------------------- | -------------------------------- | ------------------------------------------------------------ |
| **Explore**         | Haiku (fast, low latency)  | Read-only (Write / Edit refused) | File search, codebase exploration                            |
| **Plan**            | Inherits main conversation | Read-only                        | Research in plan mode (avoids infinite nesting)              |
| **general-purpose** | Inherits main conversation | All tools                        | Complex multi-step tasks mixing exploration and modification |
| statusline-setup    | Sonnet                     | (auxiliary)                      | Invoked when running `/statusline`                           |
| claude-code-guide   | Haiku                      | (auxiliary)                      | Answering questions about Claude Code itself                 |

Explore and Plan have a special design: **they skip `CLAUDE.md` and the parent session's git status**, keeping research fast and cheap. All other built-in and all custom subagents do load `CLAUDE.md` \[1].

When invoking Explore you can specify a thoroughness level: `quick` (targeted query), `medium` (balanced), `very thorough` (comprehensive analysis).

### 2.2 Custom subagents vs built-in

A custom subagent is **a single Markdown file** containing YAML frontmatter (configuration) and a body (system prompt). It can be placed in multiple scopes; the scope determines which sessions can use it and its priority.

The most important design distinction:

* Built-in subagents primarily run **read-only** tasks (Plan, Explore). `general-purpose` is the only built-in that can write.
* Custom subagents are entirely your design: read-only or writable, model-specified, skill-preloaded, worktree-isolated.

## 3. Placement locations and priority order

Custom subagents can be placed in five scopes, from highest to lowest priority \[1]:

| Location                   | Scope                                | Priority    | How to create                        |
| -------------------------- | ------------------------------------ | ----------- | ------------------------------------ |
| Managed settings           | Organization-wide                    | 1 (highest) | Admin deployment                     |
| `--agents` CLI flag        | Current session                      | 2           | Pass JSON when launching Claude Code |
| `.claude/agents/`          | Current project (version-controlled) | 3           | Interactive or manual                |
| `~/.claude/agents/`        | All your projects                    | 4           | Interactive or manual                |
| Plugin `agents/` directory | Within plugin's enabled scope        | 5 (lowest)  | Installed with the plugin            |

Claude Code **recursively scans** `.claude/agents/` and `~/.claude/agents/`, so subdirectories work (`agents/review/`, `agents/research/`). **Directory path does not affect subagent identity**; identity comes from the `name` field in frontmatter only. If two files in the same scope declare the same `name`, Claude Code keeps one and silently discards the other \[1].

Plugin `agents/` directories are also scanned recursively, but **subdirectories become part of the scoped identifier**: `my-plugin/agents/review/security.md` is identified inside plugin `my-plugin` as `my-plugin:review:security` \[1].

<Tip>
  **When to choose project-level vs user-level**

  Project-level (`.claude/agents/`) goes into version control and is shared with the team, so it is appropriate for subagents specific to this codebase. User-level (`~/.claude/agents/`) is available across all projects and is appropriate for subagents you use in all your work, such as a personal code review agent.
</Tip>

<Warning>
  **Plugin subagents restrict three frontmatter fields**

  For security reasons, plugin subagents **do not support** the `hooks`, `mcpServers`, or `permissionMode` fields; these are silently ignored \[1]. If you need any of the three, copy the agent file into `.claude/agents/` or `~/.claude/agents/`. Alternatively, add rules to `settings.json`'s `permissions.allow`, but that rule applies to the entire session, not just the plugin agent.
</Warning>

## 4. Full frontmatter reference

Subagent file format (as of 2026-06, per the official subagents documentation \[1]):

```markdown theme={null}
---
name: code-reviewer
description: Reviews code for quality and best practices
tools: Read, Glob, Grep
model: sonnet
---

You are a code reviewer. When invoked, analyze the code and provide
specific, actionable feedback on quality, security, and best practices.
```

Only `name` and `description` are required; all other fields are optional. Complete field list:

| Field             | Required | Purpose                                                                                                                                                    |
| ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`            | Yes      | Unique identifier (lowercase letters and hyphens). The `agent_type` received by the `SubagentStart` hook is this value \[1]                                |
| `description`     | Yes      | The basis on which the model decides when to delegate to this subagent                                                                                     |
| `tools`           | No       | Allowlist of tools available to the subagent. Omitting this inherits all tools. To preload skills, **use the `skills` field, not `Skill` in `tools`** \[1] |
| `disallowedTools` | No       | Blocklist, removing tools from the inherited or specified list                                                                                             |
| `model`           | No       | `sonnet` / `opus` / `haiku` / full model ID / `inherit` (default)                                                                                          |
| `permissionMode`  | No       | `default` / `acceptEdits` / `auto` / `dontAsk` / `bypassPermissions` / `plan`                                                                              |
| `maxTurns`        | No       | Maximum agentic turns for this subagent in this invocation                                                                                                 |
| `skills`          | No       | List of skill names to preload into the subagent context; full content is injected                                                                         |
| `mcpServers`      | No       | MCP servers dedicated to this subagent; can be inline or reference an already-connected server                                                             |
| `hooks`           | No       | Lifecycle-specific hooks for this subagent                                                                                                                 |
| `memory`          | No       | Persistent memory scope: `user` / `project` / `local`                                                                                                      |
| `background`      | No       | Default background mode `false`; set to `true` to always run as a background task                                                                          |
| `effort`          | No       | Override session effort: `low` / `medium` / `high` / `xhigh` / `max`                                                                                       |
| `isolation`       | No       | Set to `worktree` to run the subagent in a temporary git worktree                                                                                          |
| `color`           | No       | UI display color: `red` / `blue` / `green` / `yellow` / `purple` / `orange` / `pink` / `cyan`                                                              |
| `initialPrompt`   | No       | The first user turn when this agent runs as the main session (via `--agent` or `agent` setting)                                                            |

<Note>
  **`Task` renamed to `Agent` in v2.1.63**

  In v2.1.63, the `Task` tool was renamed to `Agent` (\[1]). The old `Task(...)` syntax still works as an alias in settings and agent definitions. `tools: Agent(worker, researcher)` is the v2.1+ standard syntax for restricting which types a subagent can spawn.
</Note>

### 4.1 Model resolution order

When Claude invokes a subagent, the model is resolved in the following order \[1]:

<Steps>
  <Step title="CLAUDE_CODE_SUBAGENT_MODEL environment variable">
    Highest priority. Set this at launch to uniformly specify the model for all subagents, overriding everything else.
  </Step>

  <Step title="model parameter at invocation time">
    The model parameter passed by the caller at invocation time, taking precedence over frontmatter.
  </Step>

  <Step title="Subagent frontmatter model">
    The `model` field declared in the subagent file. `model: inherit` (default) means use the same model as the main conversation.
  </Step>

  <Step title="The main conversation's model">
    Fallback to the model currently in use by the main conversation when none of the above is specified.
  </Step>
</Steps>

**Use a cheaper model (Haiku) for repetitive, structurally clear sub-tasks; reserve Sonnet / Opus for tasks with genuine reasoning demands.** This is the most direct cost-saving lever in subagent design.

### 4.2 Tool allowlist vs blocklist

`tools` sets an allowlist; `disallowedTools` sets a blocklist. **When both are set, the blocklist is applied first, then the allowlist is applied to what remains** \[1].

Allowlist example (strict restriction):

```yaml theme={null}
---
name: safe-researcher
description: Research agent with restricted capabilities
tools: Read, Grep, Glob, Bash
---
```

Blocklist example (inherit all tools but block writes):

```yaml theme={null}
---
name: no-writes
description: Inherits every tool except file writes
disallowedTools: Write, Edit
---
```

<Warning>
  **Tools that cannot be used in subagents**

  Even if listed in `tools`, the following tools **cannot** be used in a subagent \[1]:

  * `Agent` (a subagent cannot spawn another subagent)
  * `AskUserQuestion`
  * `EnterPlanMode`
  * `ExitPlanMode` (unless `permissionMode: plan`)
  * `ScheduleWakeup`
  * `WaitForMcpServers`
</Warning>

### 4.3 Restricting spawnable subagent types

When an agent runs as the main thread (`claude --agent`), it can spawn subagents. **Use `tools: Agent(worker, researcher)` to restrict which types it can spawn** \[1]:

```yaml theme={null}
---
name: coordinator
description: Coordinates work across specialized agents
tools: Agent(worker, researcher), Read, Bash
---
```

This is an allowlist: only `worker` and `researcher` can be spawned. To allow any type, use `tools: Agent, Read, Bash` (no parentheses). Omitting `Agent` entirely means the agent cannot spawn any subagents. **This restriction applies only to main-thread agents; subagents themselves cannot spawn any subagents** (no nesting), so `Agent(agent_type)` in a subagent frontmatter has no effect \[1].

### 4.4 `permissionMode` details

| Mode                | Behavior                                                                                  |
| ------------------- | ----------------------------------------------------------------------------------------- |
| `default`           | Standard permission checks and prompts                                                    |
| `acceptEdits`       | Automatically accepts file edits within the working directory and `additionalDirectories` |
| `auto`              | Auto mode: background classifier reviews commands and writes to protected directories     |
| `dontAsk`           | Automatically rejects permission prompts (explicitly allowed tools remain usable)         |
| `bypassPermissions` | Skips all permission prompts                                                              |
| `plan`              | Plan mode (read-only exploration)                                                         |

<Warning>
  **Parent session mode takes precedence**

  If the main session uses `bypassPermissions` or `acceptEdits`, the subagent **cannot override it** (\[1]). If the main session uses auto mode, the subagent inherits auto mode and the `permissionMode` in frontmatter is ignored: the classifier evaluates subagent tool calls using the same rules as the main session.

  `bypassPermissions` skips all permission prompts, including writes to `.git`, `.claude`, `.vscode`, `.idea`, `.husky`, and `.cargo`. `rm -rf` on root or home directories still prompts as a circuit breaker \[1].
</Warning>

### 4.5 `skills`: preloading skill content into a subagent

```yaml theme={null}
---
name: api-developer
description: Implement API endpoints following team conventions
skills:
  - api-conventions
  - error-handling-patterns
---

Implement API endpoints. Follow the conventions and patterns from the preloaded skills.
```

The **full content** of each listed skill is injected into the subagent context at startup. This controls "what is preloaded," **not** "what can be invoked": skills not listed can still be discovered and invoked at runtime via the Skill tool from project / user / plugin skills \[1].

Preloading has one reverse constraint: **skills with `disable-model-invocation: true` cannot be preloaded**, because preloading and model invokability share the same skill set. If a listed skill is missing or disabled, Claude Code skips it and writes a warning to the debug log \[1].

<Tip>
  **Subagent preloading a skill vs a skill running inside a subagent**

  These are two views of the same underlying mechanism (\[1]):

  * **Subagent frontmatter `skills: [...]`**: the subagent controls its system prompt and loads skill content into it.
  * **Skill frontmatter `context: fork` + `agent: ...`**: skill content becomes the task prompt for the specified agent, which runs in a clean context.

  The two are the same thing underneath, just written from opposite ends.
</Tip>

### 4.6 `isolation: worktree`

`isolation: worktree` runs the subagent inside a **temporary git worktree**, giving it an isolated copy of the repo (forked from the default branch, not the parent session's `HEAD`) \[1].

```yaml theme={null}
---
name: refactor-agent
description: Refactor a module in isolation
isolation: worktree
tools: Read, Edit, Write, Bash
---
```

Worktree behavior:

* A temporary worktree is created automatically when the subagent starts.
* All writes by the subagent occur only in this worktree; the main working directory is unaffected.
* **If the subagent makes no changes, the worktree is cleaned up automatically** \[1].
* If changes are made, you decide whether to merge, keep, or discard them.

<Warning>
  **`cd` inside a subagent does not persist**

  A `cd` inside a subagent does not persist across Bash / PowerShell tool calls and does not affect the main session's working directory \[1]. Use `isolation: worktree` when you need an isolated working directory.
</Warning>

## 5. Read-only vs writable, and when to use worktree isolation

The only criterion is: **will this subagent modify files or external state?**

| Type                                      | Task                                                      | Tools                                              | worktree                                      |
| ----------------------------------------- | --------------------------------------------------------- | -------------------------------------------------- | --------------------------------------------- |
| Read-only                                 | Search, review, summarize, analyze                        | `Read`, `Glob`, `Grep`; **block** `Write` / `Edit` | Not needed                                    |
| Writable (no parallel conflict)           | Refactoring, doc generation, single-file edits            | Includes `Write` / `Edit`                          | Not needed (single subagent)                  |
| Writable (multiple subagents in parallel) | Multiple subagents simultaneously writing different files | Includes `Write` / `Edit`                          | **Needed**, one worktree per subagent         |
| Untrusted input                           | Processing external documents, URLs, PR content           | Minimum set                                        | Strongly recommended (blast radius isolation) |

Worktree workflow:

```bash theme={null}
# 1. Create an independent worktree for each subagent
git worktree add ../agent-A -b agent-A-branch
git worktree add ../agent-B -b agent-B-branch

# 2. Each subagent works inside ../agent-A and ../agent-B respectively

# 3. Merge or compare when done
git diff main agent-A-branch
git merge agent-A-branch
```

<Note>
  **Decision checklist**

  1. Will this subagent write files or modify external state? No: no worktree needed.
  2. Will the subagents running in parallel write to overlapping paths? Yes: use worktrees.
  3. Will the subagent process untrusted content (external documents, arbitrary PRs)? Yes: use a worktree for blast radius isolation.
</Note>

## 6. Pairing with skills: procedure vs container

This is the most common point of confusion between subagents and skills. To clarify the division:

| Dimension    | Skill                                                     | Subagent                                                             |
| ------------ | --------------------------------------------------------- | -------------------------------------------------------------------- |
| Nature       | Procedure definition (steps, criteria, format)            | Execution container (context, model, tools, isolation)               |
| When loaded  | Invoked when the model judges semantic relevance          | Delegated by the model based on `description`, or via `@`-mention    |
| Who executes | The Claude in the current conversation (main or subagent) | The subagent itself                                                  |
| Reuse        | The same skill can be used in different conversations     | The same subagent definition can be delegated from multiple sessions |
| Best for     | "This flow should run this way"                           | "Run this task in an isolated context"                               |

### 6.1 Three typical pairings

**Skill only**: the procedure runs in the main conversation; no isolation needed. Example: "Rewrite the document in this writing style."

**Subagent only**: the sub-task procedure is simple enough to write into the subagent description; no reuse needed. Example: "Search the codebase for all places that use a deprecated API."

**Skill + subagent together**: two paths.

Path A: subagent preloads skill (`skills: [...]`)

```yaml theme={null}
---
name: code-reviewer
description: Reviews code for team conventions
skills:
  - api-conventions
  - testing-standards
---

You are a code reviewer. Apply the preloaded conventions and standards.
```

Path B: skill uses `context: fork` to push into a subagent

```yaml theme={null}
# SKILL.md in a Skill directory
---
description: Research a topic and return a citation list
context: fork
agent: Explore
---

Research $ARGUMENTS thoroughly:
1. Use Glob and Grep to find relevant files
2. Read and analyze
3. Summarize with specific file references
```

Both paths share the same underlying mechanism; the difference is "who defines the procedure and who defines the container" \[1].

<Warning>
  **`context: fork` requires the skill to contain an explicit task**

  If the skill content is purely prescriptive ("follow these API conventions") with no explicit task, `context: fork` delivers "conventions" to the subagent with nothing to do, and it returns an empty result. `context: fork` is for procedural skills that contain concrete steps \[1].
</Warning>

## 7. Invoking a subagent

### 7.1 Automatic invocation

Claude reads the subagent's `description` and delegates automatically when the task semantics match. Writing a good `description` is the key to reliable triggering.

<Note>
  **Description phrasing comparison**

  Too broad, causes false positives:

  ```yaml theme={null}
  description: Help me handle various tasks
  ```

  Too narrow, causes missed triggers:

  ```yaml theme={null}
  description: Convert my weekend research journal into markdown
  ```

  About right:

  ```yaml theme={null}
  description: Find type errors, unused imports, and public functions missing docstrings in a Python codebase. Use when reviewing Python files or after a refactor.
  ```
</Note>

### 7.2 Explicit invocation: `@`-mention

Use `@subagent-name` in the main conversation for explicit invocation. Example: "Use `@code-reviewer` to look at what this PR changed."

Plugin subagents use their namespaced identifier: `@my-plugin:review:security` \[1].

### 7.3 Background mode

`background: true` makes the subagent always run as a background task, running in parallel with the main conversation; Claude Code notifies the main conversation when the subagent completes \[1].

## 8. Tool comparison

The mechanism for "isolated context sub-agents" differs significantly across tools (as of 2026-06):

| Concept                | Anthropic Claude (primary)                                                                      | OpenAI Codex                                                                                                                                                                    | Google Antigravity                | GitHub Copilot CLI                   | Cursor (brief)                           |
| ---------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------ | ---------------------------------------- |
| Custom subagent format | Markdown frontmatter file                                                                       | `~/.codex/agents/*.toml` (personal) / `.codex/agents/*.toml` (project) + `config.toml`'s `[agents]` global params; required: `name`/`description`/`developer_instructions` \[6] | `.agents/agents/*.md` frontmatter | Not applicable (CLI is single-agent) | `.cursor/agents/` and built-in subagents |
| Built-in sub-agents    | Explore (Haiku, read-only), Plan (inherited, read-only), general-purpose (inherited, all tools) | System-layer provider agent                                                                                                                                                     | System-layer sub-agent            | Not applicable                       | Composer, Background Agent, etc.         |
| Model specification    | `model: sonnet/opus/haiku/inherit/<id>`                                                         | Configuration-based                                                                                                                                                             | Configuration-based               | Configuration-based                  | Configuration-based                      |
| Tool convergence       | `tools` allowlist + `disallowedTools` blocklist                                                 | Configuration-based                                                                                                                                                             | Configuration-based               | Tool allowlist / blocklist           | Configuration-based                      |
| Isolation mechanism    | `isolation: worktree`                                                                           | Environment layer                                                                                                                                                               | Environment layer                 | Environment layer                    | Environment layer                        |
| Skill preloading       | `skills: [...]` frontmatter                                                                     | Not applicable                                                                                                                                                                  | Configuration-based               | Not applicable                       | Not applicable                           |
| Permission mode        | `permissionMode: default/acceptEdits/auto/dontAsk/bypassPermissions/plan`                       | Configuration-based                                                                                                                                                             | Configuration-based               | Configuration-based                  | Configuration-based                      |
| Persistent memory      | `memory: user/project/local`                                                                    | Not applicable                                                                                                                                                                  | Memory mechanism                  | Not applicable                       | Not applicable                           |
| Explicit invocation    | `@subagent-name`                                                                                | `/agent` command                                                                                                                                                                | Configuration-based               | Configuration-based                  | `@agent`                                 |

<Note>
  **Naming clarification**

  * **Claude Code's subagent tool name**: renamed from `Task` to `Agent` in v2.1.63 (old `Task(...)` still works as an alias) (\[1]). `tools: Agent(worker, researcher)` to restrict spawnable types is the v2.1+ standard syntax.
  * **OpenAI Codex** subagents have been verified against official documentation \[6]: `config.toml`'s `[agents]` defines global parameters (`max_threads` / `max_depth` / `job_max_runtime_seconds`); individual agent roles go in `~/.codex/agents/*.toml` (personal) or `.codex/agents/*.toml` (project). There is no `~/.codex/prompts/*.md` or `codex.md`; persistent instructions use `AGENTS.md`.
  * **Antigravity and Cursor** mechanisms evolve quickly; verify against each vendor's current documentation before adopting.
  * **GitHub Copilot CLI** is a single-agent model as of 2026-06 and does not offer a first-class subagent mechanism; the cloud coding agent is a separate track.
  * **Cursor is a third-party IDE** (Anysphere); this Playbook mentions it in a single column only.
</Note>

## 9. Hands-on exercises

<Note>
  **30-minute exercises**

  1. **Write a read-only subagent**: create `~/.claude/agents/api-explorer.md`, give the frontmatter `tools: Read, Glob, Grep` and `model: haiku`, and write a body that says "scan the endpoints under `src/api/` and report each endpoint's method, path, and authentication requirements." Use `/agents` to confirm it appears in the Library.
  2. **Write a writable subagent**: create `.claude/agents/doc-fixer.md`, give it `tools: Read, Edit, Grep`, `model: haiku`, and `permissionMode: acceptEdits`, with a body that says "replace every `TODO` in `.md` files with an anchor linking to the corresponding issue." Invoke it explicitly with `@doc-fixer` in the same project.
  3. **Isolation test**: write a subagent with `isolation: worktree` and have it modify a file. Observe the worktree being created automatically, the worktree persisting after the subagent finishes, and the diff against the main working directory. When no changes are made, the worktree should clean itself up.
  4. **Skill + subagent**: write a skill using `context: fork` and `agent: Explore`; invoke the skill and observe it running in an isolated context, with the result summary returned to the main conversation.
  5. **Preload a skill**: write a subagent using `skills: [api-conventions]`; after starting a session, verify whether the skill content is already in the subagent's context by asking the subagent "do you see api-conventions?"
</Note>

## 10. Common pitfalls

<Warning>
  **Anti-pattern list**

  * **Using the strongest model for every subagent**: repetitive, structured sub-tasks need only Haiku-class models; reserve Opus for tasks that genuinely require deep reasoning, otherwise costs compound linearly.
  * **Granting overly broad tool permissions**: giving `Write` and `Bash` to a read-only task defeats the purpose of isolation and increases supply chain risk. Default to an allowlist of the minimum required set.
  * **Writing a skill procedure into the subagent description when there is no reuse need**: if you only use it once, there is no need to force a skill; writing the procedure directly in the subagent body is simpler.
  * **`isolation: worktree` on a read-only task**: no writes means no need for a worktree; adding one wastes disk space and creation time.
  * **Expecting the model to trigger without a designed description**: model triggering is semantic matching; descriptions that are too vague, too technical, or too broad will all cause missed triggers.
  * **Using a subagent as a thread**: subagents are one-shot containers that are destroyed when the task ends. For persistent conversation and addressable agents, use an agent team (see [04-11](/en/code-agent/customization/team-vs-subagent)).
  * **Putting sensitive information in the subagent body**: the body goes into context and, if version-controlled, is visible to everyone. Use environment variables or dynamic injection for secrets.
</Warning>

## Self-check

<Check>
  **Self-check**

  1. Can you describe the two-layer structure of Claude Code v2.1 subagents, and the default model and tool set for each of the three built-ins (Explore, Plan, general-purpose)?
  2. Can you write a subagent with complete frontmatter and a `description` that triggers reliably?
  3. For a real sub-task you have at hand, can you clearly state: the reasoning behind the `model` choice, the minimum `tools` set, whether `isolation: worktree` is needed, whether and which `permissionMode` to use, and whether `skills` preloading applies?
  4. Can you distinguish the relationship between subagents and skills? When should you use only one or the other, and when should you combine them?
</Check>

## Sources and further reading

Factual claims are grounded in official documentation; fast-changing items are annotated as of 2026-05.

<div className="references">
  * \[1] Anthropic, "Create custom subagents," code.claude.com, 2026. (two-layer structure; complete frontmatter reference; `isolation: worktree`; `skills` preloading; `memory` persistence; v2.1.63 `Task` renamed to `Agent`) [https://code.claude.com/docs/en/subagents](https://code.claude.com/docs/en/subagents) (as of 2026-06)

  * \[2] Anthropic, "Extend Claude with skills," code.claude.com, 2026. (the two pairing paths between skills and subagents via `context: fork` and `skills:` preloading) [https://code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills) (as of 2026-06)

  * \[3] Anthropic, "Plugins reference," code.claude.com, 2026. (plugin subagent restriction on `hooks` / `mcpServers` / `permissionMode`) [https://code.claude.com/docs/en/plugins-reference](https://code.claude.com/docs/en/plugins-reference) (as of 2026-06)

  * \[4] Anthropic, "Worktrees," code.claude.com, 2026. (`isolation: worktree` mechanism and default base branch behavior) [https://code.claude.com/docs/en/worktrees](https://code.claude.com/docs/en/worktrees) (as of 2026-06)

  * \[5] Agent Skills Open Standard, "Agent Skills," 2026. (open standard for skill and subagent interoperability) [https://agentskills.io](https://agentskills.io) (as of 2026-06)

  * \[6] OpenAI, "Subagents," developers.openai.com/codex, 2026. (`config.toml`'s `[agents]` global parameters `max_threads` / `max_depth` / `job_max_runtime_seconds`; individual agent TOML at `~/.codex/agents/` (personal) and `.codex/agents/` (project); required fields `name` / `description` / `developer_instructions`, optional `model` / `sandbox_mode` / `mcp_servers`; no `prompts/*.md` or `codex.md`; persistent instructions use `AGENTS.md`) [https://developers.openai.com/codex/subagents](https://developers.openai.com/codex/subagents) (as of 2026-06)
</div>

* `CLAUDE.md` and rules: see [04-1 CLAUDE.md and memory files](/en/code-agent/customization/claude-md-memory) and [04-2 rules](/en/code-agent/customization/rules).
* Skills and frontmatter: see [04-4 Skills](/en/code-agent/customization/skills).
* Deterministic enforcement via hooks: see [04-6 Hooks](/en/code-agent/customization/hooks).
* Context isolation concepts: see [01-4 Context engineering](/en/code-agent/foundations/context-engineering).
* Agent teams and multi-agent orchestration: see [04-11 Agent teams and sub-agents](/en/code-agent/customization/team-vs-subagent).
