Multi-Agent Coordination Patterns: Orchestrator-Workers & Evaluator-Optimizer
Structuring multi-agent architectures for complex software engineering and data pipelines.
Core Conceptual Brief
Single agents break down on complex tasks due to context pollution. Master Orchestrator-Worker and Evaluator-Optimizer topologies to scale agent intelligence.
Theoretical & Empirical Architecture
As tasks become more complex, asking a single agent to handle research, code generation, testing, and deployment fills its context window with conflicting instructions and irrelevant noise.
Multi-Agent Coordination breaks a monolithic problem into specialized sub-agents with narrow scopes, distinct system prompts, and isolated context boundaries.
Under the Hood: Key Engineering Mechanics
1The Orchestrator-Workers Pattern
A high-level Orchestrator analyzes the user objective, breaks it into independent sub-tasks, dispatches them concurrently to specialized Worker agents (e.g. Researcher, Database Specialist, Frontend Builder), and synthesizes their individual deliverables into a final unified result.
2The Evaluator-Optimizer Pattern (Actor-Critic)
One agent (the Generator) produces candidate code or documentation. A second agent (the Evaluator) with a critical system prompt audits the work against strict test cases and security criteria. The Evaluator provides concrete feedback back to the Generator in an iterative refinement loop until a 100% pass score is achieved.
3Router-Specialists Pattern
A fast, inexpensive classifier model (e.g. Haiku or Flash) inspects incoming requests and routes them to specialized agents with tailored tools, preventing token waste on large models.
Evaluator-Optimizer Iterative Improvement Loop
async def evaluator_optimizer_loop(objective: str, max_iterations: int = 3):
current_code = await code_generator_agent.draft(objective)
for i in range(max_iterations):
# Evaluator critiques the work
evaluation = await evaluator_agent.critique(
objective=objective,
candidate_code=current_code
)
print(f"Iteration {i + 1} Score: {evaluation.score}/100")
if evaluation.passed: # e.g. Score >= 95
return current_code
# Feed critique back to generator for targeted refinement
current_code = await code_generator_agent.refine(
current_code=current_code,
feedback=evaluation.critique_points
)
return current_codeProduction Guardrails & Takeaways
- Use Orchestrator-Workers for broad, parallelizable tasks.
- Use Evaluator-Optimizer loops when high quality and verifiable correctness are required.
- Keep subagent context windows lean by passing only required task specifications.
Real Staff AI Systems Interview Question
Q: Why is an Evaluator-Optimizer multi-agent loop often superior to asking a single model to "write the code and make sure it has no bugs"?
A single model suffers from confirmation bias: it assumes the code it just generated is correct. Splitting the roles gives the Evaluator a dedicated persona specifically rewarded for finding bugs, edge-case failures, and security risks, resulting in significantly higher defect discovery rates.