Skip to main content

Module 10 — Subagents, parallel agents, and agent teams

A conversation with Claude Code is powerful as long as it fits in a readable context. Past a certain volume — an audit of twenty-five files, a migration of three hundred components — the main thread drowns and the token budget is exhausted. The answer is not "prompt harder," but delegate. Claude Code offers four complementary families: subagents, forks, agent teams, and dynamic workflows.

Why and when to delegate

Rule of thumb: every new subagent gets a fresh context. It does not see your history, your /clear, or the files already read. It receives its system prompt, a task message, and the inherited CLAUDE.md files.

The point is exact: this isolation also isolates noise. A pytest -x -vv that produces two thousand lines of traces, a Grep across three hundred files, a read of Kubernetes logs: everything stays inside the subagent, only the summary comes back. The trade-off is latency: a subagent starts cold.

ApproachWhat you getWhen to use it
SubagentsDelegated workers inside a single session, isolated context, return a summaryA task would drown the main thread (logs, search, test output)
"Agent view"A screen that dispatches and monitors background sessions (claude agents)Several independent tasks to launch and monitor
Agent teamsCoordinated sessions, shared task list, inter-agent messaging. Experimental, disabled by defaultClaude splits a project, assigns pieces, syncs the workers
Dynamic workflowsA Claude script orchestrates many subagents and cross-references their resultsFull-repo audit, migration of hundreds of files, cross-source research

Three tools support these without being ways to execute agents themselves: worktrees (each session in a separate git checkout, no more edit conflicts), inter-session messaging to pass findings around, and the /batch command that stacks subagents and worktrees in a single move.

Subagents: the building blocks

A custom subagent is a Markdown file with a YAML header in .claude/agents/ (project, versioned) or ~/.claude/agents/ (user). Claude Code watches these folders and reloads within seconds; a restart is only needed on the first creation in a scope. Only name and description are required.

Documented frontmatter fields:

FieldRole
nameUnique identifier in lowercase and hyphens; : forbidden (reserved for plugins)
descriptionWhen Claude should delegate
tools / disallowedToolsAllowlist / denylist of tools (denylist applied first)
modelsonnet, opus, haiku, fable, a full ID, or inherit
permissionModedefault, acceptEdits, auto, dontAsk, bypassPermissions, plan
maxTurnsTurns before stopping; output is marked partial
skills / mcpServers / hooksResources scoped to this subagent
memoryuser, project, or local (persistent memory)
backgroundtrue to keep it in the background
isolationworktree for a separate git checkout
color / initialPromptDisplay, first auto-sent message with --agent

Three invocations. Natural language: "use the reviewer subagent." @-mention: @"reviewer (agent)" forces the call. Full session: claude --agent reviewer replaces the system prompt for the entire session.

A subagent that has produced output can be re-invoked: Claude calls SendMessage with the ID or name. Transcripts live in ~/.claude/projects/{project}/{sessionId}/subagents/agent-{id}.jsonl and survive a /compact.

Built-in subagents

Three built-in subagents exist without any declaration: Explore (code reconnaissance, read-only), Plan (preparing a plan before editing), general-purpose (tasks without a precise definition). Explore and Plan are one-shot: no ID, not resumable.

Concurrency and depth limits

Two variables govern speculation. CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS sets the number of simultaneous subagents per session — 20 by default; beyond that, the Agent tool refuses with Concurrent subagent limit reached. CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH controls nesting: 3 by default. At maximum depth, the Agent tool is removed from the subagent. Setting 1 disables nesting entirely.

{
"env": {
"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "8",
"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "2"
}
}

Forks: the entire conversation, in parallel

A fork is a special subagent: it inherits the system prompt, the tools, the model, and the entire history of the main conversation. No redecoration. Use it to try a variant without polluting the thread: draft tests while you code, try two approaches from the same starting point.

The dedicated command is /subtask (Claude Code v2.1.212+, /fork before):

/subtask draft the unit tests for the parser with the recent changes

The fork runs in the background, its result comes back as a message. It cannot spawn another fork, and its prompt cache is shared with the main conversation — that is what makes it cheap. Fork mode is active by default in interactive mode; toggle it through CLAUDE_CODE_FORK_SUBAGENT.

Essential commands

  • /tasks — view of background work: active and finished subagents, shell commands. Enter opens the transcript, x stops or cleans up.
  • /list-agents (or /peers) — list the subagents, agent-team teammates, and reachable Claude Code sessions, with the exact name for inter-session messaging.
  • /agents — watch out for the trap. Since v2.1.198, this command no longer opens an editor: it simply reminds you where to edit (.claude/agents/ or ~/.claude/agents/).
  • /batch <instruction> — a bundled skill that studies the repo, splits the task into 5 to 30 independent units, presents a plan, then launches one subagent per unit, each in its worktree, each opening its own PR. Ideal for a massive migration.
  • /workflows — tracking dynamic workflows: pause, resume, save.

Worktrees: isolation at the file level

A worktree is a separate git directory, branched from the main repo, with its own files. Two sessions in two worktrees never step on each other:

