Claude Code Has Four Agent Modes

This note combines two sources. Part 1 summarizes Kristopher Dunham’s article (Medium, 2026-05-20) on the four delegation patterns, with a link to the original. Part 2 is a subagent reference built with Claude chat on 2026-09-16 from the official docs and the author’s own testing in the desktop app, and goes much deeper on the second pattern.

Related: Context-Rot-and-Governing-Context (why the single window degrades) · Building-Claude-Code-with-Harness-Engineering

Note: claim tags in Part 2. Each claim in Part 2 is tagged [Docs] (official docs, fetched 2026-09-16; each tag links to the supporting section, rechecked 2026-10-16), [Tested] (confirmed hands-on by the author), or [Unverified] (inferred or not yet confirmed). Behavior references Claude Code versions up to ~v2.1.271; check yours with claude --version. Keep version numbers attached to any behavior that changed between releases, and prefer newer dated [Docs] and [Tested] entries over the article where they disagree.


Part 1 — The four patterns (summary)

A summary, in my own words, of Kristopher Dunham’s article Claude Code Has Four Agent Modes. Most Developers Only Use One. (Medium, 2026-05-20). Read the original for the full argument and its examples.

The argument: most people use Claude Code only as a single interactive session, and most of the trouble they run into, such as the agent losing the thread partway through a long task, comes from piling every file read, log and test result into one context window. Claude Code offers four ways to delegate work, and each fits a different shape of task.

PatternWhat it isUse it forSkip it when
Interactive sessionOne supervised claude session with one context windowExploration, pair programming, short supervised changesA long task fills the window with output
SubagentA separate instance with its own context, prompt and tool list, which returns only a summaryNoisy, self-contained jobs: running tests, digging through logs or legacy code, reviewsThe workers need to talk to each other
Agent teamSeveral instances working in parallel, sharing a task list and messaging each other directlyWork that splits cleanly across modules and needs negotiation between the partsThe parts edit the same files, or tokens matter more than wall-clock time
RoutineA saved prompt, repo and environment that runs on Anthropic’s cloud when triggeredRecurring, unattended choresThe task needs human judgment partway through

The four patterns

  • Interactive session. The default, and fine while you’re watching. Its weakness is that everything shares one context window, so quality slides as a long task fills it. See Context-Rot-and-Governing-Context.
  • Subagents. Each is a Markdown file with YAML frontmatter, in .claude/agents/ for one project or ~/.claude/agents/ for all of them.
    • description is what the main session reads to decide when to delegate, so it should read like a contract. tools is a hard allowlist. model lets a simple job run on a smaller, cheaper model.
    • The shape is strictly hub-and-spoke: subagents report to the main session and can’t talk to each other. Since superseded: the docs now let subagents that Claude named when it spawned them message each other with SendMessage (see Mental model in Part 2).
    • His advice: make your first subagent the task that pollutes your context the most. Part 2 below covers this pattern in depth.
  • Agent teams. A research preview from February 2026, turned on with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 in the env block of ~/.claude/settings.json.
    • Teammates coordinate through a shared task list stored as JSON and a peer-to-peer mailbox, so dependent tasks unblock on their own.
    • Each teammate is a full instance, so token cost grows with the size of the team, which Anthropic’s docs warn about. Sequential subagents are often the better and much cheaper choice.
  • Routines. A research preview from 2026-04-14, on Pro, Max, Team and Enterprise plans with Claude Code on the web enabled. Set one up at claude.ai/code/routines or with /schedule.
    • Triggers: a cron schedule (one-hour minimum), an HTTP endpoint protected by a bearer token, or GitHub events such as pull requests, pushes and releases.
    • Guardrails: a network allowlist (a blocked host returns 403 with x-deny-reason: host_not_allowed), and pull requests from webhook-triggered routines can only target claude/-prefixed branches.

The limitations he calls out

  • Agent teams are experimental: no session resume, one team per session, no nested teams, and split panes don’t work in VS Code’s integrated terminal.
  • A green routine status proves little. It means the run started and ended without an infrastructure error, not that the work is right. Check the transcript, or check the thing the routine was supposed to produce.
  • Team token costs are documented, not hypothetical. Start with subagents.
  • Subagents still hallucinate and over-engineer, just in a smaller context. Read the diff.
  • Any agent that reads input you don’t control can be prompt-injected: issue bodies, alert payloads, pull requests from forks, MCP server responses. Scope its permissions narrowly and sandbox it.
  • Permission rules resolve deny → ask → allow, and deny always wins. Organizations can lock this down with managed settings (allowManagedPermissionRulesOnly: true).

