6.3 KiB
Agent Orchestration Patterns
This reference explains different approaches to coordinating multiple agents in OpenAI Agents SDK.
Pattern 1: LLM-Based Orchestration
What: Let the LLM autonomously decide how to route tasks and execute tools.
When to Use:
- Requirements are complex and context-dependent
- You want adaptive, intelligent routing
- Task decomposition benefits from reasoning
How It Works:
- Create a "manager" agent with instructions and tools/handoffs
- LLM plans task execution based on instructions
- LLM decides which tools to call or agents to delegate to
- Self-critique and improvement loops possible
Example:
const managerAgent = Agent.create({
name: 'Project Manager',
instructions: `You coordinate project work. You have access to:
- Database agent for data operations
- API agent for external integrations
- UI agent for frontend tasks
Analyze the request and route to appropriate agents.`,
handoffs: [databaseAgent, apiAgent, uiAgent],
});
Best Practices:
- Write clear, detailed instructions
- Define tool/handoff descriptions precisely
- Implement monitoring and logging
- Create evaluation frameworks
- Iterate based on observed failures
Pros:
- Flexible and adaptive
- Handles complex scenarios
- Can self-improve with feedback
Cons:
- Less predictable
- Higher token usage
- Requires good prompt engineering
Pattern 2: Code-Based Orchestration
What: Use explicit programming logic to control agent execution flow.
When to Use:
- Workflow is deterministic and well-defined
- You need guaranteed execution order
- Debugging and testing are priorities
- Cost control is important
How It Works:
- Define agents for specific tasks
- Use code to sequence execution
- Pass outputs as inputs to next steps
- Implement conditional logic manually
Example:
// Sequential execution
const summary = await run(summarizerAgent, article);
const sentiment = await run(sentimentAgent, summary.finalOutput);
const recommendations = await run(recommenderAgent, sentiment.finalOutput);
// Conditional routing
if (sentiment.finalOutput.score < 0.3) {
await run(escalationAgent, article);
} else {
await run(responseAgent, article);
}
// Parallel execution
const [summary, keywords, entities] = await Promise.all([
run(summarizerAgent, article),
run(keywordAgent, article),
run(entityAgent, article),
]);
// Feedback loops
let result = await run(writerAgent, prompt);
let quality = await run(evaluatorAgent, result.finalOutput);
while (quality.finalOutput.score < 8) {
result = await run(writerAgent, `Improve: ${result.finalOutput}`);
quality = await run(evaluatorAgent, result.finalOutput);
}
Best Practices:
- Break complex tasks into discrete steps
- Use structured outputs for reliable routing
- Implement error handling at each step
- Log execution flow for debugging
Pros:
- Predictable and deterministic
- Easy to debug and test
- Full control over execution
- Lower token usage
Cons:
- Less flexible
- Requires upfront planning
- Manual routing logic
Pattern 3: Agents as Tools
What: Wrap agents as tools for a manager LLM, which decides when to invoke them.
When to Use:
- You want LLM routing but keep the manager in control
- Sub-agents produce specific outputs (data, not conversation)
- You need manager to summarize/synthesize results
How It Works:
- Create specialist agents with
outputType - Convert agents to tools
- Manager agent calls them as needed
- Manager synthesizes final response
Example:
const weatherAgent = new Agent({
name: 'Weather Service',
instructions: 'Return weather data',
outputType: z.object({
temperature: z.number(),
conditions: z.string(),
}),
});
// Convert to tool
const weatherTool = tool({
name: 'get_weather',
description: 'Get weather data',
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => {
const result = await run(weatherAgent, city);
return result.finalOutput;
},
});
const managerAgent = new Agent({
name: 'Assistant',
instructions: 'Help users with various tasks',
tools: [weatherTool, /* other agent-tools */],
});
Pros:
- Manager maintains conversation control
- Clean separation of concerns
- Reusable specialist agents
Cons:
- Extra layer of complexity
- Slightly higher latency
Pattern 4: Parallel Execution
What: Run multiple agents concurrently and select/combine results.
When to Use:
- Independent tasks can run simultaneously
- You want to generate multiple options
- Time to result matters
Example Use Cases:
- Generate 3 marketing copy variants
- Parallel research tasks (summary, pros/cons, stats, quotes)
- Quality voting (best result selection)
See Templates:
templates/text-agents/agent-parallel.ts
Pattern 5: Human-in-the-Loop
What: Require human approval for specific actions.
When to Use:
- High-stakes actions (payments, deletions, emails)
- Compliance requirements
- Building trust in AI systems
How It Works:
- Mark tools with
requiresApproval: true - Handle
ToolApprovalIteminterruptions - Prompt user for approval
- Resume with approve/reject
See Templates:
templates/text-agents/agent-human-approval.ts
Choosing a Pattern
| Requirement | Recommended Pattern |
|---|---|
| Adaptive routing | LLM-Based |
| Deterministic flow | Code-Based |
| Cost control | Code-Based |
| Complex reasoning | LLM-Based |
| Multiple options | Parallel |
| Safety requirements | Human-in-the-Loop |
| Manager + specialists | Agents as Tools |
Combining Patterns
You can mix patterns:
// Code-based orchestration with parallel execution and HITL
const [research1, research2] = await Promise.all([
run(researchAgent1, topic),
run(researchAgent2, topic),
]);
// LLM-based synthesis
const synthesis = await run(synthesizerAgent, {
research1: research1.finalOutput,
research2: research2.finalOutput,
});
// Human approval for final output
const approved = await requestApproval(synthesis.finalOutput);
if (approved) {
await run(publishAgent, synthesis.finalOutput);
}
Last Updated: 2025-10-26 Source: OpenAI Agents Docs - Multi-Agent Guide