| name | orchestration-patterns |
| description | Apply proven orchestration patterns for agent teams including parallel specialists, pipelines, swarms, research+implementation, plan approval, and multi-file refactoring. Use when choosing a team structure, designing workflows, or implementing specific coordination patterns. |
Orchestration Patterns
Experimental: Agent teams are disabled by default. Enable with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS in your settings.json or environment.
Proven patterns for structuring agent teams. Choose the right pattern based on your task's coordination needs.
Related skills:
See also: Complete Workflows for full end-to-end examples.
Pattern Selection Guide
Pattern 1: Parallel Specialists
Multiple specialists review code simultaneously, each with a different lens:
TeamCreate({ team_name: "code-review", description: "Parallel code review" })
Task({
team_name: "code-review",
name: "security",
subagent_type: "sdlc:security-reviewer",
prompt: "Review the PR for security vulnerabilities. Focus on: SQL injection, XSS, auth bypass. Send findings to team-lead.",
run_in_background: true
})
Task({
team_name: "code-review",
name: "quality",
subagent_type: "feature-dev:code-reviewer",
prompt: "Review the PR for bugs, logic errors, and performance issues. Focus on: N+1 queries, memory leaks, slow algorithms. Send findings to team-lead.",
run_in_background: true
})
Task({
team_name: "code-review",
name: "simplicity",
subagent_type: "code-simplifier:code-simplifier",
prompt: "Review the PR for unnecessary complexity. Focus on: over-engineering, premature abstraction, YAGNI violations. Send findings to team-lead.",
run_in_background: true
})
SendMessage({ to: "security", message: { type: "shutdown_request", reason: "Done" } })
SendMessage({ to: "quality", message: { type: "shutdown_request", reason: "Done" } })
SendMessage({ to: "simplicity", message: { type: "shutdown_request", reason: "Done" } })
TeamDelete()
Best for: Code reviews, audits, multi-perspective analysis.
Pattern 2: Pipeline
Each stage depends on the previous:
TeamCreate({ team_name: "feature-pipeline", description: "Feature development pipeline" })
TaskCreate({ subject: "Research", description: "Research best practices for the feature", activeForm: "Researching..." })
TaskCreate({ subject: "Plan", description: "Create implementation plan based on research", activeForm: "Planning..." })
TaskCreate({ subject: "Implement", description: "Implement the feature according to plan", activeForm: "Implementing..." })
TaskCreate({ subject: "Test", description: "Write and run tests for the implementation", activeForm: "Testing..." })
TaskCreate({ subject: "Review", description: "Final code review before merge", activeForm: "Reviewing..." })
TaskUpdate({ taskId: "2", addBlockedBy: ["1"] })
TaskUpdate({ taskId: "3", addBlockedBy: ["2"] })
TaskUpdate({ taskId: "4", addBlockedBy: ["3"] })
TaskUpdate({ taskId: "5", addBlockedBy: ["4"] })
Task({
team_name: "feature-pipeline",
name: "researcher",
subagent_type: "adr:adr-researcher",
prompt: "Claim task #1, research best practices, complete it, send findings to team-lead. Then check for more work.",
run_in_background: true
})
Task({
team_name: "feature-pipeline",
name: "implementer",
subagent_type: "general-purpose",
prompt: "Poll TaskList. When task #3 unblocks, claim it and implement. Then complete and notify team-lead.",
run_in_background: true
})
Best for: Multi-phase features, structured workflows where each step builds on the previous.
Pattern 3: Swarm
Workers grab available tasks from a pool (self-organizing):
TeamCreate({ team_name: "file-review-swarm", description: "Self-organizing file review" })
const swarmPrompt = `
You are a swarm worker. Your job:
1. Call TaskList to see available tasks
2. Find a task with status 'pending' and no owner
3. Claim it with TaskUpdate (set owner to your name)
4. Do the work
5. Mark it completed with TaskUpdate
6. Send findings to team-lead
7. Repeat until no tasks remain
`
Task({ team_name: "file-review-swarm", name: "worker-1", subagent_type: "general-purpose", prompt: swarmPrompt, run_in_background: true })
Task({ team_name: "file-review-swarm", name: "worker-2", subagent_type: "general-purpose", prompt: swarmPrompt, run_in_background: true })
Task({ team_name: "file-review-swarm", name: "worker-3", subagent_type: "general-purpose", prompt: swarmPrompt, run_in_background: true })
Best for: Many similar, independent tasks (file reviews, migrations, test writing).
Pattern 4: Research + Implementation
Research first, then implement with findings:
const research = await Task({
subagent_type: "adr:adr-researcher",
description: "Research caching patterns",
prompt: "Research best practices for implementing caching in APIs. Include: cache invalidation strategies, Redis vs Memcached, cache key design."
})
Task({
subagent_type: "general-purpose",
description: "Implement caching",
prompt: `
Implement API caching based on this research:
${research.content}
Focus on the user_controller.rb endpoints.
`
})
Best for: When implementation benefits from prior research. No team needed - uses plain subagents.
Pattern 5: Plan Approval
Require plan approval before implementation (high-risk changes):
TeamCreate({ team_name: "careful-work", description: "Plan-approved implementation" })
Task({
team_name: "careful-work",
name: "architect",
subagent_type: "Plan",
prompt: "Design an implementation plan for adding OAuth2 authentication",
mode: "plan",
run_in_background: true
})
SendMessage({
to: "architect",
message: { type: "plan_approval_response", request_id: "plan-xxx", approve: true }
})
SendMessage({
to: "architect",
message: { type: "plan_approval_response", request_id: "plan-xxx", approve: false, feedback: "Please add rate limiting considerations" }
})
Best for: Database migrations, security-sensitive changes, architectural decisions.
Pattern 6: Coordinated Multi-File Refactoring
TeamCreate({ team_name: "refactor-auth", description: "Auth module refactoring" })
TaskCreate({
subject: "Refactor User model",
description: "Extract authentication methods to AuthenticatableUser concern",
activeForm: "Refactoring User model..."
})
TaskCreate({
subject: "Refactor Session controller",
description: "Update to use new AuthenticatableUser concern",
activeForm: "Refactoring Sessions..."
})
TaskCreate({
subject: "Update specs",
description: "Update all authentication specs for new structure",
activeForm: "Updating specs..."
})
TaskUpdate({ taskId: "3", addBlockedBy: ["1", "2"] })
Task({
team_name: "refactor-auth",
name: "model-worker",
subagent_type: "general-purpose",
prompt: "Claim task #1, refactor the User model, complete when done",
run_in_background: true
})
Task({
team_name: "refactor-auth",
name: "controller-worker",
subagent_type: "general-purpose",
prompt: "Claim task #2, refactor the Session controller, complete when done",
run_in_background: true
})
Task({
team_name: "refactor-auth",
name: "spec-worker",
subagent_type: "general-purpose",
prompt: "Wait for task #3 to unblock (when #1 and #2 complete), then update specs",
run_in_background: true
})
Best for: Refactoring across multiple files with fan-in dependencies.
Pattern 7: RLM (Recursive Language Model)
Divide large files into partitions, analyze each with a parallel agent team, then synthesize.
When to use: Large log analysis, data exports, full-codebase review, CSV processing — any content that exceeds context limits (~1500 lines).
How it works:
- Team lead detects content type and determines partitioning strategy
- Team lead creates a team (
TeamCreate) and tasks (TaskCreate, one per partition)
- Team lead spawns analyst teammates (scaled to partition count, with
team_name + name) — NOT plain subagents
- Each analyst processes its pre-assigned chunk (1 analyst per partition, fresh context), writes findings to task description via
TaskUpdate, and sends a one-line summary via SendMessage
- Team lead collects inbox messages and synthesizes (or spawns a synthesizer teammate)
- Graceful shutdown (
SendMessage shutdown requests) and cleanup (TeamDelete)
TeamCreate({ team_name: "rlm-analysis", description: "RLM analysis of large file" })
TaskCreate({ subject: "Analyze chunk 1/8", description: "File: path\nStart: 1\nEnd: 1100\nQuery: ...", activeForm: "Analyzing..." })
Task({ team_name: "rlm-analysis", name: "analyst-1", subagent_type: "swarm:rlm-chunk-analyzer", prompt: "Analyze chunk 1...", run_in_background: true })
Task({ team_name: "rlm-analysis", name: "analyst-2", subagent_type: "swarm:rlm-chunk-analyzer", prompt: "Analyze chunk 2...", run_in_background: true })
CRITICAL: Analysts must be teammates, not plain subagents. Plain subagents dump full output into the leader's context (8 x 4K = 32K chars), causing context exhaustion. Teammates communicate via inbox messages.
Agent recommendations:
- Analysts: Content-type-specific (
swarm:rlm-code-analyzer, swarm:rlm-data-analyzer, swarm:rlm-json-analyzer, or swarm:rlm-chunk-analyzer)
- Synthesizer:
swarm:rlm-synthesizer (Sonnet)
See also: RLM Pattern for content-type detection, partitioning strategies, and full team lifecycle.
Multi-File Variant
For directories with mixed content types, the RLM pattern extends to multi-file mode:
- Per-file content-type detection and mixed analyst types in one team
- Tiered partition budget (small/medium/large files) with data-driven sizing
- Small files of the same type batched into single analyst tasks
- Two-phase synthesis: per-type (parallel) then cross-type (sequential)
- Findings written to task descriptions (not SendMessage) to protect Team Lead context
- 1 analyst per task (fresh context each), staged spawning in batches of ~15 for large workloads
See Multi-File Directory Analysis for the full specification and Multi-File RLM Design for the design document.
Best Practices
1. Always Cleanup
Don't leave orphaned teams. Always call TeamDelete() when done.
2. Use Meaningful Names
name: "security-reviewer"
name: "oauth-implementer"
name: "test-writer"
name: "worker-1"
name: "agent-2"
3. Write Clear Prompts
Tell workers exactly what to do:
prompt: `
1. Review app/models/user.rb for N+1 queries
2. Check all ActiveRecord associations have proper includes
3. Document any issues found
4. Send findings to team-lead
`
prompt: "Review the code"
4. Use Task Dependencies
Let the system manage unblocking:
TaskUpdate({ taskId: "2", addBlockedBy: ["1"] })
"Wait until task #1 is done, check every 30 seconds..."
5. Give Teammates Enough Context
Teammates load project context (CLAUDE.md, MCP servers, skills) but don't inherit the lead's conversation history. Include task-specific details in the spawn prompt.
6. Start with Research and Review
If you're new to agent teams, start with tasks that have clear boundaries and don't require writing code: reviewing a PR, researching a library, or investigating a bug.
7. Avoid File Conflicts
Two teammates editing the same file leads to overwrites. Break work so each teammate owns a different set of files.
8. Use Pass-by-Reference for Large Content
Never paste file content into prompts. Pass file paths and line ranges instead:
prompt: "Read /path/to/file.log lines 1-200 and analyze for errors"
prompt: `Analyze this content: ${fileContent}`
This is critical for the RLM pattern where chunks can be large. Analyzers should read files directly using the Read tool.