Claude Code Agent Teams: Parallel Multi-Agent Workflows

A subagent is a worker the main agent spawns, supervises and collects a result from — everything flows back through one coordinator. A teammate is a peer session with its own context window that messages other teammates directly by name and claims work from a shared task list. Use subagents when only the answer matters, and teams when the value comes from agents challenging each other.
Set the CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS environment variable to 1, either in your shell or in the env block of settings.json. Agent teams are experimental and disabled by default, so without it no team directory is created and Claude will not spawn teammates. Claude Code rereads the variable on every spawn, so the change takes effect without restarting the session.
While agent teams are enabled, any subagent Claude names launches as a teammate instead. A subagent returns its result to Claude, but a teammate only sends an idle notification saying it stopped, with no output attached. Any flow that waits on subagent results will therefore hang; set the variable to 0 in user settings to get named subagents back.
Start with three to five teammates for most workflows, and aim for five or six tasks each. Token usage scales roughly linearly with active teammates because each one is a separate context window, and coordination overhead grows faster than throughput. Three focused teammates usually outperform five scattered ones.
No. Neither /resume nor /rewind restores in-process teammates, and after resuming the lead may try to message teammates that no longer exist. The shared task list does persist locally, so the work items survive — tell the lead to spawn fresh teammates and they can pick the tasks back up.