His suggested path

Climb one rung at a time, and only when real work calls for it: one subagent for your noisiest task; then one agent team for a task that truly parallelizes, compared honestly against a sequence of subagents; then one narrow scheduled routine, run for a while before it gets write access to anything important.

The bigger point

He cites an Anthropic internal survey of 132 engineers in which about 27% of the tasks delegated to Claude Code were work that otherwise wouldn’t have been done at all, such as documentation, test coverage and small UI fixes. His conclusion: as execution gets cheap, the valuable skills become defining a task clearly, delegating it cleanly, and checking the output with the same skepticism whoever wrote it.


Part 2 — Subagents in depth (reference)

TL;DR

  • A subagent is a separate Claude instance with its own fresh context window, system prompt, tool list, and permissions. It returns only a summary to the main session. [Docs]
  • The main use is keeping noisy work (searches, test logs, file dumps) out of the main context. [Docs]
  • Invoke by plain language, @agent-<name>, claude --agent <name>, or fork with /subtask. [Docs]
  • In the desktop app, @agent-explore works even though built-in agents do not appear in the @ typeahead. [Tested]
  • Current defaults favor background, nested, parallel agents. The recommended settings below restrict this to serial, reviewable work.

Mental model

  • The subagent does not see the conversation history, previously read files, or invoked skills. Its only input from the parent is the delegation prompt Claude writes. [Docs]
  • Exception: a fork inherits the full conversation. [Docs]
  • A non-fork subagent’s startup context contains its own system prompt (not the Claude Code system prompt), the task message, CLAUDE.md files (unless its definition sets omitClaudeMd), the git status snapshot (absent outside a git repository or when the snapshot is turned off), and preloaded skills. If it has the SendMessage tool and another agent in the session has a name, it also gets a roster of named sibling agents it can message. [Docs]
  • Where the system prompt comes from: the agent’s definition, never the main session. [Docs, confirmed 2026-09-16]
    • Custom file-based agents: the Markdown body of the agent file (everything after the frontmatter) becomes the system prompt. The frontmatter is configuration only.
    • Agents passed as --agents JSON: the prompt field, equivalent to the Markdown body.
    • Built-in agents: predefined prompts shipped with Claude Code.
    • Claude Code appends basic environment details such as the working directory. If the memory field is set, it also injects memory instructions and the first 200 lines / 25KB of that agent’s MEMORY.md.
    • Appending your own text: in non-interactive mode, --append-subagent-system-prompt (or --append-subagent-system-prompt-file) adds text to every subagent’s system prompt, nested ones included, but not forks (v2.1.205+; the -file form needs v2.1.261+).
    • Don’t confuse it with the task message. The system prompt is fixed per agent; the main-session Claude writes a fresh task message on every delegation. A fork has neither split: it reuses the main session’s own system prompt.
  • Explore and Plan skip CLAUDE.md and git status. [Docs]
  • Not passed to non-fork subagents: output style, the main session’s auto memory. The context window size comes from the subagent’s own model. [Docs]

Implication: any constraint set earlier in the session (e.g., “don’t touch vendor/”) must be restated in the delegation prompt, especially for Explore and Plan.

Built-in agents

NameAccessPurposeNotes
ExploreRead-only (Write/Edit denied)Codebase search and analysisSkips CLAUDE.md. Inherits the main model; when that is Fable, runs on Opus via the Claude API but stays on the main model on Bedrock and other cloud platforms (v2.1.198+; previously Haiku). Not resumable.
PlanRead-onlyResearch during plan modeSkips CLAUDE.md. Not resumable.
general-purposeAll subagent toolsMulti-step work with editsResumable.
claudeAll subagent toolsCatch-allAlso the default for background sessions.
claude-code-guide—Answers Claude Code feature questionsHaiku. Usually auto-invoked.
statusline-setup—/statusline configSonnet. Auto-invoked.

[Docs]

