本节用两个数学子 Agent 演示多 Agent 编排:主 Agent 不直接做所有事,而是通过工具调用专门的子 Agent。
当一个 Agent 同时承担太多职责时,prompt 会变长,工具选择也更混乱。Multi-Agent 的做法是把能力拆给多个专门 Agent,再由主 Agent 负责选择和协调。
专注一个小任务,例如只会开方或只会平方。
把调用子 Agent 的逻辑封装成普通 tool。
根据用户问题选择调用哪个 wrapper tool。
“Agent as Tool”:子 Agent 本身不是直接暴露给用户,而是被一个 tool 函数调用。主 Agent 只需要学会何时调用这个 tool。
Notebook 先定义两个普通工具:一个计算平方根,一个计算平方。它们是子 Agent 的专属工具。
@tool
def square_root(x: float) -> float:
"""Calculate the square root of a number"""
return x ** 0.5
@tool
def square(x: float) -> float:
"""Calculate the square of a number"""
return x ** 2数学工具很小,但结构和真实业务一致:每个子 Agent 拥有自己的工具集和职责边界。
每个子 Agent 只拿到自己需要的工具。这样它的动作空间更小,行为也更容易预测。
subagent_1 = create_agent(
model=deepseek_model(),
tools=[square_root],
)
subagent_2 = create_agent(
model=deepseek_model(),
tools=[square],
)| Agent | 工具 | 职责 |
|---|---|---|
subagent_1 | square_root | 回答开方问题 |
subagent_2 | square | 回答平方问题 |
主 Agent 不能直接“看见”子 Agent。Notebook 用两个 wrapper tool 调用子 Agent,并把子 Agent 的最终消息返回给主 Agent。
@tool
def call_subagent_1(x: float) -> float:
"""Call subagent 1 in order to calculate the square root of a number"""
response = subagent_1.invoke(
{"messages": [HumanMessage(content=f"Calculate the square root of {x}")]}
)
return response["messages"][-1].content
@tool
def call_subagent_2(x: float) -> float:
"""Call subagent 2 in order to calculate the square of a number"""
response = subagent_2.invoke(
{"messages": [HumanMessage(content=f"Calculate the square of {x}")]}
)
return response["messages"][-1].contentWrapper tool 最好返回主 Agent 需要的最终结果或简短解释。不要把完整子 Agent trace 原样塞回去,否则主 Agent 上下文会膨胀。
主 Agent 拿到两个 wrapper tool 后,会根据用户问题选择调用哪个子 Agent。例如“square root”应路由到 call_subagent_1。
main_agent = create_agent(
model=deepseek_model(),
tools=[call_subagent_1, call_subagent_2],
)
question = "What is the square root of 456?"
response = main_agent.invoke({"messages": [HumanMessage(content=question)]})
print(response["messages"][-1].content)提出数学问题。
判断需要开方。
调用开方子 Agent。
调用底层工具并返回结果。
Notebook 最后用 pprint(response) 和 model_dump() 查看消息细节。这一步能看到主 Agent 何时发起 tool call、tool 返回了什么、最终回答如何形成。
pprint(response)
pprint(response["messages"][1])
pprint(response["messages"][0].model_dump(), sort_dicts=False)
pprint(response["messages"][1].model_dump(), sort_dicts=False)Multi-Agent 问题通常不是“模型不会回答”,而是“路由错了”或“子 Agent 返回值不适合主 Agent”。检查 trace 是最快定位方式。