Key Takeaway
Claude Code agent teams run several full Claude sessions at once under one lead. Each teammate holds its own context window, messages the others through a mailbox file, and claims work from a shared task list protected by file locking. Teams are experimental and off by default until you set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS to 1.
I had a bug that survived three separate sessions. Each one found a plausible cause, wrote a plausible fix, and left the symptom exactly where it was. The fourth session I ran differently: I asked for five teammates, gave each a different hypothesis, and told them to argue. Two of the theories died within four minutes because another teammate could point at the code that disproved them.
That is the shape agent teams are actually for. This post covers how to turn them on, how they differ from subagents in ways that break orchestration if you assume they are the same, where the team lives on disk, how to gate teammates with hooks, and the limitations that are worth knowing before you hand a team a refactor.
Agent teams are experimental. Without the environment variable set, no team directory is written at session start and Claude will not spawn a teammate no matter how you phrase the request. The variable is read from settings.json or from your shell, and Claude Code rereads it every time it spawns a subagent, so you can flip it mid-session and the next spawn honours the new value.
The part that surprises people is what else the switch does. While teams are enabled, any subagent Claude names launches as a teammate rather than a subagent. Claude names subagents on its own so it can message them later, so a team can form during delegation you never framed as team work.
// ~/.claude/settings.json
// Agent teams are experimental and OFF by default. Without this
// variable no team directory is written and Claude never spawns
// a teammate, however you phrase the prompt.
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
// "in-process" (default) keeps every teammate in one terminal.
// "auto" opens split panes when tmux or iTerm2 + it2 is present.
"teammateMode": "in-process"
}A subagent returns its result to Claude. A teammate only sends an idle notification that says it stopped, without its output. An orchestration flow that waits on subagent results will therefore stall silently once agent teams are on. If that happens, set the variable to 0 in your user settings and the next named subagent launches as a subagent again.
Both give you more than one agent, and that is where the similarity ends. A subagent is a worker the main agent spawns, supervises and collects from. A teammate is a peer session that talks to other peers and picks up its own work. Choosing the wrong one costs you either coordination you did not need or coordination you needed and did not get.
The four differences that actually change which one you should reach for:
| Dimension | Subagents | Agent teams |
|---|---|---|
| Communication | Returns one result to the caller | Teammates message each other directly by name |
| Coordination | The main agent manages all the work | Self-coordination plus a shared, lockable task list |
| Best for | Focused tasks where only the result matters | Work that needs discussion and disagreement |
| Token cost | Lower — results are summarised back | Higher — each teammate is a whole Claude instance |
You do not create a team as a separate step any more. The TeamCreate and TeamDelete tools were removed in v2.1.178, and cleanup happens when the session exits. You describe the roles you want and the lead spawns them. Always name them in the prompt: the lead assigns a name to every teammate it spawns, and that name is what any other teammate uses to send it a message. If you let the lead invent the names you cannot reference a specific teammate in your next instruction.
# The lead spawns teammates from plain language. Name them —
# the name is the address other teammates send messages to.
Spawn three teammates to review PR #142:
- security : token handling, session management, input validation
- perf : N+1 queries and allocation in the hot path
- tests : coverage of the new branches only
Have them message each other with anything the others should
re-check, then report to me.
# Agent panel keys (in-process mode):
# up / down select a teammate
# Enter open its transcript and type to message it
# x stop the selected teammate
# Ctrl+T toggle the shared task list
# Esc interrupt the selected teammate's current turnSpawning requires an interactive session. In non-interactive mode with the -p flag, including Agent SDK sessions, Claude does not spawn teammates and a named subagent runs as an ordinary subagent even with the feature enabled. Teammates also inherit the lead's permission mode at spawn time, and you cannot set a per-teammate mode when spawning — only afterwards.
The team is not an abstraction held in the model's head. It is a directory, and knowing that turns most team debugging into reading files. The team name is derived from the session: the string session- followed by the first eight characters of the session id.
# Where a team actually lives on disk. The name is
# "session-" plus the first eight characters of the session id.
~/.claude/teams/session-a1b2c3d4/config.json # members, agent ids, pane ids
~/.claude/teams/session-a1b2c3d4/inboxes/*.json # one mailbox per agent
~/.claude/tasks/session-a1b2c3d4/ # the shared task list
# config.json holds live runtime state — do not hand-author it.
# The teams directory is removed when the session exits; the tasks
# directory persists, so a resumed session keeps its task list.Each agent's mailbox is a JSON file, and Claude Code validates every entry as it reads one. Entries that do not match the message format are reported and removed, and the valid messages still get delivered. Before v2.1.207 a single malformed entry produced a repeated error every second and blocked delivery for that mailbox until you deleted the file by hand. A message is only reported as sent when the write to the recipient's mailbox actually succeeds, so a full disk means the sender gets an error rather than a message quietly vanishing.
The failure I hit most often is a teammate that decides it is finished while the type-check is still red. Three hooks fire on team lifecycle events, and all three use the same convention: exit with code 2 to reject the transition and send your stderr text back to the agent as feedback.
// .claude/settings.json — a teammate that says it is done
// but left the type-check red goes back to work. Exit code 2
// sends the stderr text back as feedback and keeps it running.
{
"hooks": {
"TeammateIdle": [
{
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit || { echo 'tsc is red — fix it before going idle' >&2; exit 2; }"
}
]
}
]
}
}Token usage scales roughly linearly with the number of active teammates, because each one is a separate context window doing its own file reads. Anthropic's own guidance is to start with three to five teammates for most workflows and to give each of them five or six tasks — three focused teammates routinely beat five scattered ones, and beyond a certain point extra teammates stop speeding anything up while still costing full price.
There is a second, less obvious cost. An in-process teammate's requests fall outside the main conversation's prompt-cache bucket, so its cache holds for five minutes by default rather than an hour, even on a subscription. On a team that thinks for a while between turns, that means paying to reprocess the prefix repeatedly.
Set subagentPromptCacheTtl to 1h in settings.json before a long team run. The API bills one-hour cache writes at a higher rate, so it is a real trade — but on a five-teammate session with long gaps between turns it has been the cheaper side of that trade for me every time.
Agent teams are labelled experimental and the label is doing real work. These are the constraints that changed how I use them:
The rule I ended up with is narrow on purpose: reach for a team when the value comes from disagreement, and for subagents when the value comes from the answer. Parallel review, competing hypotheses and cross-layer work all benefit from teammates that can challenge each other. Anything sequential, anything touching the same files, and anything where you just want a summary back is cheaper and more reliable as a subagent.
Sources & further reading