Skip to main content

Sub-Agents & Coordination

The agent loop doesn't just run once — it can spawn child loops. When a task is too complex for a single context, Claude Code creates sub-agents that work autonomously and return results.

The Agent Tool

The Agent tool is how Claude spawns sub-agents:

🤖
Main Agent
🔧
Agent Tool: spawn sub-agent
Sub-Agent
🤖
Sub-Agent
Own conversation context
Filtered tool set
Custom system prompt
⚙️
Autonomous work
📤
Return result to main agent

Key Parameters

src/tools/AgentTool/AgentTool.ts
Agent({
prompt: "Search the codebase for all API endpoints",
description: "Find API endpoints", // Short summary (3-5 words)
subagent_type: "Explore", // Agent type
model: "sonnet", // Optional model override
isolation: "worktree", // Optional git worktree isolation
run_in_background: true, // Run as background task
})

A Universal Abstraction

This shape — prompt, model, tools, delegation mode — appears in every major framework. The core idea is the same: configure an LLM with instructions and capabilities, then let it run autonomously.

src/tools/AgentTool/AgentTool.ts
Agent({
prompt: "Find all API endpoints",
description: "Find endpoints",
subagent_type: "Explore", // filters tools
model: "sonnet",
run_in_background: true,
})

Sub-agents are tools — the model decides when to spawn one. Tool filtering by agent type.

ConceptClaude CodeGoogle ADKOpenAI AgentsLangGraph
Agent initAgent({prompt, type, model})LlmAgent(instruction, model, tools)Agent(instructions, model, tools)create_agent(model, tools)
Delegationrun_in_backgroundsub_agents treehandoffs / as_tool()Graph edges
Tool filteringPer agent typePer agent instancePer agent instancePer graph node
IsolationGit worktreeSeparate sessionsSeparate contextSeparate state

Agent Types

Each type has a filtered set of tools — this constrains what the sub-agent can do:

Agent TypePurposeAvailable Tools
general-purposeComplex multi-step tasksAll tools
ExploreFast codebase explorationRead-only: Read, Glob, Grep, WebFetch, WebSearch
PlanDesign implementation plansRead-only: Read, Glob, Grep, WebFetch, WebSearch
code-simplifierSimplify and refine codeAll tools
Custom (via plugins)Domain-specific tasksConfigured per agent

Why filter tools? Explore agents can't accidentally modify files. Plan agents focus on research without side effects. Fewer tools means a smaller decision space, improving focus.

src/tools/AgentTool/AgentTool.ts (simplified)
function getToolsForAgentType(type: string, allTools: Tool[]): Tool[] {
switch (type) {
case 'Explore':
case 'Plan':
return allTools.filter(t =>
t.isReadOnly() && !['Agent', 'Edit', 'Write', 'Bash'].includes(t.name)
)
case 'general-purpose':
case 'code-simplifier':
return allTools // Full access
default:
return allTools
}
}

Agent Lifecycle

🤖
Main Agent
🔧
Agent(type, prompt, description)
🤖
Create Sub-Agent with filtered tools + custom prompt
📡
Query Anthropic API with sub-agent system prompt
Agentic Loop
🔄
Execute tools
📡
Send tool results to API
🤖
Continue or end_turn
📤
Final result returned to main agent

Foreground vs Background

ModeBehavior
Foreground (default)Blocks main agent until complete. Result immediately available.
Background (run_in_background: true)Main agent continues. Notified via <task-notification> on completion. Output retrieved via TaskOutput.

SendMessage — Continue a Running Agent

Previously spawned agents can be continued without losing context:

src/tools/SendMessageTool/SendMessageTool.ts
SendMessage({
to: "agent-id-or-name",
message: "Now also check the test files"
})

Git Worktree Isolation

When isolation: "worktree" is specified:

  1. A temporary git worktree is created (isolated copy of the repo)
  2. The sub-agent works in this worktree
  3. If changes are made, the worktree path and branch are returned
  4. If no changes, the worktree is automatically cleaned up

This prevents sub-agents from conflicting with each other or with the main agent's work.

Coordinator Mode

When COORDINATOR_MODE is enabled (feature-flagged, internal), Claude Code splits into a coordinator and workers:

👤
User: "Implement feature X and write tests"
🤖
Coordinator decomposes into subtasks
Worker 1
🤖
Agent("Implement feature X")
⚙️
Research, implement, verify
task-notification: completed
Worker 2
🤖
Agent("Write tests for feature X")
⚙️
Analyze, write tests, run
task-notification: completed
🤖
Coordinator retrieves results, synthesizes
📤
Response to User
RoleResponsibilitiesTools Available
CoordinatorDecompose task, delegate, synthesize resultsAgent, SendMessage, TaskStop
WorkerExecute assigned subtask autonomouslySubset of all tools

The coordinator gets a specialized system prompt instructing it to delegate rather than execute directly, decompose tasks into parallel subtasks, and synthesize worker results.

Communication Flow

DirectionMechanism
Coordinator → WorkerAgent tool with run_in_background: true
Worker → CoordinatorTask completion notifications (<task-notification>)
Coordinator → Running WorkerSendMessage for follow-up instructions

Agent Progress Summaries

Coordinator mode also has a lightweight progress summarization layer for workers:

🤖
Running worker transcript
~30s timer
🪞
Fork transcript into summary agent
📝
Generate 1-2 sentence progress summary
📤
Store on AgentProgress for UI display

