The definitive guide to multiplying your output with specialized sub-agents and coordinated multi-session teams. From single-session delegat
The definitive guide to multiplying your output with specialized sub-agents and coordinated multi-session teams. From single-session delegation to full swarm orchestration.
Sub-agents are specialized AI assistants that run within a single Claude Code session. Each sub-agent operates in its own context window with a custom system prompt, specific tool access, and independent permissions. When Claude encounters a task that matches a sub-agent's description, it delegates to that sub-agent, which works independently and returns results to the main conversation.
Without sub-agents, every task you perform eats into a single shared context window. Run a test suite? That verbose output fills your context. Explore a codebase? Those file reads pile up. Review code while also implementing a feature? Everything competes for the same limited space.
Sub-agents solve this by isolating work into separate contexts:
Main Conversation (your context stays clean)
|
+-- Sub-Agent: Explore (reads 50 files, only summary returns)
|
+-- Sub-Agent: test-runner (runs full suite, reports 3 failures)
|
+-- Sub-Agent: code-reviewer (analyzes diff, returns findings)
Sub-agents cannot spawn other sub-agents. If your workflow requires nested delegation, you must chain sub-agents from the main conversation or use Skills instead.
Main Conversation
|
+-- Sub-Agent A (works, returns results)
|
+-- [Main conversation receives results, decides next step]
|
+-- Sub-Agent B (works using insights from A)
This is a deliberate design constraint that prevents infinite nesting and keeps execution predictable.
Claude Code ships with several sub-agents that it uses automatically when appropriate. You never need to create these; they are always available.
| Sub-Agent | Model | Tool Access | Purpose | When Claude Uses It |
|---|---|---|---|---|
| Explore | Haiku (fast) | Read-only (Write/Edit denied) | File discovery, code search, codebase exploration | When it needs to search or understand a codebase without making changes |
| Plan | Inherits from main | Read-only (Write/Edit denied) | Codebase research for planning | During Plan Mode when Claude needs to gather context before presenting a plan |
| General-purpose | Inherits from main | All tools | Complex research, multi-step operations, code modifications | When a task requires both exploration and modification, or multiple dependent steps |
| Bash | Inherits from main | Bash commands only | Running terminal commands in a separate context | When it needs to run commands without cluttering main context |
| statusline-setup | Sonnet | Internal | Configuring your status line | When you run /statusline |
| Claude Code Guide | Haiku | Internal | Answering questions about Claude Code features | When you ask about Claude Code itself |
Explore is the most commonly triggered built-in sub-agent. When Claude needs to understand your codebase, it delegates to Explore rather than reading files directly in your main conversation.
Key behavior: Claude specifies a thoroughness level when invoking Explore:
| Thoroughness | When Used | Typical Scope |
|---|---|---|
| quick | Targeted lookups, finding a specific function or file | 1-5 files |
| medium | Balanced exploration, understanding a module | 5-20 files |
| very thorough | Comprehensive analysis, mapping an entire subsystem | 20+ files |
You do not control the thoroughness directly. Claude decides based on the complexity of the task. However, you can influence it by saying things like "do a thorough exploration of the auth module" versus "quickly find the login handler."
The Plan sub-agent is used exclusively during Plan Mode (/plan or Shift+Tab). When you ask Claude to plan an implementation, it uses this sub-agent to gather codebase context without modifying anything. This prevents the Plan sub-agent from accidentally making changes during the research phase.
The general-purpose sub-agent is the most capable built-in option. It has access to all tools and is used for complex tasks that require both reading and writing. Claude delegates to it for multi-step operations that would consume too much context in the main conversation.
Sub-agents are Markdown files with YAML frontmatter. The frontmatter defines configuration; the Markdown body becomes the system prompt.
---
name: my-agent
description: What this agent does and when Claude should use it.
tools: Read, Grep, Glob
model: sonnet
---
You are a specialist in [domain]. When invoked, do the following:
1. [Step one]
2. [Step two]
3. [Step three]
Format your output as:
- [Format specification]
Sub-agents are loaded from multiple locations. When multiple sub-agents share the same name, the higher-priority location wins.
| Priority | Location | Scope | How to Create | Version Control |
|---|---|---|---|---|
| 1 (highest) | --agents CLI flag (JSON) |
Current session only | Pass JSON when launching Claude Code | N/A (ephemeral) |
| 2 | .claude/agents/ |
Current project | Interactive (/agents) or manual file creation |
Yes -- commit to share with team |
| 3 | ~/.claude/agents/ |
All your projects | Interactive (/agents) or manual file creation |
No (personal) |
| 4 (lowest) | Plugin's agents/ directory |
Where plugin is enabled | Installed with plugins | Via plugin distribution |
When to use each scope:
.claude/agents/): Sub-agents specific to a codebase. A Django project might have a migration-reviewer agent. Check these into version control so your team benefits.~/.claude/agents/): Personal sub-agents you use across all projects. A code-simplifier that follows your personal style preferences.--agents): Temporary sub-agents for testing, scripting, or CI/CD pipelines. They exist only for the session.The /agents command is the recommended way to create and manage sub-agents.
/agents
This opens an interactive interface where you can:
Step 1: Run /agents in Claude Code
Step 2: Select "Create new agent"
Step 3: Choose scope:
- "User-level" (available in all projects, saved to ~/.claude/agents/)
- "Project-level" (this project only, saved to .claude/agents/)
Step 4: Choose creation method:
- "Generate with Claude" -- Describe what you want, Claude writes the file
- "Write manually" -- Opens your editor with a template
Step 5: If generating with Claude, provide a description:
"A code improvement agent that scans files and suggests improvements
for readability, performance, and best practices. It should explain
each issue, show the current code, and provide an improved version."
Step 6: Select tools (checkboxes):
[x] Read-only tools
[ ] All tools
(Or custom selection)
Step 7: Select model:
- Sonnet (balanced)
- Haiku (fast/cheap)
- Opus (most capable)
- Inherit (same as main conversation)
Step 8: Choose a background color for UI identification
Step 9: Save. Available immediately (no restart needed).
# For all your projects (user-level)
mkdir -p ~/.claude/agents
nano ~/.claude/agents/security-reviewer.md
# For the current project only
mkdir -p .claude/agents
nano .claude/agents/security-reviewer.md
Write the file content:
---
name: security-reviewer
description: Expert at security code review. Use proactively after any code changes to auth, API, or data handling modules.
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
model: sonnet
---
You are a senior security engineer specializing in identifying vulnerabilities.
When reviewing code, check for:
- SQL injection risks
- Authentication bypass potential
- Data exposure vulnerabilities
- Missing input validation
- Insecure token/session handling
- Exposed secrets or API keys
Format findings as:
- **CRITICAL**: Must fix before merge
- **WARNING**: Should fix soon
- **INFO**: Consider improving
Include specific remediation steps for each finding.
Important: Sub-agents are loaded at session start. If you create a sub-agent by manually adding a file, restart your session or use /agents to load it immediately.
For quick testing, automation scripts, or CI/CD pipelines, pass sub-agents as JSON:
claude --agents '{
"code-reviewer": {
"description": "Expert code reviewer. Use proactively after code changes.",
"prompt": "You are a senior code reviewer. Focus on code quality, security, and best practices.",
"tools": ["Read", "Grep", "Glob", "Bash"],
"model": "sonnet"
},
"test-runner": {
"description": "Runs and validates test suites.",
"prompt": "You run tests and report results. Fix failing tests when possible.",
"tools": ["Read", "Edit", "Bash", "Grep", "Glob"],
"model": "haiku"
}
}'
The --agents flag accepts the same fields as file-based sub-agents: description, prompt, tools, disallowedTools, model, permissionMode, mcpServers, hooks, maxTurns, skills, and memory. Use prompt for the system prompt (equivalent to the markdown body in file-based sub-agents).
Claude uses each sub-agent's description field to decide when to delegate. Two approaches:
Automatic delegation -- Include phrases like "use proactively" in the description:
description: Reviews code for quality. Use proactively after any code modifications.
Claude will automatically delegate to this sub-agent when it detects code has been modified.
Explicit invocation -- Ask Claude directly:
Use the security-reviewer agent to check the authentication module
Have the test-runner agent run the full test suite
| Field | Required | Type | Default | Description |
|---|---|---|---|---|
name |
Yes | string | -- | Unique identifier. Lowercase letters and hyphens only (e.g., code-reviewer). |
description |
Yes | string | -- | Tells Claude when to delegate to this sub-agent. Include "proactively" to auto-trigger. |
tools |
No | comma-separated string | Inherits all | Tools the sub-agent can use. If omitted, inherits everything from the main conversation. |
disallowedTools |
No | comma-separated string | None | Tools to deny, removed from inherited or specified list. |
model |
No | string | inherit |
sonnet, opus, haiku, or inherit. |
permissionMode |
No | string | default |
default, acceptEdits, dontAsk, bypassPermissions, or plan. |
maxTurns |
No | number | Unlimited | Maximum agentic turns before the sub-agent stops. |
skills |
No | YAML list | None | Skills to preload into the sub-agent's context at startup. |
mcpServers |
No | YAML list | None | MCP servers available to this sub-agent. |
hooks |
No | YAML object | None | Lifecycle hooks scoped to this sub-agent. |
memory |
No | string | None | user, project, or local. Enables persistent cross-session memory. |
background |
No | boolean | false |
true to always run as a background task. |
isolation |
No | string | None | worktree for git worktree isolation. |
Sub-agents can use any of Claude Code's internal tools. The most commonly used ones:
| Tool | Category | Purpose |
|---|---|---|
Read |
File | Read file contents |
Write |
File | Create or overwrite files |
Edit |
File | Make targeted edits to existing files |
Bash |
System | Run terminal commands |
Grep |
Search | Search file contents with regex |
Glob |
Search | Find files by name pattern |
Task |
Delegation | Spawn other sub-agents (main thread only) |
| MCP tools | External | Any tool provided by configured MCP servers |
Allowlist approach -- Specify exactly which tools to grant:
tools: Read, Grep, Glob
The sub-agent can ONLY use Read, Grep, and Glob. All other tools are denied.
Denylist approach -- Block specific tools while allowing everything else:
disallowedTools: Write, Edit
The sub-agent can use all tools EXCEPT Write and Edit.
Combined approach -- Specify an allowlist, then further restrict:
tools: Read, Grep, Glob, Bash
disallowedTools: Bash
This results in Read, Grep, and Glob only.
When an agent runs as the main thread with claude --agent, you can restrict which sub-agent types it can spawn:
---
name: coordinator
description: Coordinates work across specialized agents
tools: Task(worker, researcher), Read, Bash
---
This is an allowlist: only worker and researcher sub-agents can be spawned. If the agent tries to spawn any other type, the request fails.
To allow spawning any sub-agent:
tools: Task, Read, Bash
To prevent spawning any sub-agents, omit Task from the tools list entirely.
Important: This restriction only applies to agents running as the main thread with claude --agent. Sub-agents themselves cannot spawn other sub-agents regardless of configuration, so Task(agent_type) has no effect in sub-agent definitions.
| Mode | Behavior | Use Case |
|---|---|---|
default |
Standard permission checking with prompts | General use; lets you approve/deny each action |
acceptEdits |
Auto-accept file edits (still prompts for other actions) | Trusted sub-agents that need to modify code |
dontAsk |
Auto-deny permission prompts (explicitly allowed tools still work) | Strict sub-agents that should never prompt |
bypassPermissions |
Skip ALL permission checks | Fully trusted automation (use with extreme caution) |
plan |
Plan mode (read-only exploration) | Research-only sub-agents |
Permission inheritance rules:
bypassPermissions, this takes precedence and CANNOT be overridden by the sub-agent.model: sonnet # Fast, balanced -- good for code review, search
model: opus # Most capable -- good for complex reasoning
model: haiku # Fastest, cheapest -- good for simple tasks, verification
model: inherit # Same as the main conversation (default)
Cost-performance tradeoffs:
| Model | Relative Cost | Best For |
|---|---|---|
| Haiku | 1x (baseline) | Test running, linting, simple verification, copyright header updates |
| Sonnet | ~5x Haiku | Code review, debugging, data analysis, most sub-agent work |
| Opus | ~15x Haiku | Complex architecture decisions, nuanced security review |
The skills field injects full skill content into the sub-agent's context at startup. This gives domain knowledge without requiring the sub-agent to discover and load skills during execution.
---
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.
Key details:
Sub-agents can access MCP servers by name (referencing an already-configured server) or with inline definitions:
---
name: github-reviewer
description: Reviews GitHub PRs using the GitHub MCP server
mcpServers:
- github
---
Or with an inline MCP server definition:
---
name: db-analyst
description: Analyzes database contents
mcpServers:
- my-db:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-sqlite", "path/to/db.sqlite"]
---
Important: MCP tools are NOT available in background sub-agents.
Sub-agents support lifecycle hooks defined in two places:
These hooks run only while the specific sub-agent is active and are cleaned up when it finishes.
| Event | Matcher Input | When It Fires |
|---|---|---|
PreToolUse |
Tool name | Before the sub-agent uses a tool |
PostToolUse |
Tool name | After the sub-agent uses a tool |
Stop |
(none) | When the sub-agent finishes (converted to SubagentStop at runtime) |
---
name: safe-coder
description: Implements code with validation checks
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-command.sh"
timeout: 10
PostToolUse:
- matcher: "Edit|Write"
hooks:
- type: command
command: "./scripts/run-linter.sh"
timeout: 30
---
These hooks respond to sub-agent lifecycle events in the main session:
| Event | Matcher Input | When It Fires |
|---|---|---|
SubagentStart |
Agent type name | When a sub-agent begins execution |
SubagentStop |
Agent type name | When a sub-agent completes |
{
"hooks": {
"SubagentStart": [
{
"matcher": "db-agent",
"hooks": [
{ "type": "command", "command": "./scripts/setup-db-connection.sh" }
]
}
],
"SubagentStop": [
{
"hooks": [
{ "type": "command", "command": "./scripts/cleanup-db-connection.sh" }
]
}
]
}
}
Both support matchers to target specific agent types by name. Omitting the matcher matches all sub-agents.
The memory field gives the sub-agent a persistent directory that survives across conversations. The sub-agent builds up knowledge over time -- codebase patterns, debugging insights, architectural decisions.
| Scope | Storage Location | Use When |
|---|---|---|
user |
~/.claude/agent-memory/<agent-name>/ |
Knowledge applies across all your projects |
project |
.claude/agent-memory/<agent-name>/ |
Knowledge is project-specific, shareable via git |
local |
.claude/agent-memory-local/<agent-name>/ |
Project-specific, NOT in version control |
How it works:
When memory is enabled:
MEMORY.md in the memory directory are injected into context at startup.MEMORY.md if it exceeds 200 lines.Memory tips from official docs:
user is the recommended default scope. Use project or local only when knowledge is codebase-specific.Update your agent memory as you discover codepaths, patterns, library
locations, and key architectural decisions. This builds up institutional
knowledge across conversations. Write concise notes about what you found
and where.
| Aspect | Foreground | Background |
|---|---|---|
| Blocking | Blocks main conversation until complete | Runs concurrently |
| Permission prompts | Passed through to you | Pre-approved at launch; anything else auto-denied |
| Clarifying questions | Passed through to you | Fail (but sub-agent continues) |
| MCP tools | Available | NOT available |
| User control | Wait for results | Continue working; Ctrl+B to background a running task |
Setting background execution:
---
name: test-runner
background: true
---
Or ask Claude: "run this in the background."
To background a foreground sub-agent mid-execution: press Ctrl+B.
If a background sub-agent fails due to missing permissions, you can resume it in the foreground to retry with interactive prompts.
To disable all background task functionality:
export CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1
---
name: experimental-coder
description: Tries experimental approaches in an isolated copy of the repo
isolation: worktree
---
When isolation: worktree is set:
.git history as the main repo.Ask Claude to use sub-agents in sequence. Each completes its task and returns results to the main conversation, which then passes context to the next.
Use the code-reviewer agent to find performance issues in src/api/,
then use the optimizer agent to fix the top 3 issues it finds
How it works:
code-reviewer sub-agentcode-reviewer analyzes src/api/, returns findingsoptimizer sub-agent with the findings as contextoptimizer implements fixesFor independent investigations, spawn multiple sub-agents to work simultaneously:
Research the authentication, database, and API modules in parallel
using separate sub-agents
Each sub-agent explores its area independently. Claude synthesizes the findings when all return. This works best when the research paths do not depend on each other.
Warning from official docs: When sub-agents complete, their results return to your main conversation. Running many sub-agents that each return detailed results can consume significant context. For tasks that need sustained parallelism or exceed your context window, agent teams give each worker its own independent context.
One of the most effective uses for sub-agents is isolating operations that produce large amounts of output:
Use a sub-agent to run the test suite and report only the failing tests
with their error messages
The verbose test output (potentially thousands of lines) stays in the sub-agent's context. Only the relevant summary returns to your main conversation. This is valuable for:
Each sub-agent invocation normally creates a new instance with fresh context. To continue an existing sub-agent's work instead of starting over, ask Claude to resume it:
Use the code-reviewer agent to review the authentication module
[Agent completes]
Continue that code review and now analyze the authorization logic
[Claude resumes the sub-agent with full context from previous conversation]
Resumed sub-agents retain their full conversation history, including all previous tool calls, results, and reasoning. The sub-agent picks up exactly where it stopped.
Sub-agent transcripts persist at ~/.claude/projects/{project}/{sessionId}/subagents/ as agent-{agentId}.jsonl. They survive main conversation compaction and session restarts.
Sub-agents support automatic compaction using the same logic as the main conversation:
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE to a lower percentage (e.g., 50).Main conversation compaction does NOT affect sub-agent transcripts. They are stored in separate files and managed independently.
Use the main conversation when:
Use sub-agents when:
Consider Skills instead when: You want reusable prompts or workflows that run in the main conversation context rather than isolated sub-agent context.
A sub-agent that reviews code without modifying it. Limited tool access (no Edit or Write) ensures it cannot accidentally change your code.
---
name: code-reviewer
description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code.
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
model: inherit
---
You are a senior code reviewer ensuring high standards of code quality and security.
When invoked:
1. Run git diff to see recent changes
2. Focus on modified files
3. Begin review immediately
Review checklist:
- Code is clear and readable
- Functions and variables are well-named
- No duplicated code
- Proper error handling
- No exposed secrets or API keys
- Input validation implemented
- Good test coverage
- Performance considerations addressed
Provide feedback organized by priority:
- Critical issues (must fix)
- Warnings (should fix)
- Suggestions (consider improving)
Include specific examples of how to fix issues.
A sub-agent that can both analyze and fix issues. Includes Edit because fixing bugs requires modifying code.
---
name: debugger
description: Debugging specialist for errors, test failures, and unexpected behavior. Use proactively when encountering any issues.
tools: Read, Edit, Bash, Grep, Glob
model: inherit
---
You are an expert debugger specializing in root cause analysis.
When invoked:
1. Capture error message and stack trace
2. Identify reproduction steps
3. Isolate the failure location
4. Implement minimal fix
5. Verify solution works
Debugging process:
- Analyze error messages and logs
- Check recent code changes with git diff
- Form and test hypotheses
- Add strategic debug logging
- Inspect variable states
For each issue, provide:
- Root cause explanation
- Evidence supporting the diagnosis
- Specific code fix
- Testing approach
- Prevention recommendations
Focus on fixing the underlying issue, not the symptoms.
Boris Cherny's approach: after implementing a feature, run the code simplifier to clean it up.
---
name: code-simplifier
description: Simplifies and refines code for clarity, consistency, and maintainability while preserving all functionality. Use after implementation is complete.
tools: Read, Edit, Write, Grep, Glob
model: sonnet
---
You simplify code. Focus on recently modified files unless instructed otherwise.
Simplification rules:
- Remove dead code and unused imports
- Simplify complex conditionals
- Extract repeated patterns into functions
- Improve naming for clarity
- Reduce nesting depth
- Replace verbose patterns with idiomatic equivalents
- Keep all functionality intact
- Do not change public APIs
Process:
1. Run git diff --name-only to find recently modified files
2. Read each modified file
3. Identify simplification opportunities
4. Apply changes
5. Verify no functionality was lost
If unsure whether a simplification preserves behavior, skip it.
A verification sub-agent that runs the full quality pipeline and reports results.
---
name: verify-app
description: Runs full verification suite -- linting, type checking, tests, and build. Use before committing or creating PRs.
tools: Bash, Read, Grep
model: haiku
---
Run the full verification pipeline in this exact order:
1. Lint: `npm run lint`
2. Type check: `npx tsc --noEmit`
3. Tests: `npm test`
4. Build: `npm run build`
Report results as:
- PASS or FAIL for each step
- Full error output for any failures
- Summary of what needs fixing
If any step fails, still run the remaining steps so we get the complete picture.
Do not fix any issues. Only report them.
A sub-agent that allows Bash access but validates commands to permit only read-only SQL queries. Uses a PreToolUse hook for conditional validation.
---
name: db-reader
description: Execute read-only database queries for analysis and reporting. Use when analyzing data or generating reports.
tools: Bash, Read
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-readonly-query.sh"
timeout: 5
---
You are a database analyst with read-only access. Execute SELECT queries
to answer questions about the data.
When asked to analyze data:
1. Identify which tables contain the relevant data
2. Write efficient SELECT queries with appropriate filters
3. Present results clearly with context
You cannot modify data. If asked to INSERT, UPDATE, DELETE, or modify
schema, explain that you only have read access.
The companion validation script (./scripts/validate-readonly-query.sh):
#!/bin/bash
# Blocks SQL write operations, allows SELECT queries
# Read JSON input from stdin (Claude Code passes hook input as JSON)
INPUT=$(cat)
# Extract the command field from tool_input using jq
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
if [ -z "$COMMAND" ]; then
exit 0
fi
# Block write operations (case-insensitive)
if echo "$COMMAND" | grep -iE '\b(INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|TRUNCATE|REPLACE|MERGE)\b' > /dev/null; then
echo "Blocked: Write operations not allowed. Use SELECT queries only." >&2
exit 2 # Exit code 2 = block execution, send stderr as feedback
fi
exit 0
Make the script executable:
chmod +x ./scripts/validate-readonly-query.sh
A domain-specific sub-agent for data analysis work, showing how to create sub-agents for specialized workflows outside of typical coding tasks.
---
name: data-scientist
description: Data analysis expert for SQL queries, BigQuery operations, and data insights. Use proactively for data analysis tasks and queries.
tools: Bash, Read, Write
model: sonnet
---
You are a data scientist specializing in SQL and BigQuery analysis.
When invoked:
1. Understand the data analysis requirement
2. Write efficient SQL queries
3. Use BigQuery command line tools (bq) when appropriate
4. Analyze and summarize results
5. Present findings clearly
Key practices:
- Write optimized SQL queries with proper filters
- Use appropriate aggregations and joins
- Include comments explaining complex logic
- Format results for readability
- Provide data-driven recommendations
For each analysis:
- Explain the query approach
- Document any assumptions
- Highlight key findings
- Suggest next steps based on data
Always ensure queries are efficient and cost-effective.
A code reviewer that learns patterns over time and gets better with each use.
---
name: learning-reviewer
description: Code reviewer that learns project patterns over time. Use proactively after code changes.
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
model: sonnet
memory: project
---
You are a code reviewer who learns and remembers project patterns.
Before reviewing:
1. Check your agent memory for known patterns and past findings
2. Apply project-specific knowledge from previous reviews
During review:
1. Look for violations of established patterns
2. Check for recurring issues you have seen before
3. Evaluate code quality, security, and maintainability
After review:
1. Update your agent memory with new patterns discovered
2. Note any recurring issues for future reference
3. Record architectural decisions you observed
Update your agent memory as you discover codepaths, patterns, library
locations, and key architectural decisions. This builds institutional
knowledge across conversations.
To prevent Claude from using specific sub-agents, add them to the deny array in settings:
{
"permissions": {
"deny": ["Task(Explore)", "Task(my-custom-agent)"]
}
}
Or via CLI:
claude --disallowedTools "Task(Explore)"
Agent Teams is an experimental Claude Code feature that enables multiple Claude Code instances to work together as a coordinated team. Unlike sub-agents (which run within a single session and report back to the main agent), agent teams are fully independent sessions that communicate with each other through a shared task list and messaging system.
SUB-AGENTS (Part A):
Main Session
|
+-- sub-agent A (works, returns results to main)
+-- sub-agent B (works, returns results to main)
(A and B never talk to each other)
AGENT TEAMS (Part B):
Team Lead Session
|
+-- Teammate A ---+
+-- Teammate B ---+--- Shared Task List + Direct Messaging
+-- Teammate C ---+
(A, B, and C communicate with each other directly)
Agent teams use significantly more tokens than a single session. They are worth it when:
| Scenario | Why Agent Teams Help |
|---|---|
| Research and review | Multiple teammates investigate different aspects simultaneously, then share and challenge findings |
| New modules or features | Teammates each own a separate piece without stepping on each other |
| Debugging with competing hypotheses | Teammates test different theories in parallel and converge faster |
| Cross-layer coordination | Changes spanning frontend, backend, and tests, each owned by a different teammate |
| Large migrations | Multiple teammates handle different directories/modules in parallel |
| Content analysis | Multiple teammates analyze different dimensions of large datasets |
| Scenario | Better Approach |
|---|---|
| Sequential tasks with dependencies | Single session or chained sub-agents |
| Same-file edits | Single session (avoid merge conflicts) |
| Quick bug fix | Solo Claude Code |
| Simple, single-layer feature | Solo Claude Code |
| Tasks that need frequent human iteration | Solo Claude Code |
| Routine tasks | Single session (lower token cost) |
Agent teams are disabled by default. Enable them by setting the environment variable.
# Edit your global settings
nano ~/.claude/settings.json
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
Or at the project level in .claude/settings.json:
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
# For current session
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
# Permanent (add to ~/.zshrc or ~/.bashrc)
echo 'export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1' >> ~/.zshrc
source ~/.zshrc
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"teammateMode": "auto",
"permissions": {
"allow": [
"Bash(npm run test)",
"Bash(npm run lint)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)"
]
}
}
# Start Claude and ask it to create a team
claude
> Create a team called "test-team" and verify agent teams are working
If agent teams are not enabled, Claude will not have access to TeamCreate, SendMessage, or the other team primitives.
When Claude spawns teammates, they need somewhere to run. There are two display modes, controlled by teammateMode:
{
"teammateMode": "in-process"
}
{
"teammateMode": "tmux"
}
{
"teammateMode": "auto"
}
# Override for a single session
claude --teammate-mode in-process
claude --teammate-mode tmux
| Terminal | Requirement |
|---|---|
| tmux | Install via package manager (brew install tmux on macOS) |
| iTerm2 | Install it2 CLI, enable Python API in iTerm2 > Settings > General > Magic > Enable Python API |
| VS Code integrated terminal | NOT supported for split panes |
| Windows Terminal | NOT supported for split panes |
| Ghostty | NOT supported for split panes (use in-process mode) |
An agent team consists of four components:
| Component | Role |
|---|---|
| Team Lead | The main Claude Code session. Creates the team, spawns teammates, coordinates work, synthesizes results. |
| Teammates | Separate Claude Code instances. Each has its own context window, works on assigned tasks, communicates with peers. |
| Task List | Shared list of work items. Teammates claim tasks, update status, and track dependencies. |
| Mailbox | Messaging system for inter-agent communication. Supports direct messages, broadcasts, shutdown requests. |
Two entry points:
In both cases, you stay in control. Claude will not create a team without your approval.
Teams and tasks are stored locally:
~/.claude/
teams/
my-team/
config.json # Team membership & metadata
tasks/
my-team/
1.json # Task 1
2.json # Task 2
3.json # Task 3
.lock # File-locking for race conditions
Team config.json structure:
{
"name": "my-team",
"leadAgentId": "lead-abc123",
"leadSessionId": "session-xyz789",
"createdAt": "2026-02-20T10:00:00Z",
"members": [
{
"name": "researcher",
"agentId": "agent-def456",
"agentType": "general-purpose"
},
{
"name": "implementer",
"agentId": "agent-ghi789",
"agentType": "general-purpose"
}
]
}
Individual task JSON structure:
{
"id": "1",
"subject": "Research API requirements",
"description": "Investigate third-party APIs needed for integration",
"status": "pending",
"owner": "researcher",
"dependencies": [],
"createdAt": "2026-02-20T10:00:00Z",
"completedAt": null
}
--dangerously-skip-permissions, all teammates do too.When spawned, a teammate loads the same project context as a regular session:
It also receives the spawn prompt from the lead. The lead's conversation history does NOT carry over. This is a fresh context.
Agent teams are built on seven fundamental tools that Claude uses internally. You do not call these directly; you tell Claude what you want in natural language and it uses the appropriate primitives.
Creates a team with a shared task list.
TeamCreate({
team_name: "my-feature",
description: "Implementing user authentication"
})
~/.claude/teams/my-feature/config.json~/.claude/tasks/my-feature/ directoryAdds tasks to the team's shared backlog.
TaskCreate({
title: "Implement login API endpoint",
description: "Create POST /api/auth/login with JWT tokens",
priority: "high"
})
Tasks start in pending status with no owner.
Updates task status, assigns owners, marks completion.
TaskUpdate({
task_id: "task-1",
status: "completed",
owner: "backend-dev"
})
Views all tasks and their current status.
TaskList() // Returns all tasks with status, owner, dependencies, etc.
Spawns a new teammate agent. This is the same Task tool used for sub-agents, but with the team_name parameter to make it a team member.
Task({
prompt: "Implement the REST API for user authentication",
subagent_type: "general-purpose",
team_name: "my-feature",
name: "backend-dev"
})
Enables inter-agent communication. Four message types:
// Direct message to one agent
SendMessage({
type: "message",
recipient: "backend-dev",
content: "The API schema has changed, please update endpoints",
summary: "API schema update notification"
})
// Message to ALL agents (use sparingly -- expensive)
SendMessage({
type: "broadcast",
content: "API v2 schema is finalized, all teams proceed",
summary: "API schema finalized"
})
// Ask an agent to shut down gracefully
SendMessage({
type: "shutdown_request",
recipient: "researcher",
content: "Research phase complete, wrapping up"
})
// Agent responds to shutdown request
SendMessage({
type: "shutdown_response",
request_id: "abc-123",
approve: true
})
Cleans up team resources when work is complete.
TeamDelete() // Removes team config and task directories
Important: Always use the lead to clean up. Teammates should not run cleanup because their team context may not resolve correctly.
Phase 1: SETUP
1. TeamCreate("my-team") -- Create team + task list
2. TaskCreate(title, description) -- Define work items (repeat for each task)
Phase 2: SPAWN
3. Task(prompt, team_name, name) -- Create specialized agents (repeat for each teammate)
Phase 3: ASSIGN
4. TaskUpdate(task_id, owner) -- Assign tasks to agents
(Or teammates self-claim unassigned tasks)
Phase 4: WORK
5. Teammates work independently -- Read/write code, run tests, etc.
6. SendMessage(recipient, content) -- Coordinate between agents as needed
Phase 5: COMPLETE
7. TaskUpdate(task_id, "completed") -- Mark tasks done
8. Team lead synthesizes results
Phase 6: CLEANUP
9. SendMessage(shutdown_request) -- Wind down each teammate
10. TeamDelete() -- Clean up team resources
The team lead creates the team and defines the task backlog. This is planning time. Before spawning agents, the lead should understand the full scope of work.
Best practice: Have Claude plan the work FIRST (using Plan Mode), then create the team based on the plan.
The lead spawns teammates with specific prompts. Each spawn prompt should include:
Two approaches:
Task claiming uses file locking to prevent race conditions.
Teammates work independently. Communication happens via:
Tasks have three states:
pending -- Not yet startedin_progress -- Being worked oncompleted -- DoneTasks can depend on other tasks. A pending task with unresolved dependencies cannot be claimed until those dependencies are completed. The system manages this automatically.
Always shut down teammates before deleting the team. The lead sends shutdown_request to each teammate. Each can approve (exit gracefully) or reject with an explanation. Once all teammates are shut down, TeamDelete() removes team resources.
Tell Claude what team you want in natural language:
Create a team called "auth-feature" with the following agents:
1. "architect" - Plans the implementation and reviews code
2. "backend-dev" - Implements API endpoints and database models
3. "frontend-dev" - Implements UI components and state management
4. "tester" - Writes and runs tests
Tasks:
1. Design auth system architecture (architect)
2. Implement JWT token service (backend-dev)
3. Create login/signup UI (frontend-dev)
4. Write integration tests (tester)
Create a team with 4 teammates to refactor these modules in parallel.
Use Sonnet for each teammate.
| Agent Type | Tools Available | Best For |
|---|---|---|
general-purpose |
All tools (read, write, edit, bash, etc.) | Implementation work |
Explore |
Read-only (glob, grep, read) | Research, code exploration |
Plan |
Read-only | Architecture planning |
Bash |
Bash commands only | Running tests, builds |
Custom agents in .claude/agents/ |
As configured | Specialized roles |
For complex or risky tasks, require teammates to plan before implementing:
Spawn an architect teammate to refactor the authentication module.
Require plan approval before they make any changes.
The teammate works in read-only plan mode until the lead approves:
Influence approval criteria: "only approve plans that include test coverage" or "reject plans that modify the database schema."
Each teammate is a full, independent Claude Code session. You can interact directly:
In-process mode:
Split-pane mode:
in_progress per agent at a time.shutdown_request, do not just kill processes.| State | Meaning |
|---|---|
pending |
Not yet started. Available for claiming (if no unresolved dependencies). |
in_progress |
Being worked on by an assigned teammate. |
completed |
Done. Dependent tasks may now unblock. |
Tasks can depend on other tasks. A pending task with unresolved dependencies cannot be claimed until those dependencies are completed. The system manages unblocking automatically.
Tasks:
1. Design API schema (architect) -- no dependencies
2. Implement endpoints (backend-dev) -- depends on task 1
3. Write integration tests (tester) -- depends on task 2
4. Update documentation (doc-writer) -- depends on task 1
In this example, tasks 2 and 4 both depend on task 1. Task 3 depends on task 2. The system ensures:
.lock file in the tasks directory) to prevent race conditions when multiple teammates try to claim the same task.From the official docs:
Aim for 5-6 tasks per teammate to keep everyone productive and let the lead reassign work if someone gets stuck.
| Type | Recipient | Cost | Use When |
|---|---|---|---|
message |
One specific teammate | 1 message | Normal coordination, follow-ups, redirects |
broadcast |
ALL teammates | N messages (one per teammate) | Critical team-wide updates ONLY |
shutdown_request |
One specific teammate | 1 message | Asking a teammate to stop gracefully |
shutdown_response |
The requester | 1 message | Teammate approving or rejecting shutdown |
plan_approval_request |
Team lead | 1 message | Teammate submitting a plan for approval |
plan_approval_response |
One teammate | 1 message | Lead approving or rejecting a plan |
SendMessage({
type: "message",
recipient: "backend-dev",
content: "The API schema has changed. The /users endpoint now returns
a 'roles' array instead of a single 'role' string. Please
update your implementation.",
summary: "API schema change notification"
})
Messages are delivered automatically. The recipient does not need to poll for updates.
SendMessage({
type: "broadcast",
content: "STOP: Critical bug found in the auth module. Do not merge
any code until further notice.",
summary: "Critical blocking issue found"
})
Use broadcasts sparingly. Each broadcast sends N messages (one per teammate). With 5 teammates, one broadcast = 5 separate messages. Cost scales linearly with team size.
Valid broadcast scenarios:
For everything else, use direct message to specific teammates.
# Lead sends shutdown request
SendMessage({
type: "shutdown_request",
recipient: "researcher",
content: "Research phase complete, wrapping up"
})
# Teammate can approve (exits gracefully)
SendMessage({
type: "shutdown_response",
request_id: "abc-123",
approve: true
})
# Or reject with explanation
SendMessage({
type: "shutdown_response",
request_id: "abc-123",
approve: false,
content: "Still working on task #3, need 5 more minutes"
})
Teammates finish their current request or tool call before shutting down, which can take time.
When a teammate finishes working and goes idle, it automatically notifies the lead. This is normal behavior, not an error. The lead can then:
Agent teams have two special hooks beyond the standard ones: TeammateIdle and TaskCompleted.
Fires when a teammate is about to go idle. Use exit code 2 to block idling and send feedback.
Input (JSON via stdin):
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../transcript.jsonl",
"cwd": "/Users/your-project",
"permission_mode": "default",
"hook_event_name": "TeammateIdle",
"teammate_name": "researcher",
"team_name": "my-project"
}
Example hook script:
#!/bin/bash
# ./scripts/check-teammate-done.sh
INPUT=$(cat)
TEAMMATE=$(echo "$INPUT" | jq -r '.teammate_name')
# Check if the teammate actually finished their work
if [ ! -f "./output/${TEAMMATE}-done.txt" ]; then
echo "You haven't completed your task yet. Check the task list." >&2
exit 2 # Exit code 2 = block idle, send stderr as feedback
fi
exit 0 # Allow idle
Configure in settings.json:
{
"hooks": {
"TeammateIdle": [
{
"hooks": [
{
"type": "command",
"command": "./scripts/check-teammate-done.sh",
"timeout": 10
}
]
}
]
}
}
Fires when a task is being marked complete. Use exit code 2 to block completion.
Input (JSON via stdin):
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../transcript.jsonl",
"cwd": "/Users/your-project",
"permission_mode": "default",
"hook_event_name": "TaskCompleted",
"task_id": "task-001",
"task_subject": "Implement authentication",
"task_description": "Add login/signup endpoints",
"teammate_name": "backend-dev",
"team_name": "my-project"
}
Example hook script:
#!/bin/bash
# ./scripts/validate-task-completion.sh
INPUT=$(cat)
TASK=$(echo "$INPUT" | jq -r '.task_subject')
# Require tests to pass before marking complete
if ! npm test 2>&1; then
echo "Tests must pass before completing: $TASK" >&2
exit 2 # Block completion, send feedback
fi
exit 0 # Allow completion
Configure in settings.json:
{
"hooks": {
"TaskCompleted": [
{
"hooks": [
{
"type": "command",
"command": "./scripts/validate-task-completion.sh",
"timeout": 120,
"statusMessage": "Running tests before task completion..."
}
]
}
]
}
}
| Exit Code | Behavior |
|---|---|
| 0 | Allow the action (idle / task completion proceeds) |
| 1 | Hook failed (logged, but action still proceeds) |
| 2 | Block the action AND send stderr as feedback to the agent |
tmux is a terminal multiplexer. It lets you split your terminal into multiple panes, each running its own process. For agent teams, each teammate gets its own visible pane so you can see all agents working simultaneously.
# macOS
brew install tmux
# Ubuntu/Debian
sudo apt install tmux
# Verify
tmux -V
# Start a new named session
tmux new -s claude-swarm
# Launch Claude inside the tmux session
claude
# Now when Claude spawns teammates, each gets its own pane
All tmux commands start with the prefix key: Ctrl+b (press Ctrl+b, release, then press the command key).
| Action | Keys | Description |
|---|---|---|
| Split horizontal | Ctrl+b " |
New pane below |
| Split vertical | Ctrl+b % |
New pane to the right |
| Navigate panes | Ctrl+b Arrow |
Move between panes |
| Resize pane | Ctrl+b Ctrl+Arrow |
Grow/shrink current pane |
| Zoom pane | Ctrl+b z |
Toggle fullscreen for current pane |
| Kill pane | Ctrl+b x |
Close current pane |
| Detach session | Ctrl+b d |
Leave session running in background |
| List sessions | tmux ls |
Show all sessions |
| Reattach | tmux attach -t claude-swarm |
Reconnect to session |
| Scroll mode | Ctrl+b [ |
Enter scroll mode (q to exit) |
Create or edit ~/.tmux.conf:
# Better prefix (Ctrl+a instead of Ctrl+b)
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Mouse support (click to select panes, scroll)
set -g mouse on
# Easier splits (| and - instead of % and ")
bind | split-window -h
bind - split-window -v
# Start window numbering at 1
set -g base-index 1
setw -g pane-base-index 1
# Larger scrollback buffer
set -g history-limit 50000
# Status bar with session info
set -g status-style 'bg=#333333 fg=#5eacd3'
set -g status-left '#[fg=green]Session: #S '
set -g status-right '#[fg=yellow]Panes: #{window_panes} '
# Pane border colors for visibility
set -g pane-border-style fg=colour240
set -g pane-active-border-style fg=green
# Don't rename windows automatically
set -g allow-rename off
# Reload config
bind r source-file ~/.tmux.conf \; display "Config reloaded!"
After editing, reload:
tmux source-file ~/.tmux.conf
If using iTerm2, tmux control mode provides native tab/pane integration:
tmux -CC new -s claude-swarm
This makes tmux panes appear as native iTerm2 split panes with full mouse support, native scrollback, and normal copy/paste.
Note from official docs: tmux -CC in iTerm2 is the suggested entry point into tmux.
tmux can notify you when output changes in a pane:
# In tmux, enter command mode: Ctrl+b :
setw monitor-activity on
set -g visual-activity on
This highlights the pane in your status bar when new output appears -- useful for knowing when a teammate has completed work or encountered an error.
If a tmux session persists after the team ends:
# List all sessions
tmux ls
# Kill a specific session
tmux kill-session -t claude-swarm
The number one mistake is jumping straight into spawning agents. Instead:
"Work on the frontend"
This is too vague. The agent does not know where to start, what files to modify, or what "done" looks like.
"Implement the login form component at src/components/auth/LoginForm.tsx.
Requirements:
- Email and password fields with validation
- Submit button that calls POST /api/auth/login
- Error message display for invalid credentials
- Redirect to /dashboard on success
- Use the existing Button and Input components from src/components/ui/
- Follow the styling patterns in src/styles/auth.css
- Do NOT modify any files outside of src/components/auth/
When done, run: npm test -- --testPathPattern=auth"
For every agent prompt, include these five elements:
| Element | Description | Example |
|---|---|---|
| Scope | What files/directories does this agent own? | "Work only in src/components/auth/" |
| Purpose | What should the agent accomplish? | "Implement the login form with email/password fields" |
| Existing patterns | What conventions should it follow? | "Follow the styling patterns in src/styles/auth.css" |
| Constraints | What should the agent NOT do? | "Do NOT modify any files outside of src/components/auth/" |
| Verification | How does the agent verify its work? | "Run: npm test -- --testPathPattern=auth" |
| Boundaries | What boundaries exist between this agent and others? | "The backend-dev is handling the API endpoint; just call it" |
All agents in a team share the same CLAUDE.md files. Use this to establish universal conventions:
# CLAUDE.md (project root)
## Team Conventions
- All API endpoints follow RESTful patterns
- Use TypeScript strict mode
- Tests go in __tests__/ directories next to source files
- Branch naming: feature/TICKET-description
- Commit messages: type(scope): description
## Current Sprint Context
- Working on: User Authentication (Sprint 14)
- API base URL: /api/v2
- Database: PostgreSQL with Prisma ORM
For complex multi-agent work, store context in individual files rather than trying to maintain it across long conversations:
project/
.claude/
context/
architecture-decisions.md
api-schema.md
ui-components.md
test-strategy.md
Each agent reads only the context files relevant to their work, preventing "context rot" (degraded output quality as conversations grow long).
The most effective pattern is having a team lead that:
The lead should NOT do implementation work itself. Its job is coordination.
Use when: Building a feature that spans multiple layers (API, UI, tests, docs).
Team: "user-auth"
Agents:
- backend-dev: Implements API endpoints and DB models
- frontend-dev: Builds UI components and state management
- test-writer: Creates unit and integration tests
- doc-writer: Updates API docs and README
Task Dependencies:
1. backend-dev: Create API endpoints (no dependencies)
2. frontend-dev: Build login UI (depends on API schema, not implementation)
3. test-writer: Write tests (starts after backend, tests as code lands)
4. doc-writer: Update docs (starts after API design is stable)
Key insight: The frontend dev can start with the API schema even before the backend is implemented. Give it a sample response shape so it can build against a contract.
Use when: A bug could have multiple causes and you want to investigate all of them simultaneously.
Team: "bug-hunt"
Agents:
- investigator-1: "Check if the issue is in the auth middleware"
- investigator-2: "Check if the issue is in the database query layer"
- investigator-3: "Check if the issue is in the frontend state management"
Each agent investigates independently and reports findings.
The team lead synthesizes results and identifies the root cause.
Key insight from official docs: A single agent tends to find one plausible explanation and stop looking. Making teammates explicitly adversarial ("try to disprove each other's theories, like a scientific debate") overcomes anchoring bias.
Spawn 5 agent teammates to investigate different hypotheses. Have them
talk to each other to try to disprove each other's theories, like a
scientific debate. Update the findings doc with whatever consensus emerges.
Use when: Reviewing a large codebase or many files at once.
Team: "code-review"
Agents:
- security-reviewer: Focus on auth, input validation, data exposure
- perf-reviewer: Focus on N+1 queries, memory leaks, bundle size
- style-reviewer: Focus on naming, patterns, consistency
- test-reviewer: Focus on test coverage, edge cases, flaky tests
Key insight: A single reviewer gravitates toward one type of issue at a time. Splitting review criteria into independent domains means security, performance, and test coverage all get thorough attention simultaneously.
Use when: Changing a pattern across many files.
Team: "migrate-to-v2"
Agents:
- migrator-1: Handle files in src/components/
- migrator-2: Handle files in src/pages/
- migrator-3: Handle files in src/utils/
- verifier: Run tests after each batch of changes
Key: Each agent owns a distinct directory -- no file conflicts.
Use when: You need to research before implementing, but can parallelize both.
Team: "new-feature"
Agents:
- researcher (Explore type): Research existing patterns, find relevant code
- architect (Plan type): Design the implementation based on research
- implementer (general-purpose): Build once the plan is approved
- tester (general-purpose): Write tests based on the design
Use when: Analyzing large amounts of content.
Real-world example from perrotta.dev: 4 agents analyzed a 1,041-post blog in 5 minutes 17 seconds using ~239k tokens:
Each agent produced a focused report. The team lead synthesized into a comprehensive analysis.
Problem: Spawning 10+ agents for a simple task.
Why it fails: Coordination overhead exceeds parallelism benefits. More agents = more token cost. More agents = more messages = more context consumed by coordination.
Rule of thumb: 2-5 agents is the sweet spot. Start with fewer and add more only if there is clear parallelism benefit.
Problem: Multiple agents modifying the same file simultaneously.
Why it fails: Merge conflicts, lost changes, inconsistent state. One agent's edit overwrites another's.
Solution: Assign clear file ownership. Use git worktrees for true isolation. Or structure work so each agent owns a distinct directory.
Problem: "Work on the backend" or "Fix bugs."
Why it fails: Agents do not know where to start, overlap with each other, or miss requirements.
Solution: Use the SPECVB template. Specific files, specific requirements, specific verification steps.
Problem: Agents mark tasks "done" without running tests.
Why it fails: Broken code accumulates, integration failures compound.
Solution: Every task prompt should end with "verify by running..." Use TaskCompleted hooks to enforce test passes before completion.
Problem: Using broadcast messages for all communication.
Why it fails: Each broadcast sends N messages (one per agent). With 5 agents, every broadcast costs 5 messages. Expensive and noisy.
Solution: Use direct message to specific agents. Reserve broadcast for critical team-wide updates only.
Problem: Spawning agents and letting them figure things out.
Why it fails: No one resolves conflicts, manages dependencies, or handles integration.
Solution: Always have a team lead that orchestrates the work. The lead should coordinate, not implement.
Problem: Immediately spawning agents without understanding the codebase.
Why it fails: Agents work on the wrong things, create incompatible implementations, or duplicate effort.
Solution: Plan Mode first. Understand the codebase. Define tasks. Then parallelize.
Problem: The team lead starts implementing tasks instead of waiting for teammates.
Why it fails: The lead is supposed to coordinate, not compete with teammates. When it implements, it loses track of what teammates are doing.
Solution: Tell the lead: "Wait for your teammates to complete their tasks before proceeding."
Problem: Two teammates both told to "optimize the API" without specific file boundaries.
Why it fails: They step on each other's work, create conflicting changes.
Solution: Define non-overlapping scopes: "Teammate A handles src/routes/, Teammate B handles src/middleware/."
Agent teams are experimental. Current limitations from the official documentation:
| Limitation | Description | Workaround |
|---|---|---|
| No session resumption with in-process teammates | /resume and /rewind do not restore in-process teammates. After resuming, the lead may try to message teammates that no longer exist. |
Tell the lead to spawn new teammates after resuming. |
| Task status can lag | Teammates sometimes fail to mark tasks as completed, blocking dependent tasks. | Check if work is actually done; manually update status or tell the lead to nudge. |
| Shutdown can be slow | Teammates finish their current request/tool call before shutting down. | Be patient; do not force-kill. |
| One team per session | A lead can only manage one team at a time. | Clean up the current team before starting a new one. |
| No nested teams | Teammates cannot spawn their own teams or teammates. Only the lead can manage the team. | Use the lead for all team management. |
| Lead is fixed | The session that creates the team is the lead for its lifetime. Cannot promote a teammate. | Plan leadership before creating the team. |
| Permissions set at spawn | All teammates start with the lead's permission mode. Per-teammate modes can only be changed after spawning. | Pre-approve common operations in permission settings. |
| Split panes limited | Split-pane mode is NOT supported in VS Code integrated terminal, Windows Terminal, or Ghostty. | Use in-process mode or install tmux/iTerm2. |
| Token cost | Each teammate is a separate Claude instance with its own context window. Costs scale linearly. | Start with fewer agents; use Haiku for simple tasks. |
| Dimension | Sub-Agents | Agent Teams |
|---|---|---|
| Session model | Run within the main session. Results return to the caller's context. | Each teammate is a fully independent Claude Code session. |
| Context window | Own context window, but results are injected back into the main conversation. | Own context window, fully independent. Results do NOT return to the lead's context. |
| Spawning | Main conversation spawns sub-agents. Sub-agents cannot spawn other sub-agents. | Lead spawns teammates. Teammates cannot spawn teams or additional teammates. |
| Communication | One-way: sub-agent works, returns results to main conversation. Sub-agents never talk to each other. | Multi-way: teammates message each other directly via SendMessage. Shared task list for coordination. |
| Coordination | Main agent manages all work. No shared task list. | Shared task list with self-coordination. Teammates can self-claim tasks. |
| Display | Background tasks or foreground blocking. No separate panes. | In-process (Shift+Down cycling) or split panes (tmux/iTerm2). |
| Dimension | Sub-Agents | Agent Teams |
|---|---|---|
| Token cost | Lower. Results are summarized back to main context. One context window for the main conversation + temporary windows for sub-agents. | Higher. Each teammate is a separate Claude instance. N teammates = roughly N times the cost. |
| Coordination overhead | Minimal. No inter-agent messaging. | Significant. Task list management, message passing, idle/shutdown protocol. |
| Latency | Sub-agent starts fresh but returns results to existing conversation. | Each teammate starts fresh with project context (CLAUDE.md, MCP, skills) but NOT the lead's conversation history. |
| Context pressure | Sub-agent results compress into main context. Many sub-agents with detailed results can fill context. | No context pressure on the lead. Each teammate manages its own context independently. |
| Dimension | Sub-Agents | Agent Teams |
|---|---|---|
| Inter-worker communication | Not possible. Sub-agents are isolated from each other. | Direct messaging, broadcasts, plan approval requests/responses. |
| Task dependencies | Manual. You chain sub-agents sequentially from the main conversation. | Automatic. Task system manages dependencies and unblocking. |
| Persistence | Sub-agent transcripts persist in ~/.claude/projects/. Can be resumed. |
Team config and tasks persist in ~/.claude/teams/ and ~/.claude/tasks/. No session resumption for in-process teammates. |
| File isolation | Optional worktree isolation (isolation: worktree). |
Teammates share the same working directory by default. Use git worktrees or distinct directory ownership for isolation. |
| Memory | Persistent memory across sessions (user/project/local scope). | No built-in persistent memory for teammates (they are ephemeral sessions). |
| Hooks | PreToolUse, PostToolUse, Stop (in frontmatter). SubagentStart, SubagentStop (in settings.json). | TeammateIdle, TaskCompleted (in settings.json). Standard hooks also apply. |
| MCP servers | Available in foreground sub-agents. NOT available in background sub-agents. | Available to teammates (they load project MCP config). |
| Background execution | Supported. Sub-agents can run concurrently while you keep working. | Teammates always run independently (they are inherently "background" from the lead's perspective). |
| Scenario | Sub-Agents | Agent Teams | Why |
|---|---|---|---|
| Run tests and report failures | Best | Overkill | Simple, isolated task. No inter-worker communication needed. |
| Explore codebase structure | Best | Overkill | Read-only research. Explore sub-agent is built for this. |
| Review code after changes | Best | Good | Single-focus task. Sub-agent with read-only tools is ideal. |
| Debug a mystery bug | Good | Best | Competing hypotheses benefit from agents challenging each other. |
| Cross-layer feature (API + UI + tests) | Possible (chained) | Best | Multiple independent workers in different areas. Communication helps. |
| Large refactor across many files | Possible | Best | Parallel work across directories. Shared task list keeps track. |
| Content analysis (many documents) | Good | Best | Parallel analysis of independent data. Agent teams shine here. |
| Quick verification (lint, build) | Best | Overkill | Fast, cheap task. Use Haiku sub-agent. |
| Research multiple topics in parallel | Good | Good | Both work. Sub-agents if no inter-topic communication needed. Agent teams if researchers should share findings. |
Yes. Teammates in an agent team can use sub-agents. A teammate is a full Claude Code session, so it can spawn Explore, Plan, or custom sub-agents for its own work. The sub-agents report back to the teammate (not the team lead).
Lead
|
+-- Teammate A (has own sub-agents)
| |
| +-- Explore sub-agent (searches codebase for Teammate A)
| +-- code-reviewer sub-agent (reviews Teammate A's changes)
|
+-- Teammate B (has own sub-agents)
|
+-- test-runner sub-agent (runs tests for Teammate B)
This is the most powerful pattern for complex work, but also the most expensive in terms of tokens.
Use this flowchart to decide which approach to take:
START: What kind of task?
|
+-- Single, focused task (review, test, explore)?
| |
| +-- YES --> Use a SUB-AGENT
| |
| +-- Read-only? --> Explore sub-agent (built-in)
| +-- Needs verification? --> verify-app sub-agent (custom)
| +-- Quick/cheap? --> Set model: haiku
| +-- Heavy output? --> Sub-agent isolates it from your context
|
+-- Multiple independent tasks that don't need communication?
| |
| +-- YES --> Use PARALLEL SUB-AGENTS (or Boris's tmux pattern)
| |
| +-- Each sub-agent gets a different task
| +-- Results return to main conversation
| +-- Main conversation synthesizes
|
+-- Multiple tasks that need coordination/communication?
| |
| +-- YES --> Use an AGENT TEAM
| |
| +-- Workers need to share findings? --> Agent Team
| +-- Workers need to challenge each other? --> Agent Team
| +-- Shared task list with dependencies? --> Agent Team
| +-- Cross-layer work (API + UI + tests)? --> Agent Team
|
+-- Sequential tasks that build on each other?
| |
| +-- YES --> Use CHAINED SUB-AGENTS
| |
| +-- Sub-agent A works, returns results
| +-- Main conversation passes context to sub-agent B
| +-- Sub-agent B works, returns results
|
+-- Unsure?
|
+-- Start with a single session or sub-agent
+-- Scale up to agent team only if you see clear parallelism
Goal: Create a read-only code reviewer sub-agent and use it.
Steps:
/agents in Claude CodeVerification: The sub-agent should analyze code without modifying any files. Check that Write and Edit are not available to it.
Goal: Create a verify-app sub-agent (Boris style) and chain it with implementation.
Steps:
~/.claude/agents/verify-app.md:---
name: verify-app
description: Runs full verification suite. Use before committing.
tools: Bash, Read, Grep
model: haiku
---
Run the full verification pipeline:
1. Lint: `npm run lint` (or equivalent)
2. Type check: `npx tsc --noEmit` (if TypeScript)
3. Tests: `npm test`
4. Build: `npm run build`
Report PASS/FAIL for each step with error details.
Do not fix any issues. Only report them.
Verification: The sub-agent should run all four checks and report results without modifying files.
Goal: Use multiple sub-agents to research different parts of a codebase simultaneously.
Steps:
Verification: Each sub-agent should explore its assigned module independently. Results should be consolidated in your main conversation.
Goal: Create a sub-agent that validates commands before execution using a PreToolUse hook.
Steps:
./scripts/validate-readonly-query.sh (from Example 5 above)chmod +x ./scripts/validate-readonly-query.sh.claude/agents/db-reader.md with the hook configurationVerification: SELECT queries should execute. INSERT/UPDATE/DELETE should be blocked with an error message.
Goal: Set up agent teams and run a basic research team.
Steps:
~/.claude/settings.json:{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"teammateMode": "auto"
}
Verification: Three teammates should spawn, each analyzing a different dimension. The lead should synthesize their findings.
Goal: Run an agent team with visible split panes.
Steps:
brew install tmux{
"teammateMode": "tmux"
}
tmux new -s claude-swarmCtrl+b ArrowCtrl+b zVerification: Each teammate should appear in its own tmux pane. You should be able to navigate between them and see their output in real-time.
Goal: Use agent teams to investigate a bug from multiple angles simultaneously.
Steps:
Create a team to investigate why [describe the bug]. Spawn three
investigators, each testing a different hypothesis:
1. Check if the issue is in [component A]
2. Check if the issue is in [component B]
3. Check if the issue is in [component C]
Have them share findings with each other and try to disprove
each other's theories.
Verification: Each investigator should explore a different theory. They should communicate findings and converge on a root cause.
Goal: Combine sub-agents and agent teams in a realistic workflow.
Steps:
code-simplifier, verify-app, code-reviewerPhase 1 (Agent Team):
"Create a team to implement [feature]. Spawn teammates for API,
UI, and tests. Each teammate should own its own directory."
Phase 2 (Sub-Agent - each teammate):
Each teammate uses code-simplifier sub-agent to clean up its code
Phase 3 (Sub-Agent):
"Use verify-app to run the full verification suite"
Phase 4 (Sub-Agent):
"Use code-reviewer to review all changes from this session"
Verification: The workflow should demonstrate agent teams for parallel implementation and sub-agents for focused verification and review tasks.
Boris Cherny is an engineer at Anthropic who works on Claude Code. His parallel workflow is one of the most productive publicly documented.
Each Claude instance gets a different tab color. This lets you quickly identify which instance is working on which task at a glance. In Ghostty, this is a built-in feature. In iTerm2, you can set tab colors via the profile settings.
All instances share the same project CLAUDE.md, so they follow the same conventions. This is your source of truth for coding standards, patterns, and project context.
/commit-push-pr -- Commits, pushes, and creates a PR in one step
Boris creates custom slash commands for actions he performs multiple times per day.
Boris uses two critical sub-agents:
code-simplifier -- Runs after implementation to clean up codeverify-app -- Runs before every commit/PR to catch issuesThese are not optional extras. They are part of every single workflow.
Boris uses /permissions to set Bash(execute:*) so Claude can run any command without asking for permission each time. This removes friction during implementation.
Boris goes back and forth with Claude in Plan Mode until the plan is solid, then switches to implementation. This prevents wasted effort on wrong approaches.
Boris prefers clean sequential commits over amending. Each commit represents a logical step, making it easy to review changes.
1. Start 5 Claude terminals (color-coded)
2. Open Plan Mode in each with a different task
3. Review and approve each plan
4. Let all 5 implement in parallel
5. Review PRs as they come in
6. Use code-simplifier sub-agent for cleanup
7. Run verify-app before merging
You do not need the experimental agent teams feature to run parallel Claudes. Boris's approach works with plain tmux or multiple terminal tabs:
# Create a 5-pane tmux layout
tmux new-session -s work -d
tmux split-window -h
tmux split-window -v
tmux select-pane -t 0
tmux split-window -v
tmux select-pane -t 2
tmux split-window -v
tmux attach -t work
# In each pane, start Claude with a specific task
# The panes are independent -- no shared task list or messaging
# You manually coordinate by reading each pane's output
The difference between this approach and agent teams:
Boris's approach is simpler, more predictable, and does not require the experimental feature flag. Agent teams add automation to the coordination layer.
| Topic | URL |
|---|---|
| Sub-Agents | https://code.claude.com/docs/en/sub-agents |
| Agent Teams | https://code.claude.com/docs/en/agent-teams |
| Hooks | https://code.claude.com/docs/en/hooks |
| Settings | https://code.claude.com/docs/en/settings |
| Permissions | https://code.claude.com/docs/en/permissions |
| Skills | https://code.claude.com/docs/en/skills |
| MCP Servers | https://code.claude.com/docs/en/mcp |
| Plugins | https://code.claude.com/docs/en/plugins |
| Common Workflows | https://code.claude.com/docs/en/common-workflows |
| Best Practices | https://code.claude.com/docs/en/best-practices |
| Model Configuration | https://code.claude.com/docs/en/model-config |
| CLI Reference | https://code.claude.com/docs/en/cli-reference |
| Token Costs | https://code.claude.com/docs/en/costs |
| Features Overview | https://code.claude.com/docs/en/features-overview |
| Headless Mode | https://code.claude.com/docs/en/headless |
| Resource | URL |
|---|---|
| How Boris Uses Claude Code | https://howborisusesclaudecode.com |
| Addy Osmani: Claude Code Swarms | https://addyo.substack.com/p/claude-code-swarms |
| Kieran Klaassen: Swarm Orchestration Skill | https://gist.github.com/kieranklaassen/c1e5e0a1fd1e50f498e3e02b62943058 |
| Alex Op: From Tasks to Swarms | https://www.alexop.dev/posts/claude-code-from-tasks-to-swarms |
| Perrotta.dev: Claude Code Swarm Mode | https://perrotta.dev/2026/02/claude-code-swarm-mode-agent-teams/ |
| Tool | URL |
|---|---|
| tmux | https://github.com/tmux/tmux |
| iTerm2 | https://iterm2.com/ |
| Ghostty | https://ghostty.org/ |
| it2 CLI (for iTerm2) | https://github.com/mkusaka/it2 |
---
name: my-agent
description: What it does. Use proactively when [trigger].
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
model: sonnet
permissionMode: default
maxTurns: 30
memory: user
background: false
---
You are a [role]. When invoked:
1. [Action]
2. [Action]
3. [Verification]
# 1. Enable agent teams
echo '{"env":{"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS":"1"},"teammateMode":"auto"}' > ~/.claude/settings.json
# 2. Install tmux (optional, for split panes)
brew install tmux
# 3. Start tmux session
tmux new -s swarm
# 4. Launch Claude
claude
# 5. Create a team
> Create a team with 3 teammates to [describe task]
| Action | Keys |
|---|---|
| Cycle through teammates | Shift+Down |
| View teammate session | Enter |
| Interrupt teammate | Escape |
| Toggle task list | Ctrl+T |
| Background a running task | Ctrl+B |
| Action | Keys |
|---|---|
| Navigate panes | Ctrl+b Arrow |
| Zoom pane | Ctrl+b z |
| Detach session | Ctrl+b d |
| Split horizontal | Ctrl+b " |
| Split vertical | Ctrl+b % |
| Kill pane | Ctrl+b x |
| Scroll mode | Ctrl+b [ |
Sub-agents: Minimal overhead. Use freely.
2-3 teammates: Sweet spot for most team tasks.
4-5 teammates: Only for clearly parallel work.
6+ teammates: Rarely worth the coordination cost.
Use Haiku for simple agents (10-20x cheaper than Opus).
Direct message > broadcast (always).
Set maxTurns to prevent runaway execution.
| Variable | Purpose |
|---|---|
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS |
Required to enable agent teams |
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS |
Set to 1 to disable background sub-agents |
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE |
Trigger compaction earlier (e.g., 50 for 50%) |
CLAUDE_CODE_SUBAGENT_MODEL |
Override model for all sub-agents |
BASH_MAX_TIMEOUT_MS |
Max time for Bash commands |
Last Updated: 2026-02-20 Compiled from official Anthropic documentation and community best practices
New techniques, real-world patterns, and Claude updates — delivered as the guides evolve.