Ways to invoke

  1. Natural language: “Use the Explore subagent to find all call sites of X.” Claude decides whether to delegate, so it isn’t guaranteed. [Docs]
  2. @-mention: guarantees which agent runs, but Claude still writes the task prompt. [Docs]
    • Menu form: @"code-reviewer (agent)" ...
    • Manual form: @agent-<name> .... Plugin agents use @agent-plugin:name. [Docs]
  3. Session-wide: claude --agent <name>, or set "agent": "<name>" in .claude/settings.json. The agent’s prompt replaces the default system prompt, and the choice persists on resume. [Docs]
  4. Fork: /subtask <task>. On v2.1.161–v2.1.211 the command is /fork. [Docs]

Desktop app findings (2026-09-16)

  • Typing @ opens a fuzzy file matcher. In a working directory that contains a large notes folder, such as an Obsidian vault, short words like explore match hundreds of notes because the letters match in order across paths. [Tested]
  • Built-in agents do not appear in the desktop @ menu. No Explore (agent) entry was shown. [Tested]
  • Typing @agent-explore manually was recognized with no menu match. Lowercase worked, and Claude responded that no task was given. [Tested]
  • Open item: confirm the mention actually resolves rather than being inferred from text. Send @agent-explore <real task> and look for an Explore(...) tool row in the transcript. [Unverified]
    • Docs support it (2026-09-16): for the manual @agent-<name> form, “the typeahead shows file matches rather than agents” while you type, and the mention “still resolves when you submit.” That matches the [Tested] behavior above. The hands-on check is still open. [Docs]
  • Pressing Enter while the file menu is open likely inserts the highlighted file. Press Esc first. [Unverified]
  • Docs say custom, plugin, and running named agents appear in the typeahead. Not yet tested in the desktop app. [Unverified]

Confirming delegation happened

  • The transcript shows a tool row like Explore(Find loadUser call sites). [Docs]
  • /tasks shows running subagents and their model (v2.1.242+). [Docs]
  • If Claude reads files directly with no agent row, it didn’t delegate.

Custom subagents

  • Location: ~/.claude/agents/ (all projects) or .claude/agents/ (project, check into git). Directories are scanned recursively, and identity comes from name, not the filename. [Docs]
  • Priority on name collision: managed > --agents CLI JSON > project > user > plugin. [Docs]
  • Creation: as of v2.1.198, /agents no longer has a creation wizard. Write the file yourself or ask Claude to write it. Many tutorials are outdated on this. [Docs]
  • Reload: file edits are picked up within seconds, but a newly created agents directory needs a restart. [Docs]

Example: read-only failure-mode reviewer

---
name: failure-mode-reviewer
description: Reviews recent changes for unhandled errors and edge cases. Read-only.
tools: Read, Grep, Glob, Bash
model: inherit
maxTurns: 25
---

You review code changes for failure modes, not style. Run git diff, then for
each changed function report: unhandled error paths, unvalidated inputs,
boundary conditions, race conditions, and unverified assumptions.
Classify findings as Critical / Warning / Suggestion with file:line references.
Never propose edits you haven't traced through the calling code.

Warning: Bash in a “read-only” agent. tools without Edit/Write still allows Bash, which can modify files (sed -i, rm, git). For a truly read-only agent, drop Bash or add a PreToolUse hook that blocks writes. The same applies to any test-runner subagent that keeps Bash so it can run the suite, like the one in the original article. [Inference from docs]

Frontmatter fields

FieldPurposeNotes
name / descriptionRequiredLowercase and hyphens, no : and no leading -. The description drives auto-delegation.
toolsAllowlistOmit to inherit all subagent tools.
disallowedToolsDenylistApplied before tools. Bash(git push *) removes all of Bash.
modelsonnet/opus/haiku/fable/full ID/inherit
permissionModedefault, acceptEdits, auto, dontAsk, bypassPermissions, planOften overridden, see Gotchas.
maxTurnsTurn capOutput is marked partial and can be resumed (v2.1.246+).
isolation: worktreeTemporary git worktreeBranches from the default branch, not your HEAD or uncommitted work.
hooksPer-agent lifecycle hooksProject agents need workspace trust for hooks to run.
memoryuser/project/local persistent dirRequires auto memory enabled.
skillsPreload full skill content
mcpServersScope MCP servers to the agentKeeps tool descriptions out of the main context.
backgroundForce background
effortPer-agent effort
omitClaudeMdSkip CLAUDE.mdv2.1.271+

