Delegation between agents
With allow_delegation=True, an agent gets two tools for its coworkers: hand them a job, or ask them a question. The coworker's answer comes back as the tool's result.
In lesson 14 you decided the order of work. With delegation the writer decides, and it can ask the clerk only when it needs to.
from crewai import Agent, Crew, Task
from shop_llm import ShopLLM
from tools import lookup_order
clerk = Agent(role="Order clerk", goal="Find the status of customers' orders",
backstory="You can look up any order in the shop's system.",
llm=ShopLLM(model="shop"), tools=[lookup_order])
writer = Agent(role="Reply writer", goal="Write replies to customers",
backstory="You write short, friendly emails.",
llm=ShopLLM(model="shop"))import json
import re
from shop_llm import ShopLLM
class ManagerLLM(ShopLLM):
def call(self, messages, tools=None, **kwargs):
found = {t["function"]["name"]: t["function"] for t in tools or []}
delegate = found.get("delegate_work_to_coworker")
if delegate and messages[-1]["role"] == "user":
names = delegate["description"].split("coworkers: ")[1].split("\n")[0]
coworker = next(n for n in names.split(", ") if "order" in n.lower())
job = re.search(r"Current Task: (.*)", messages[-1]["content"]).group(1)
args = {"task": job, "context": "A customer wrote in.", "coworker": coworker}
return [{"id": "delegate_1", "type": "function", "function": {
"name": "delegate_work_to_coworker", "arguments": json.dumps(args)}}]
return super().call(messages, tools=tools, **kwargs)ManagerLLM is a model for an agent that delegates. When it is offered the delegate_work_to_coworker tool, it reads the coworkers' roles from the tool's description, picks the one whose role mentions orders, and asks for the job with the customer's request as the task. Otherwise it behaves as ShopLLM.
from crewai import Task
from desk_manager import ManagerLLM
writer.allow_delegation = True
writer.llm = ManagerLLM(model="shop")
task = Task(description="Answer the customer: {question}",
expected_output="One sentence.", agent=writer)
crew = Crew(agents=[clerk, writer], tasks=[task])
print(crew.kickoff(inputs={"question": "Where is my order A17?"}).raw)One task, given to the writer. The writer's model called delegate_work_to_coworker with the clerk's role; CrewAI ran a task for the clerk, whose model looked A17 up with its own tool, and the clerk's answer came back to the writer as the tool's result.
What delegation adds
result = crew.kickoff(inputs={"question": "Where is my order A17?"})
for message in result.tasks_output[0].messages[2:]:
print(message["role"], "|", message.get("tool_calls") or message["content"])The writer's own conversation holds one tool call and one tool result. The clerk's work happened in a separate conversation, as lesson 5 said: each agent's call starts fresh, and only the task and context arguments cross over. The collaboration page makes the same point about writing them: the coworker sees only what is in them.
Pick one to watch it run, step by step.
The dashed line is the next lesson: a manager agent in place of the writer, holding the same two tools.
- Set
allow_delegation=Falseand run the first example again. - Ask "Hello" and check whether the writer delegates.
- Rename the clerk's role to "Stock checker" and read the error from
next.
Slow is fine. Stopping is the only problem.