Skip to content

Commit 6ce5466

Browse files
author
Pierre
authored
Merge pull request #51 from WorkflowAI/pierre-examples-workflows-agent-delegation
Examples: agent delegation workflow
2 parents 6969157 + e1f9e07 commit 6ce5466

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

examples/workflows/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,27 @@ The Chain of Agents pattern is designed for processing long documents or complex
5858

5959
For an implementation example, see [chain_of_agents.py](chain_of_agents.py).
6060

61+
## 7. Agent Delegation
62+
The Agent Delegation pattern enables dynamic and flexible workflows where one agent can invoke other agents through tools. This pattern is particularly useful when you want an agent to dynamically choose which specialized agents to use based on the task at hand, rather than having a fixed sequence or structure.
63+
64+
**Key Features:**
65+
- Dynamic model selection based on task requirements
66+
- Flexible workflow that adapts based on initial responses
67+
- Ability to track which agents were used and why
68+
- Built-in confidence scoring for quality control
69+
70+
**Example:**
71+
- An orchestrator agent receives a complex task (e.g., system architecture design)
72+
- It breaks down the task into smaller components
73+
- For each component, it:
74+
- Chooses the most appropriate model (e.g., GPT-4 for reasoning, Claude for analysis)
75+
- Delegates the work through a tool
76+
- Evaluates the response and confidence level
77+
- Requests additional work if needed
78+
- Finally, it synthesizes all responses into a coherent solution
79+
80+
For an implementation example, see [agent_delegation.py](agent_delegation.py).
81+
6182
---
6283

6384
These patterns were inspired by the workflow patterns described in the [Vercel AI SDK Documentation](https://sdk.vercel.ai/docs/foundations/agents#patterns-with-examples) and research from organizations like [Google Research](https://research.google/blog/chain-of-agents-large-language-models-collaborating-on-long-context-tasks/).
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
"""
2+
This example demonstrates agent delegation, where one agent (the orchestrator) can dynamically
3+
invoke other agents through tools. This pattern is useful when you want to:
4+
5+
1. Let an agent dynamically choose which specialized agents to use
6+
2. Allow the orchestrator to adapt its strategy based on initial responses
7+
3. Enable flexible workflows where the sequence of agent calls isn't fixed
8+
4. Track which agents were used and why
9+
10+
The example shows how to:
11+
1. Set up a tool that allows one agent to call another
12+
2. Structure input/output types for delegation
13+
3. Configure the orchestrator agent with the delegation tool
14+
4. Handle responses and track agent usage
15+
"""
16+
17+
import asyncio
18+
from typing import Optional
19+
20+
from pydantic import BaseModel, Field
21+
22+
import workflowai
23+
from workflowai import Model
24+
25+
26+
class DelegateInput(BaseModel):
27+
"""Input for delegating a task to a specialized agent."""
28+
29+
task: str = Field(description="The task to delegate")
30+
model: Model = Field(description="The model to use for this task")
31+
context: Optional[str] = Field(
32+
default=None,
33+
description="Additional context that might help the agent",
34+
)
35+
36+
37+
class DelegateOutput(BaseModel):
38+
"""Output from a delegated task."""
39+
40+
response: str = Field(description="The agent's response to the task")
41+
confidence: float = Field(
42+
description="Confidence score between 0 and 1",
43+
ge=0,
44+
le=1,
45+
)
46+
47+
48+
class WorkerInput(BaseModel):
49+
"""Input for the worker agent."""
50+
51+
task: str = Field(description="The task to perform")
52+
context: Optional[str] = Field(
53+
default=None,
54+
description="Additional context that might help with the task",
55+
)
56+
57+
58+
class WorkerOutput(BaseModel):
59+
"""Output from the worker agent."""
60+
61+
response: str = Field(description="The response to the task")
62+
confidence: float = Field(
63+
description="Confidence score between 0 and 1",
64+
ge=0,
65+
le=1,
66+
)
67+
68+
69+
class OrchestratorInput(BaseModel):
70+
"""Input for the orchestrator agent."""
71+
72+
objective: str = Field(description="The high-level objective to achieve")
73+
requirements: list[str] = Field(
74+
description="List of specific requirements or constraints",
75+
default_factory=list,
76+
)
77+
78+
79+
class OrchestratorOutput(BaseModel):
80+
"""Final output from the orchestrator."""
81+
82+
solution: str = Field(description="The final solution that meets the objective")
83+
explanation: str = Field(description="Explanation of how the solution was derived")
84+
agents_used: list[str] = Field(
85+
description="List of agents/models used in the process",
86+
default_factory=list,
87+
)
88+
89+
90+
@workflowai.agent()
91+
async def worker_agent(agent_input: WorkerInput) -> WorkerOutput:
92+
"""
93+
A specialized worker agent that handles specific tasks.
94+
95+
Make sure to:
96+
1. Focus on the specific task assigned
97+
2. Provide detailed reasoning for your approach
98+
3. Include confidence level in your response
99+
"""
100+
...
101+
102+
103+
async def delegate_task(agent_input: DelegateInput) -> DelegateOutput:
104+
"""Delegate a task to a worker agent with a specific model."""
105+
# Run the worker agent with the specified model
106+
run = await worker_agent.run(
107+
WorkerInput(
108+
task=agent_input.task,
109+
context=agent_input.context,
110+
),
111+
model=agent_input.model,
112+
)
113+
return DelegateOutput(
114+
response=run.output.response,
115+
confidence=run.output.confidence,
116+
)
117+
118+
119+
@workflowai.agent(
120+
id="orchestrator",
121+
model=Model.GPT_4O_LATEST,
122+
tools=[delegate_task],
123+
)
124+
async def orchestrator_agent(agent_input: OrchestratorInput) -> OrchestratorOutput:
125+
"""
126+
You are an expert orchestrator that breaks down complex objectives into smaller tasks
127+
and delegates them to specialized agents. You can use the delegate_task tool to assign
128+
work to other agents.
129+
130+
Your responsibilities:
131+
1. Break down the objective into smaller, focused tasks
132+
2. Choose appropriate models for each task based on its nature:
133+
- GPT-4O for complex reasoning or creative tasks
134+
- Claude for analytical or structured tasks
135+
- Gemini for technical or scientific tasks
136+
3. Use the delegate_task tool to assign work
137+
4. Evaluate responses and confidence levels
138+
5. Request additional work if needed
139+
6. Synthesize all responses into a cohesive solution
140+
7. Track which models were used and why
141+
142+
Make sure the final solution:
143+
- Meets all specified requirements
144+
- Is well-reasoned and explained
145+
- Acknowledges any limitations or uncertainties
146+
- Lists all models/agents used in the process
147+
"""
148+
...
149+
150+
151+
async def main():
152+
# Example: Software architecture task
153+
print("\nExample: Software Architecture Design")
154+
print("-" * 50)
155+
156+
result = await orchestrator_agent.run(
157+
OrchestratorInput(
158+
objective="Design a scalable microservices architecture for an e-commerce platform",
159+
requirements=[
160+
"Must handle 10,000+ concurrent users",
161+
"Include payment processing and inventory management",
162+
"Ensure data consistency across services",
163+
"Provide real-time order tracking",
164+
],
165+
),
166+
)
167+
168+
print("\nSolution:")
169+
print(result.output.solution)
170+
print("\nExplanation:")
171+
print(result.output.explanation)
172+
print("\nAgents Used:")
173+
for agent in result.output.agents_used:
174+
print(f"- {agent}")
175+
176+
177+
if __name__ == "__main__":
178+
asyncio.run(main())

0 commit comments

Comments
 (0)