claude --worktree feature-payment

The worktree is created under .claude/worktrees/feature-payment/ on a branch worktree-feature-payment. On exit, Claude Code asks what to do if any changes remain. To give a subagent its own checkout, just add isolation: worktree to its frontmatter: Claude Code creates a temporary worktree and cleans it up if no changes remain there.

A .worktreeinclude file (.gitignore syntax) automatically copies gitignored files (typically .env) into each new worktree.

Agent teams (experimental)

Agent teams orchestrate several Claude Code sessions coordinated by a lead. Experimental, disabled by default: enable via CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 in env. Once active, just describe the task: "spawn three teammates to explore this problem from three angles." The lead opens a shared task list, spawns teammates, and assigns work.

Two display modes: in-process (same terminal, arrow+Enter navigation) and split panes (each teammate in a tmux or iTerm2 pane). Setting via teammateMode in settings.json or --teammate-mode. Warning: teammates are not isolated in worktrees, you must partition the files.

Dynamic workflows

A dynamic workflow is a script written by Claude that spawns many subagents and cross-references their results. It fits when a handful of subagents is no longer enough: full-repo audit, migration of 500 files, cross-source research. Provided workflows (/deep-research) are accessible directly; you can also ask Claude to write one, approve it via plan mode, then save it for replay. Tracking via /workflows.

Kiosque: two complete subagents

For Kiosque, Nadia codes two project subagents, versioned in .claude/agents/. The first reviews code, the second runs the test suite in an isolated context.

Subagent 1 — reviewer

Goal: pass a post-modification review in read-only mode and report a prioritized summary. No edit rights, no Write access.

---
name: reviewer
description: Reviews recent Python changes. Use proactively after a coding session.
tools: Read, Grep, Glob, Bash
model: inherit
permissionMode: plan
color: blue
---

You are a senior Python reviewer for the Kiosque codebase.

When invoked:
1. Run `git diff main...HEAD` to identify the changes.
2. Focus on modified `.py` files.
3. Apply the following checklist and report a summary.

Checklist:
- Readability, naming, no duplicated code.
- Explicit error handling (no bare `except:`).
- No secrets in plain text, no API keys committed.
- Input validation on the FastAPI side.
- Sufficient test coverage for the modified behavior.
- Alembic migrations generated if the schema changes.

Report in three sections:
- "Blockers": fix before merge.
- "To revisit": recommended improvements.
- "Nits": style or taste details.

Do not modify any file.

Subagent 2 — tester

Goal: run make test in an isolated worktree (so as not to pollute the main checkout if a test creates a temporary file), and report only failures.

---
name: tester
description: Runs the Kiosque test suite in an isolated worktree and reports only failures with their traces.
tools: Read, Bash, Grep
model: haiku
isolation: worktree
maxTurns: 10
color: green
hooks:
PostToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "${CLAUDE_PROJECT_DIR}/.claude/hooks/annotate-tests.sh"
---

You are a test runner for Kiosque.

When invoked:
1. Confirm you are inside a worktree (`git rev-parse --show-toplevel`).
2. Run `make test` with full output.
3. If everything passes: return "Green suite: N tests, T seconds".
4. If a test fails: for each failure, extract the test name, the file, the line, the first assertion line, and 5 lines of trace context.
5. Never rerun the suite on an individual test unless asked to.
6. Do not modify any source code, any migration.

Failure output format:
- Number of tests run, number failing.
- List of failures (name, path, trace excerpt).
- No "probable cause" comment: just the facts.

Daily use

Karim types @"reviewer (agent)" review services/paiement/`` before opening a PR: the reviewer reads, touches nothing, returns three prioritized lists. Lea launches @"tester (agent)" run the full suite while she keeps coding: the tester runs in a temporary worktree, only failures come back. For a larger effort — moving every endpoint to Pydantic v2 — Nadia launches /batch migrate the endpoints in services/ to Pydantic v2: split into 20 units, one subagent per module in its worktree, one PR per unit.

When to prefer an agent team

A reviewer + a tester = two subagents. A team becomes useful when several virtual humans need to hold a conversation with each other (architect, backend, frontend, each reacting to the others' messages). For one-shot, black-box delegable work, stick with subagents.

Summary

  • Subagents: isolated context, summarized return, YAML in .claude/agents/. Key fields: name, description, tools, model, permissionMode, isolation, maxTurns, skills, hooks.
  • Forks (/subtask): a subagent that inherits the whole context; cheap parallelism.
  • Limits: CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS (20) and CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH (3).
  • Commands: /tasks, /list-agents, /subtask, /fork, /batch, /workflows; /agents no longer opens an editor.
  • Worktrees: --worktree <name> isolates a session; isolation: worktree on a subagent gives it its own checkout.
  • Agent teams (experimental): CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1. Dynamic workflows: Claude scripts at scale, tracked via /workflows.

Next module: MCP: connect Claude Code to your tools and data — how to open Claude Code onto GitHub, a Postgres database, a ticket tracker, without writing the integration code yourself.