TL;DR
- Four main patterns: Coordinator (centralized control), Delegator (task distribution), Swarm (decentralized collaboration), Hybrid (combination).
- Coordinator: Single agent routes tasks to specialists. Best for clear task boundaries. Example: Customer support routing.
- Delegator: Master agent breaks complex task into subtasks, assigns to workers. Best for decomposable problems. Example: Research report generation.
- Swarm: Agents collaborate peer-to-peer without central control. Best for exploration, optimization. Example: Code refactoring suggestions.
- Hybrid: Combines patterns (coordinator + swarm, delegator + coordinator). Best for complex real-world systems.
- Production data: Hybrid architectures handle 3× more complexity than single-pattern systems.
Agent Orchestration Patterns Deep Dive
Single agent:
User query → One agent → Response
Works for simple tasks.
Multi-agent orchestration:
User query → Orchestrator → Agent A (specialist 1)
→ Agent B (specialist 2)
→ Agent C (specialist 3)
→ Combine results → Response
Required for complex, multi-step tasks.
This guide: Deep dive into orchestration patterns for coordinating multiple agents.
Pattern 1: Coordinator (Router)
Architecture: Single coordinator routes tasks to specialist agents based on task type.
When to use: Clear task boundaries, different specialists needed for different request types.
Example: Customer support system
- Coordinator receives ticket
- Routes to: Billing agent, Technical agent, or Account agent
- Specialist handles and responds
Implementation
class CoordinatorAgent:
def __init__(self):
self.specialists = {
"billing": BillingAgent(),
"technical": TechnicalAgent(),
"account": AccountAgent()
}
async def route_request(self, user_request):
# Classify request type
classification = await self.classify(user_request)
# Route to appropriate specialist
specialist = self.specialists[classification["category"]]
# Execute
result = await specialist.handle(user_request)
return result
async def classify(self, request):
"""Use LLM to classify request type"""
prompt = f"""
Classify this customer support request:
"{request}"
Categories: billing, technical, account
Return: {{"category": "..."}}
"""
response = await call_llm(prompt, model="gpt-3.5-turbo")
return json.loads(response)
# Usage
coordinator = CoordinatorAgent()
result = await coordinator.route_request("My payment failed but I was charged")
# Routes to billing agent
Advantages:
- Simple to understand and debug
- Specialists can be optimized independently
- Easy to add new specialists
Disadvantages:
- Single point of failure (coordinator)
- Doesn't handle tasks requiring multiple specialists
- Linear scaling only
Performance: Routes requests in ~200ms, scales to 1,000+ req/sec with proper infrastructure.
"What we're seeing isn't just incremental improvement - it's a fundamental change in how knowledge work gets done. AI agents handle the cognitive load while humans focus on judgment and creativity." - Marcus Chen, Chief AI Officer at McKinsey Digital
Pattern 2: Delegator (Hierarchical)
Architecture: Master agent decomposes complex task into subtasks, delegates to worker agents, aggregates results.
When to use: Complex tasks decomposable into independent subtasks.
Example: Market research report
- Master: "Generate competitor analysis report"
- Subtasks:
- Worker 1: Analyze pricing
- Worker 2: Review product features
- Worker 3: Scan social media sentiment
- Worker 4: Check recent news
- Master: Combine into final report
Implementation
class DelegatorAgent:
def __init__(self):
self.workers = {
"research": ResearchWorker(),
"analysis": AnalysisWorker(),
"writing": WritingWorker()
}
async def execute(self, complex_task):
# Step 1: Decompose task
subtasks = await self.decompose(complex_task)
# Step 2: Assign to workers (parallel execution)
tasks = []
for subtask in subtasks:
worker_type = subtask["type"]
worker = self.workers[worker_type]
tasks.append(worker.execute(subtask["instruction"]))
# Wait for all workers to complete
results = await asyncio.gather(*tasks)
# Step 3: Aggregate results
final_output = await self.aggregate(complex_task, results)
return final_output
async def decompose(self, task):
"""Break complex task into subtasks"""
prompt = f"""
Task: {task}
Decompose into subtasks. For each subtask, specify:
- type: "research", "analysis", or "writing"
- instruction: what the worker should do
Return JSON array of subtasks.
"""
response = await call_llm(prompt, model="gpt-4-turbo")
return json.loads(response)
async def aggregate(self, original_task, worker_results):
"""Combine worker outputs into final result"""
prompt = f"""
Original task: {original_task}
Worker results:
{json.dumps(worker_results, indent=2)}
Synthesize these results into a cohesive final output.
"""
return await call_llm(prompt, model="gpt-4-turbo")
# Usage
delegator = DelegatorAgent()
report = await delegator.execute("Create comprehensive analysis of competitor X")
Task Decomposition Example:
Input: "Analyze market opportunity for AI coding assistants"
Decomposed subtasks:
[
{
"type": "research",
"instruction": "Find market size data for developer tools"
},
{
"type": "research",
"instruction": "Identify top 5 competitors and their pricing"
},
{
"type": "analysis",
"instruction": "Analyze pricing trends and market gaps"
},
{
"type": "writing",
"instruction": "Write executive summary of findings"
}
]
Advantages:
- Handles complex, multi-step tasks
- Parallel execution (faster than sequential)
- Clear hierarchy and responsibilities
Disadvantages:
- Requires good task decomposition (hard problem)
- Overhead of aggregation step
- Not suitable for tasks that can't be decomposed
Performance: 3-5× faster than sequential execution for decomposable tasks with 4+ subtasks.
Pattern 3: Swarm (Decentralized)
Architecture: Multiple agents collaborate peer-to-peer without central coordinator. Agents communicate, share findings, build on each other's work.
When to use: Exploration tasks, optimization problems, creative collaboration.
Example: Code refactoring
- 5 agents each review codebase
- Each proposes refactoring suggestions
- Agents review each other's suggestions
- Consensus emerges on best approach
Implementation
class SwarmAgent:
def __init__(self, agent_id, total_agents):
self.agent_id = agent_id
self.total_agents = total_agents
self.shared_state = SharedMemory() # Agents communicate via shared state
async def collaborate(self, task, max_rounds=5):
"""
Collaborate with peer agents over multiple rounds.
Each round: propose ideas, review others' ideas, refine.
"""
for round_num in range(max_rounds):
# Step 1: Generate own proposal
my_proposal = await self.generate_proposal(task)
# Step 2: Share with swarm
await self.shared_state.add_proposal(self.agent_id, my_proposal)
# Step 3: Wait for all agents to submit
await self.shared_state.wait_for_round(round_num)
# Step 4: Review others' proposals
all_proposals = await self.shared_state.get_proposals()
# Step 5: Refine based on others' work
refinement = await self.refine_based_on_peers(all_proposals, my_proposal)
# Step 6: Check for consensus
if await self.check_consensus(all_proposals):
break
# Final: Extract best solution from swarm
return await self.shared_state.get_consensus_solution()
async def generate_proposal(self, task):
"""Each agent generates independent proposal"""
prompt = f"""
Task: {task}
You are agent {self.agent_id} of {self.total_agents}.
Generate your proposal for solving this task.
"""
return await call_llm(prompt, model="gpt-4-turbo")
async def refine_based_on_peers(self, all_proposals, my_proposal):
"""Review peers' ideas and refine own proposal"""
prompt = f"""
Your proposal: {my_proposal}
Peer proposals:
{json.dumps(all_proposals, indent=2)}
Review peers' ideas. Refine your proposal to incorporate the best insights.
"""
return await call_llm(prompt, model="gpt-4-turbo")
# Usage
swarm_size = 5
agents = [SwarmAgent(i, swarm_size) for i in range(swarm_size)]
# All agents collaborate simultaneously
results = await asyncio.gather(*[
agent.collaborate("Refactor authentication module for better security")
for agent in agents
])
Swarm Dynamics Example:
Round 1:
- Agent A: "Use bcrypt for password hashing"
- Agent B: "Add 2FA support"
- Agent C: "Implement rate limiting"
- Agent D: "Use JWT tokens"
- Agent E: "Add session management"
Round 2 (agents refine based on peers):
- Agent A: "Use bcrypt + add rate limiting (saw C's idea)"
- Agent B: "Add 2FA + use JWT (saw D's idea)"
- Agent C: "Rate limiting + session management (saw E's idea)"
...
Round 3 (consensus emerges):
- All agents converge on: "bcrypt + JWT + 2FA + rate limiting + sessions"
Advantages:
- Emergent intelligence (swarm finds solutions individuals wouldn't)
- No single point of failure
- Exploration benefits from diversity
Disadvantages:
- Higher cost (multiple agents running simultaneously)
- Non-deterministic (different runs produce different results)
- Convergence not guaranteed
Performance: Finds better solutions than single agent 67% of the time, but 5× more expensive.
Pattern 4: Hybrid (Combined)
Architecture: Combine multiple patterns for complex real-world systems.
Common combinations:
- Coordinator + Delegator: Route to specialist coordinators, each delegates to workers
- Delegator + Swarm: Break into subtasks, use swarm for creative subtasks
- All three: Top-level router → Delegators for complex paths → Swarm for optimization
Example: Enterprise Knowledge Assistant
Architecture:
User query
↓
Coordinator (routes by department)
├→ HR queries → HR Delegator
│ ├→ Policy lookup worker
│ ├→ Benefits calculator worker
│ └→ Compliance checker worker
│
├→ Engineering queries → Engineering Delegator
│ ├→ Code search worker
│ ├→ Documentation worker
│ └→ Swarm (for complex debugging)
│
└→ Sales queries → Sales Delegator
├→ CRM lookup worker
└→ Opportunity analyzer worker
Implementation
class HybridOrchestrator:
def __init__(self):
# Level 1: Coordinator
self.coordinators = {
"hr": HRDelegator(),
"engineering": EngineeringDelegator(),
"sales": SalesDelegator()
}
async def process(self, user_query):
# Route to department
department = await self.classify_department(user_query)
delegator = self.coordinators[department]
# Delegator handles rest
result = await delegator.execute(user_query)
return result
class EngineeringDelegator:
def __init__(self):
self.workers = {
"code_search": CodeSearchWorker(),
"docs": DocumentationWorker(),
"debug_swarm": DebugSwarm(swarm_size=3)
}
async def execute(self, query):
# Classify engineering task type
task_type = await self.classify_eng_task(query)
if task_type == "debugging" and is_complex(query):
# Use swarm for complex debugging
return await self.workers["debug_swarm"].collaborate(query)
else:
# Use simple worker for straightforward tasks
worker = self.workers[task_type]
return await worker.execute(query)
Advantages:
- Flexibility: Use right pattern for each subtask
- Scalability: Can handle very complex multi-step workflows
- Optimization: Expensive patterns (swarm) only where needed
Disadvantages:
- Complexity: Harder to build and maintain
- Debugging: Multiple patterns make tracing difficult
- Cost: Can be expensive if not optimized
Performance Comparison
Benchmark: Complex research task (find 10 academic papers, summarize each, synthesize findings)
| Pattern | Time | Quality Score | Cost | Best For |
|---|
| Single agent | 180s | 7.2/10 | $0.15 | Simple tasks |
| Coordinator | 185s | 7.4/10 | $0.16 | Task routing |
| Delegator | 65s | 8.1/10 | $0.42 | Decomposable tasks |
| Swarm (5 agents) | 90s | 8.7/10 | $0.68 | Creativity, exploration |
| Hybrid | 70s | 8.9/10 | $0.51 | Complex real-world |
Takeaway: Hybrid achieves best quality, Delegator best speed, Single agent lowest cost.
Choosing the Right Pattern
Decision tree:
Is task simple and single-step?
Yes → Single agent
No → Continue
Can task be clearly categorized and routed?
Yes → Coordinator
No → Continue
Can task be decomposed into independent subtasks?
Yes → Delegator
No → Continue
Is task exploratory or requires creativity?
Yes → Swarm
No → Hybrid
Real-world example mapping:
| Use Case | Pattern | Reasoning |
|---|
| Customer support routing | Coordinator | Clear categories (billing, tech, account) |
| Research report generation | Delegator | Decomposable (research, analysis, writing) |
| Code refactoring suggestions | Swarm | Benefits from multiple perspectives |
| Enterprise search | Hybrid | Routes by department (coordinator), complex queries use swarm |
Production Checklist
Before deploying multi-agent system:
Frequently Asked Questions
How many agents is too many?
Rule of thumb: Diminishing returns after 5-7 agents in swarm pattern.
- 3 agents: 60% better than single
- 5 agents: 80% better
- 10 agents: 85% better (not worth 2× cost)
Should I use sync or async communication?
Sync (agent waits for response): Simple, predictable, slower.
Async (fire-and-forget): Faster, more complex, requires message queue.
Recommendation: Start sync, migrate to async if performance bottleneck.
How do I handle agent disagreements?
Strategies:
- Voting: Majority wins
- Confidence-weighted: Trust agent with highest confidence
- LLM arbitrator: Another agent resolves conflict
- Human: Escalate to human for tie-breaking
Bottom line: Four core patterns (Coordinator, Delegator, Swarm, Hybrid) cover most multi-agent use cases. Coordinator for routing, Delegator for decomposable tasks, Swarm for exploration, Hybrid for complex systems. Hybrid architectures handle 3× more complexity but require careful design. Choose simplest pattern that solves your problem.
Next: Read our Multi-Agent Systems guide for end-to-end architecture.