Fields ignored for plugin agents: hooks, mcpServers, permissionMode, initialPrompt. [Docs]

Validation

  • Files are silently skipped if they have no name, no description, bad YAML, or --- not on line 1. [Docs]
  • Check with claude plugin validate ~/.claude/agents (v2.1.233+). It won’t flag a missing name. [Docs]
  • Or run claude --debug and read the debug log.

Decision: limit delegation to 1–2 foreground agents with no nesting. Rationale: current defaults (fork mode on in interactive sessions, background by default, nesting depth 3, concurrency limit 20) produce more parallel work than can be personally reviewed.

~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_DISABLE_BACKGROUND_TASKS": "1",
    "CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "1",
    "CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "2"
  }
}
SettingEffectMin version
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1All subagents run in the foreground, with prompts shown to you one at a time—
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1Subagents can’t spawn subagentsv2.1.219 default = 3
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS=2Concurrency capv2.1.217
CLAUDE_CODE_FORK_SUBAGENT=0Fork mode off everywhere—
"permissions": {"deny": ["Agent"]}No delegation at all—
"permissions": {"deny": ["Agent(Explore)"]}Block a specific agent—

[Docs] · spawn depth · concurrency · fork mode · disabling agents

Open item: confirm these env settings take effect in the desktop app as well as the CLI. [Unverified]

Gotchas and failure modes

  1. Session-wide grants from background prompts. A lasting “allow” answered for a background subagent applies to the whole session, including the main thread. [Docs]
  2. permissionMode is ignored when the main session is in bypassPermissions, acceptEdits, or auto, because the subagent inherits that mode. A restricted agent can run permissively. [Docs]
  3. Background agents get a smaller built-in tool set, so the same definition behaves differently in the foreground and background. There’s no error unless zero tools remain. [Docs]
  4. disallowedTools specifiers remove the whole tool. Use permissions.deny for command-level blocks. [Docs]
  5. Silent skipping of malformed agent files (see Validation). [Docs]
  6. Explore and Plan don’t load CLAUDE.md, so project rules must be restated in the prompt. [Docs]
  7. Explore and Plan can’t be resumed. Use general-purpose or a custom agent for continuing work. [Docs]
  8. Worktree isolation branches from the default branch, so the agent won’t see your uncommitted changes. [Docs]
  9. Context cost. Many subagents returning detailed results can still flood the main context. [Docs]
  10. Token cost. A third-party writeup claims multi-agent workflows use ~4–7x the tokens of single-agent sessions, citing Anthropic. This is consistent with the article’s “many times the cost” for agent teams in Part 1, but the figure itself is not confirmed. [Unverified]
  11. Over-delegation. Higher-tier models may spawn agents when direct work would be cheaper. Watch for unexpected tool rows. [Third-party claim, Unverified]
  12. Version drift. Many behaviors changed across 2.1.x releases (Explore model, wizard removal, nesting defaults, fork command name). Re-check docs after updates.
  13. Prompt injection via subagent output. Reports are scanned and instruction-like text is escaped, but this is not a security boundary. Rely on tool restrictions. [Docs, v2.1.210+]

When to use a subagent and when not to

Use a subagent when the output is verbose and the conclusion is small (test runs, codebase searches, doc crawls), when you need enforced tool restrictions, or when the task is self-contained. [Docs]

Stay in the main session when the work involves tight back-and-forth, phases share heavy context (plan → implement → test), you’re making a quick targeted change, or latency matters. [Docs]

Alternatives:

  • /btw for side questions about the current context. It has no tools and nothing is added to history. [Docs]
  • Skills for reusable prompts that run in the main context. [Docs]
  • Agent teams (Pattern three in Part 1): a lead plus teammates that message each other directly. Separate sessions that pass messages without a team use cross-session messaging instead. Heavier and more expensive, and not aligned with a serial review workflow. [Docs]

Resuming

  • Claude resumes a finished subagent via SendMessage using its ID or name, with full history retained. [Docs]
  • Transcripts are stored at ~/.claude/projects/{project}/{sessionId}/subagents/agent-{agentId}.jsonl and deleted after cleanupPeriodDays (default 30). [Docs]
  • Agents you stopped manually (x in /tasks) don’t auto-resume. [Docs]

Sources