This is not another autonomous worker. src/services/AgentSummary/agentSummary.ts forks the existing sub-agent conversation, strips incomplete tool calls, denies all tool use, and asks for a short present-tense summary naming the file or function being worked on.

The result is written back onto the worker's progress state so coordinator-mode UIs can show a live status line without waiting for task completion.

How Other Frameworks Compare

Most frameworks expose some notion of delegation, but Claude Code pushes further into runtime coordination: background workers, follow-up messages, task notifications, and permission routing are all part of the same harness.

ConcernClaude CodeGoogle ADKOpenAI AgentsLangGraph
Delegation primitiveAgent tool spawns a child loopsub_agents tree + transfer_to_agenthandoffs or as_tool()Graph nodes / subgraphs
Control flow shapeCall/return by default, optional background taskTransfer within an agent treeHandoff transfers control; as_tool() nests a run and returnsDetermined by graph topology
Nested approval handlingCoordinator or leader can relay approvalsTool-level confirmationNested ToolApprovalItem interruptions from agent-tool runsInterrupt/checkpoint and caller resume
Coordination emphasisRuntime worker orchestrationAgent hierarchyRunner-level delegation primitivesExplicit state graph design
Key difference

Claude Code's distinctive part is not just that it has sub-agents. It couples delegation with task persistence, follow-up messaging, progress summaries, and approval routing, so the harness behaves more like a managed worker runtime than a bare handoff primitive.

Swarm Mode (Agent Teams)

While coordinator mode uses background agents, swarm mode creates teams of in-process agents that can see each other in the terminal and communicate via a shared mailbox.

Feature flag

Swarm mode is gated behind the KAIROS feature flag and compiled out of the public build (v2.1.88). The infrastructure is substantial (~30 source files) but not yet user-facing.

Architecture

👤
User: TeamCreate("build-team")
🤖
Team Leader (your session)
Teammate A
🤖
In-process agent
Own context + filtered tools
Teammate B
🤖
In-process agent
Own context + filtered tools
Teammate C
🤖
In-process agent
Own context + filtered tools
📬
Mailbox — shared async message queue
🔒
Leader Permission Bridge — leader handles all approval dialogs

Backends

Teammates can be visualized in three ways:

BackendHow It WorksVisual
tmuxCreates tmux panes for each teammateSplit terminal panes
iterm2Uses iTerm2 native split panes via it2 CLINative iTerm2 splits
in-processRuns in the same Node.js process with isolated contextShared terminal
src/utils/swarm/backends/types.ts
type BackendType = 'tmux' | 'iterm2' | 'in-process'

Mailbox System

Agents communicate via an async message queue — the Mailbox:

src/utils/mailbox.ts
type MessageSource = 'user' | 'teammate' | 'system' | 'tick' | 'task'

type Message = {
id: string
source: MessageSource
content: string
from?: string // Sender agent name
color?: string // Agent color for UI
timestamp: string
}

class Mailbox {
send(msg: Message): void // Push message, wake waiters
poll(fn): Message | undefined // Non-blocking check
receive(fn): Promise<Message> // Async wait for matching message
}

The MailboxContext React provider makes the mailbox available to all components. Each teammate can send messages to the shared mailbox, and other teammates poll or await messages.

Team Management

Teams are created and destroyed via tools:

src/tools/TeamCreateTool/TeamCreateTool.ts
TeamCreate({
team_name: "build-team",
description: "Implement and test the auth module",
agent_type: "researcher", // Role of team lead
})
// → Creates team file at ~/.claude/teams/{team_name}.json
// → Spawns lead agent with assigned color
// → Returns { team_name, team_file_path, lead_agent_id }
src/tools/TeamDeleteTool/TeamDeleteTool.ts
TeamDelete()
// → Cleans up team files and task directories
// → Kills teammate processes

Leader Permission Bridge

When a teammate needs permission for a tool call (e.g., file write), the request is bridged to the leader agent who shows the approval dialog to the user. This prevents multiple teammates from competing for user input:

src/utils/swarm/leaderPermissionBridge.ts
// Leader registers its permission UI
registerLeaderToolUseConfirmQueue(setter)

// Teammates route permission requests through the bridge
// → Leader shows approval dialog
// → Decision forwarded back to teammate

Swarm vs Coordinator

AspectCoordinator ModeSwarm Mode
Agent locationBackground processesIn-process (shared runtime)
CommunicationTask notifications + SendMessageShared mailbox queue
VisibilityNo terminal UI for workersTerminal panes per teammate
Permission handlingEach worker independentLeader bridges all approvals
Team persistenceNone (session-scoped)Team files on disk
Feature flagCOORDINATOR_MODEKAIROS

Key Source Files

FilePurpose
src/tools/AgentTool/Agent tool implementation
src/tools/SendMessageTool/Agent communication
src/services/AgentSummary/agentSummary.tsPeriodic progress summaries for coordinator workers
src/buddy/Sub-agent system (6 files)
src/coordinator/coordinatorMode.tsCoordinator logic
src/utils/swarm/Swarm system (15+ files)
src/utils/swarm/backends/Terminal backend implementations
src/utils/mailbox.tsAsync message queue
src/context/mailbox.tsxReact context provider
src/utils/swarm/leaderPermissionBridge.tsPermission delegation
src/tools/TeamCreateTool/Team creation tool
src/tools/TeamDeleteTool/Team cleanup tool