
构建多代理系统:从架构设计到落地实践的完整指南(附代码解析)
在人工智能从单一模型走向复杂协作的时代,多代理系统(MAS)正成为破解高难度任务的关键钥匙。本文聚焦从理论到代码的全流程实践,深度解析如何通过模块化设计让多个智能体协同完成复杂目标。
你将学会:
- 三大核心组件(模型选型、工具集成、指令配置)如何支撑代理逻辑;
- 两种经典架构模式(Supervisor集中管理与Swarm分布式协作)的适用场景与代码实现;
- 消息流转、层级管理、流式输出等工程化细节的落地技巧;
- 隐藏挑战与行业标准(如MCP、A2A协议)如何突破系统瓶颈。
文中附带完整Python代码示例(基于LangGraph框架),从环境搭建到多代理交互全流程可复现,无论是AI开发者、算法工程师,还是技术管理者,都能从中获取从0到1构建智能协作系统的方法论与实战经验。
准备好了吗?让我们一起揭开多代理系统的技术面纱,解锁AI协作的无限可能。
1. 简介
在评估代理可以增加价值的领域时,请优先考虑那些传统方法难以自动化、尤其是存在摩擦的工作流:
- 复杂决策:涉及细微判断、例外情况或上下文敏感决策的工作流,例如客户服务中的退款审批。
- 难以维护的规则:由于规则集复杂庞大而难以管理的系统,更新成本高或容易出错,例如供应商安全审查。
- 高度依赖非结构化数据:需要解释自然语言、从文档中提取信息或与用户对话交互的场景,例如处理家庭保险索赔。
在决定构建代理之前,请验证用例是否明确符合这些标准。否则,确定性解决方案可能已足够。
2. 代理设计组件
从最基本的形式来看,代理由三个核心组件组成:1. 模型:为代理的推理和决策提供动力的大型语言模型(LLM)。2. 工具:代理可以用来执行操作的外部函数或 API。3. 指令:定义代理行为的明确指导方针和安全机制。
2.1 选择模型
不同模型在任务复杂度、延迟和成本方面各有优劣。并非所有任务都需要最强大的模型——简单的检索或意图分类任务可以由更小、更快的模型处理,而像决定是否批准退款这样的复杂任务可能需要更强大的模型。
一个有效的方法是使用最适合每个任务的强大模型构建代理原型,以建立性能基线。然后尝试替换为更小的模型,观察是否仍能达到可接受的结果。这种方式可以避免过早限制代理能力,并诊断小模型的优缺点。
总之,选择模型的原则很简单:
- 设置评估以建立性能基线。
- 专注于使用可用的最佳模型达到准确性目标。
- 在可能的情况下,通过用更小的模型替换大模型来优化成本和延迟。
函数调用的最佳小型模型是什么?
可以从选择任何开源权重模型开始,如 Llama、Mistral、Qwen、Claude Opus 等。
2.2 定义工具
函数调用是使大型语言模型(LLM)能够与工具交互的主要方式。通常“函数”和“工具”可互换使用,因为“函数”(可重用的代码块)就是代理用来执行任务的“工具”。
工具通过底层应用程序或系统的 API 扩展代理的能力。对于没有 API 的遗留系统,代理可以依靠计算机使用模型通过 Web 和应用程序界面直接与这些系统交互,就像人类一样。每个工具都应有标准化定义,以实现工具与代理之间灵活的多对多关系。文档完善、经过充分测试和可重用的工具可以提高可发现性,简化版本管理,并避免重复定义。
概括来说,代理需要三种类型的工具:
例如,以下是使用 Agents SDK 为上述代理配置一系列工具的示例:
from agents import Agent, WebSearchTool, function_tool
@function_tool
def save_results(output):
db.insert({"output": output, "timestamp": datetime.time()})
return "File saved"
search_agent = Agent(
name="Search agent",
instructinotallow="Help the user search the internet and save results if asked.",
tools=[WebSearchTool(), save_results],
)
当所需工具数量增加时,可考虑将任务分配给多个代理。
2.3 配置指令
高质量的指令对任何 LLM 驱动的应用程序都至关重要,对代理而言更是如此。清晰的指令可以减少歧义,改善代理的决策,从而实现更流畅的工作流执行和更少的错误。
可以使用高级模型(如 o1 或 o3-mini)从现有文档自动生成指令。以下是说明该方法的示例提示:
3. 编排
在基础组件就绪后,即可考虑编排模式,使代理能够高效执行工作流。
多代理系统可以建模为图,代理表示为节点。在管理者和监督者模式中,边表示工具调用;而在去中心化和群体模式中,边表示代理之间的执行交接。
AI 代理的工作流程通常遵循以下 4 个步骤:
无论采用何种编排模式,原则都是一致的:保持组件的灵活性、可组合性,并由清晰、结构良好的提示驱动。
在去中心化模式中,代理可以相互“交接”工作流执行。交接是一种单向转移,允许代理将任务委托给另一个代理。
4. 实现:监督者模式
- 创建一个监督者代理来协调多个专业代理。
pip install langgraph-supervisor langchain-openai
export OPENAI_API_KEY=<your_api_key>
from langchain_openai import ChatOpenAI
from langgraph.graph import START, END
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import create_react_agent
from langgraph_supervisor import create_supervisor
from IPython.display import Image, display
import os
# 选择 LLM
model = ChatOpenAI(model="gpt-4o", api_key=os.getenv("OPENAI_API_KEY"))
# 定义工具
def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
def multiply(a: float, b: float):
"""Multiply two numbers."""
return a * b
def divide(a: float, b: float):
"""Divide two numbers."""
return a / b
tavily_api_key = os.getenv("TAVILY_API_KEY", "your_tavily_api_key")
web_search = TavilySearchResults(max_results=3, tavily_api_key=tavily_api_key)
# 创建工作代理
research_agent = create_react_agent(
model=model,
tools=[web_search],
name="research_agent",
prompt=(
"You are a research agent.\n\n"
"INSTRUCTIONS:\n"
"- Assist ONLY with research-related tasks, DO NOT do any math\n"
"- After you're done with your tasks, respond to the supervisor directly\n"
"- Respond ONLY with the results of your work, do NOT include ANY other text."
))
math_agent = create_react_agent(
model=model,
tools=[add, multiply, divide],
name="math_agent",
prompt=(
"You are a math agent.\n\n"
"INSTRUCTIONS:\n"
"- Assist ONLY with math-related tasks\n"
"- After you're done with your tasks, respond to the supervisor directly\n"
"- Respond ONLY with the results of your work, do NOT include ANY other text."
))
# 创建监督者代理
supervisor_agent = create_supervisor(
model=model,
agents=[research_agent, math_agent],
prompt=(
"You are a supervisor managing two agents:\n"
"- a research agent. Assign research-related tasks to this agent\n"
"- a math agent. Assign math-related tasks to this agent\n"
"Assign work to one agent at a time, do not call agents in parallel.\n"
"Do not do any work yourself."
),
add_handoff_back_messages=True,
output_mode = "full_history",
).compile()
display(Image(supervisor_agent.get_graph().draw_mermaid_png()))
我们将使用 pretty_print_messages
辅助函数来美观地呈现流式代理输出。
from langchain_core.messages import convert_to_messages
def pretty_print_message(message, indent=False):
pretty_message = message.pretty_repr(html=True)
ifnot indent:
print(pretty_message)
return
indented = "\n".join("\t" + c for c in pretty_message.split("\n"))
print(indented)
def pretty_print_messages(update, last_message=False):
is_subgraph = False
if isinstance(update, tuple):
ns, update = update
# 跳过父图更新的打印
if len(ns) == 0:
return
graph_id = ns[-1].split(":")[0]
print(f"Update from subgraph {graph_id}:")
print("\n")
is_subgraph = True
for node_name, node_update in update.items():
update_label = f"Update from node {node_name}:"
if is_subgraph:
update_label = "\t" + update_label
print(update_label)
print("\n")
messages = convert_to_messages(node_update["messages"])
if last_message:
messages = messages[-1:]
for m in messages:
pretty_print_message(m, indent=is_subgraph)
print("\n")
测试流程:
def test_supervisor_functionality():
"""Test the supervisor pattern with a specific GDP query to validate handoffs."""
print(f"Query: find US and New York state GDP in 2024. what % of US GDP was New York state?")
print("-" * 80)
try:
for chunk in supervisor_agent.stream(
{
"messages": [
{
"role": "user",
"content": "find US and New York state GDP in 2024. what % of US GDP was New York state?",
}
]
},
subgraphs=False
):
pretty_print_messages(chunk, last_message=True)
print(f"Test completed successfully")
except Exception as e:
print(f"Test failed with error: {str(e)}")
print("=" * 80)
# 运行
if __name__ == "__main__"orTrue:
test_supervisor_functionality()
输出:
Query: find US and New York state GDP in 2024. what % of US GDP was New York state?
--------------------------------------------------------------------------------
Update from node supervisor:
================================= Tool Message =================================
Name: transfer_to_research_agent
Successfully transferred to research_agent
Update from node research_agent:
================================= Tool Message =================================
Name: transfer_back_to_supervisor
Successfully transferred back to supervisor
Update from node supervisor:
================================= Tool Message =================================
Name: transfer_to_math_agent
Successfully transferred to math_agent
Update from node math_agent:
================================= Tool Message =================================
Name: transfer_back_to_supervisor
Successfully transferred back to supervisor
Update from node supervisor:
================================== Ai Message ==================================
Name: supervisor
In 2024, New York State's GDP was approximately 8.15% of the US GDP.
Test completed successfully
================================================================================
4.1 消息历史管理
可以控制如何将代理消息添加到多代理系统的整体对话历史中:包含代理的完整消息历史:
supervisor = create_supervisor(
agents=[agent1, agent2],
output_mode="full_history")
仅包含代理的最终响应:
supervisor = create_supervisor(
agents=[agent1, agent2],
output_mode="last_message")
4.2 多级分层结构
可以通过创建管理多个监督者的超级监督者来构建多级分层系统:
research_team = create_supervisor(
[research_agent, math_agent],
model=model,
supervisor_name="research_supervisor").compile(name="research_team")
writing_team = create_supervisor(
[writing_agent, publishing_agent],
model=model,
supervisor_name="writing_supervisor").compile(name="writing_team")
top_level_supervisor = create_supervisor(
[research_team, writing_team],
model=model,
supervisor_name="top_level_supervisor").compile(name="top_level_supervisor")
4.3 自定义交接工具
默认情况下,监督者使用预构建的 create_handoff_tool
创建交接工具。您也可以创建自定义交接工具,以下是修改默认实现的一些思路:
- 更改工具名称和/或描述
- 添加供 LLM 填充的工具调用参数,例如给下一个代理的任务描述
- 更改交接时传递给子代理的数据:默认情况下,
create_handoff_tool
会传递完整的消息历史(截至当前在监督者中生成的所有消息),以及指示交接成功的工具消息。
以下是向 create_supervisor
传递自定义交接工具的示例:
from langgraph_supervisor import create_handoff_tool
workflow = create_supervisor(
[research_agent, math_agent],
tools=[
create_handoff_tool(agent_name="math_expert", name="assign_to_math_expert", descriptinotallow="Assign task to math expert"),
create_handoff_tool(agent_name="research_expert", name="assign_to_research_expert", descriptinotallow="Assign task to research expert")
],
model=model,
)
您还可以控制是否将交接工具调用消息添加到状态中。默认情况下会添加(add_handoff_messages=True
),但如果需要更简洁的历史记录,可以禁用:
workflow = create_supervisor(
[research_agent, math_agent],
model=model,
add_handoff_messages=False)
此外,您可以自定义自动生成的交接工具的前缀:
workflow = create_supervisor(
[research_agent, math_agent],
model=model,
handoff_tool_prefix="delegate_to")
# 这将创建名为:delegate_to_research_expert, delegate_to_math_agent 的工具
以下是自定义交接工具的示例代码:
from typing import Annotated
from langchain_core.tools import tool, InjectedToolCallId
from langgraph.prebuilt import InjectedState
from langgraph.graph import StateGraph, START, MessagesState, END
from langgraph.types import Command
from IPython.display import display, Image
def create_handoff_tool(*, agent_name: str, description: str | None = None):
name = f"transfer_to_{agent_name}"
description = description orf"Ask {agent_name} for help."
@tool(name, descriptinotallow=description)
def handoff_tool(
state: Annotated[MessagesState, InjectedState],
tool_call_id: Annotated[str, InjectedToolCallId],
) -> Command:
tool_message = {
"role": "tool",
"content": f"Successfully transferred to {agent_name}",
"name": name,
"tool_call_id": tool_call_id,
}
return Command(
goto=agent_name,
update={**state, "messages": state["messages"] + [tool_message]},
graph=Command.PARENT,
)
return handoff_tool
# 交接工具定义
assign_to_research_agent = create_handoff_tool(
agent_name="research_agent",
descriptinotallow="Assign task to a researcher agent.",
)
assign_to_math_agent = create_handoff_tool(
agent_name="math_agent",
descriptinotallow="Assign task to a math agent.",
)
# 监督者代理创建
supervisor_agent = create_react_agent(
model="openai:gpt-4o-mini",
tools=[assign_to_research_agent, assign_to_math_agent],
prompt=(
"You are a supervisor managing two agents:\n"
"- a research agent. Assign research-related tasks to this agent\n"
"- a math agent. Assign math-related tasks to this agent\n"
"Assign work to one agent at a time, do not call agents in parallel.\n"
"Do not do any work yourself."
),
name="supervisor",
)
# 定义多代理监督者图
supervisor = (
StateGraph(MessagesState)
# 注意:`destinations` 仅用于可视化,不影响运行时行为
.add_node(supervisor_agent, destinatinotallow=("research_agent", "math_agent", END))
.add_node(research_agent)
.add_node(math_agent)
.add_edge(START, "supervisor")
# 始终返回监督者
.add_edge("research_agent", "supervisor")
.add_edge("math_agent", "supervisor")
.compile())
display(Image(supervisor.get_graph().draw_mermaid_png()))
输出:
for chunk in supervisor.stream(
{
"messages": [
{
"role": "user",
"content": "find US and New York state GDP in 2024. what % of US GDP was New York state?",
}
]
},
):
pretty_print_messages(chunk, last_message=True)
final_message_history = chunk["supervisor"]["messages"]
Update from node supervisor:
================================= Tool Message =================================
Name: transfer_to_research_agent
Successfully transferred to research_agent
Update from node research_agent:
================================== Ai Message ==================================
Name: research_agent
- US GDP in 2024: Approximately $28.18 trillion USD (Statista).
- New York State GDP in 2024: The specific GDP number for New York State in 2024 has not been directly located, but relevant forecasts are provided in the state assembly reports.
For calculations regarding the percentage of the US GDP that New York State comprises, specific figures would need to be sourced.
Update from node supervisor:
================================= Tool Message =================================
Name: transfer_to_math_agent
Successfully transferred to math_agent
Update from node math_agent:
================================== Ai Message ==================================
Name: math_agent
5.93%
Update from node supervisor:
================================== Ai Message ==================================
Name: supervisor
In 2024, the approximate GDP of the United States is $28.18 trillion USD. New York State's GDP is estimated to be around $1.671 trillion USD. Therefore, New York State contributes about 5.93% of the total US GDP.
我们已获得上述 final_message_history
。现在,查看完整的消息历史结果:
for message in final_message_history:
message.pretty_print()
输出:
================================ Human Message =================================
find US and New York state GDP in 2024. what % of US GDP was New York state?
================================== Ai Message ==================================
Name: supervisor
Tool Calls: transfer_to_research_agent (call_9Innk7roc0BYXdvTnvljH267) Call ID: call_9Innk7roc0BYXdvTnvljH267
Args:
================================= Tool Message =================================
Name: transfer_to_research_agent
Successfully transferred to research_agent
================================== Ai Message ==================================
Name: research_agent
Tool Calls: tavily_search_results_json (call_6rXCVDfY6Rg9FiWHsxbyBxQG) Call ID: call_6rXCVDfY6Rg9FiWHsxbyBxQG
Args:
query: US GDP 2024 forecast
tavily_search_results_json (call_hAsCKkl3tMIFwixTTp7eh0zt) Call ID: call_hAsCKkl3tMIFwixTTp7eh0zt
Args:
query: New York state GDP 2024 forecast
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "GDP forecast U.S. 2034 - Statista", "url": "https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/", "content": "[](https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/#statisticContainer) This graph shows a forecast of the gross domestic product of the United States of America for fiscal years 2024 to 2034. GDP refers to the market value of all final goods and services produced within a country in a given period. According to the CBO, the United States GDP will increase steadily over the next decade from 28.18 trillion U.S. dollars in 2023 to 41.65 trillion U.S. dollars in [...] * [Economy & Politics](https://www.statista.com/markets/2535/economy-politics/)›\n* [Economy](https://www.statista.com/markets/2535/topic/970/economy/)\n\nU.S. GDP forecast 2024-2034\n===========================\n\n Published by \n\n[Abigail Tierney](https://www.statista.com/aboutus/our-research-commitment/3508/abigail-tierney), \n\n Jul 5, 2024 [...] .%20dollars)%C2%A0https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/)[](mailto:?subject=Statista%C2%A0-%C2%A0Forecast%20of%20the%20gross%20domestic%20product%20of%20the%20United%20States%20from%20fiscal%20year%2024%20%20to%20fiscal%20year%202034%20(in%20billion%20U.S.%20dollars)&body=This%20graph%20shows%20a%20forecast%20of%20the%20gross%20domestic%20product%20of%20the%20United%20States%20of%20America%20for%20fiscal%20years%2024%20to%202034", "score": 0.9245858}, {"title": "United States GDP Growth Rate - Trading Economics", "url": "https://tradingeconomics.com/united-states/gdp-growth", "content": "| [GDP from Services](https://tradingeconomics.com/united-states/gdp-from-services) | 17050.50 | 16949.30 | USD Billion | Dec 2024 |\n| [GDP from Transport](https://tradingeconomics.com/united-states/gdp-from-transport) | 730.50 | 721.40 | USD Billion | Dec 2024 |\n| [GDP from Utilities](https://tradingeconomics.com/united-states/gdp-from-utilities) | 350.80 | 341.40 | USD Billion | Dec 2024 | [...] | [GDP from Manufacturing](https://tradingeconomics.com/united-states/gdp-from-manufacturing) | 2406.80 | 2402.80 | USD Billion | Dec 2024 |\n| [GDP from Mining](https://tradingeconomics.com/united-states/gdp-from-mining) | 343.60 | 337.60 | USD Billion | Dec 2024 |\n| [GDP from Public Administration](https://tradingeconomics.com/united-states/gdp-from-public-administration) | 2653.10 | 2635.50 | USD Billion | Dec 2024 | [...] | [Gross Fixed Capital Formation](https://tradingeconomics.com/united-states/gross-fixed-capital-formation) | 4346.50 | 4265.90 | USD Billion | Mar 2025 |\n| [Gross National Product](https://tradingeconomics.com/united-states/gross-national-product) | 23620.90 | 23427.70 | USD Billion | Dec 2024 |\n| [Real Consumer Spending](https://tradingeconomics.com/united-states/real-consumer-spending) | 1.20 | 4.00 | percent | Mar 2025 |", "score": 0.8458536}, {"title": "A post-cycle economy faces greater policy uncertainty", "url": "https://am.jpmorgan.com/us/en/asset-management/adv/insights/market-insights/investment-outlook/us-economic-outlook/", "content": "This year, the economy saw surprisingly robust growth with real GDP on track to expand at a 1.8% annualized rate in the fourth quarter, closing 2024 with 2.3% annual growth, by our estimates. The biggest driver of this strength has been consumer spending, which contributed an average 78% of real GDP growth in the first three quarters. Despite pushing back on high retail prices, a thriftier consumer managed to stretch their budget and still expand their shopping cart. Inflation-adjusted consumer", "score": 0.83290404}]
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "Annual State of the City's Economy and Finances 2024", "url": "https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/", "content": "[[1]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref1) At that time, the Comptroller’s Office expected five-year cumulative real GDP growth, 2020 to 2024, of 8.7 percent while the mayor expected 9.5 percent.\n\n[[2]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref2) U.S. Bureau of Labor Statistics Local Area Unemployment Statistics (LAUS). [...] Nationally, the economy is expected to grow by 2.3 percent in 2025, stronger than the 1.6 percent that was last forecast in May, according to the Office of the New York City Comptroller’s forecast. Short-term interest rates are projected to decline more rapidly over the next few years, reaching 3 percent by early 2026, while inflation remains near targeted levels. Average wages and overall employment levels in New York City are estimated to have been stronger than had been forecast in 2024. The [...] (constant 2019 dollars)**22,550 15,322 13,596 19,451 21,211 21,096\n**_% change_**(32.1%)(11.3%)43.1%9.0%(0.5%)\n\nSource: NY State Department of Taxation and Finance and Office of the New York City Comptroller", "score": 0.882276}, {"title": "New York by the Numbers Monthly Economic and Fiscal Outlook", "url": "https://comptroller.nyc.gov/newsroom/newsletter/new-york-by-the-numbers-monthly-economic-and-fiscal-outlook-no-101-may-2025/", "content": "| A | Current (2024-25) | Year Earlier (2023-24) | Pre-Pandemic* | E |\n| --- | --- | --- | --- | --- |\n| Jan-24 | 1,335 | 1,810 | 1,307 | |\n| Feb-24 | 1,937 | 1,292 | 1,316 | |\n| Mar-24 | 1,641 | 1,232 | 884 | |\n| Apr-24 | 1,360 | 929 | 947 | |\n| May-24 | 652 | 1,377 | 1,020 | |\n| Jun-24 | 665 | 1,200 | 1,265 | |\n| Jul-24 | 529 | 905 | 1,232 | |\n| Aug-24 | 516 | 754 | 935 | |\n| Sep-24 | 355 | 805 | 806 | |\n| Oct-24 | 375 | 844 | 1,026 | |\n| Nov-24 | 431 | 801 | 1,476 | | [...] | 26-Oct-24 | 5.30% | 12.50% |\n| 2-Nov-24 | 9.40% | 6.90% |\n| 9-Nov-24 | 3.40% | 0.30% |\n| 16-Nov-24 | 6
4.4 消息转发
你可以使用create_forward_message_tool
为 supervisor 配备一个工具,将从 worker 代理接收到的最后一条消息直接转发到图表的最终输出。当 supervisor 确定 worker 的响应已足够,无需进一步处理或总结时,这非常有用。它为 supervisor 节省了 tokens,并避免了通过转述可能导致的 worker 响应的误传。
from langgraph_supervisor.handoff import create_forward_message_tool
# 假设已定义 research_agent 和 math_agent
forwarding_tool = create_forward_message_tool("supervisor") # 该参数是分配给结果转发消息的名称
workflow = create_supervisor(
[research_agent, math_agent],
model=model,
# 将转发工具与任何其他自定义或默认的交接工具一起传递
tools=[forwarding_tool]
)
这将创建一个名为forward_message
的工具,supervisor 可以调用该工具。该工具需要一个参数from_agent
,用于指定应将哪个代理的最后一条消息直接转发到输出。
5. 实现:群模式
以下是使用_langgraph_swarm_库实现群式多代理系统的示例代码,该库构建在 LangGraph 之上,支持专门代理之间的动态协作和交接。
我们将使用与 supervisor 模式中相同的数学代理和研究代理示例。
from langchain_openai import ChatOpenAI
from langgraph.graph import START, END
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import create_react_agent
from langgraph_swarm import create_swarm, create_handoff_tool
from IPython.display import Image, display
import os
# 选择 LLM
model = ChatOpenAI(model="gpt-4o-mini", api_key=os.getenv("OPENAI_API_KEY"))
# 定义工具
def add(a: float, b: float) -> float:
"""添加两个数字。"""
return a + b
def multiply(a: float, b: float):
"""将两个数字相乘。"""
return a * b
def divide(a: float, b: float):
"""将两个数字相除。"""
return a / b
# 群模式的交接工具 - 使用适当的 LangGraph 群交接工具
handoff_to_research_agent = create_handoff_tool(
agent_name="research_agent",
descriptinotallow="将控制权转移给研究代理,以执行与研究相关的任务、网络搜索和信息收集。"
)
handoff_to_math_agent = create_handoff_tool(
agent_name="math_agent",
descriptinotallow="将控制权转移给数学代理,以执行数学计算和计算任务。"
)
tavily_api_key = os.getenv("TAVILY_API_KEY", "your_tavily_api_key")
web_search = TavilySearchResults(max_results=3, tavily_api_key=tavily_api_key)
# 创建 Worker 代理
research_agent = create_react_agent(
model=model,
tools=[web_search, handoff_to_math_agent],
name="research_agent",
prompt=(
"你是一个专门从事网络研究和信息收集的研究代理。\n\n"
"说明:\n"
"- 处理与研究相关的任务、网络搜索和信息收集\n"
"- 不要尝试数学计算 - 任何数学任务都使用 handoff_to_math_agent()\n"
"- 如果用户要求进行数学计算,立即交接给数学代理\n"
"- 完成研究任务后,提供全面的结果\n"
"- 需要数学计算时使用 handoff_to_math_agent()"
)
)
math_agent = create_react_agent(
model=model,
tools=[add, multiply, divide, handoff_to_research_agent],
name="math_agent",
prompt=(
"你是一个专门从事数学计算和计算的数学代理。\n\n"
"说明:\n"
"- 处理数学计算、算术运算和数值分析\n"
"- 不要尝试网络搜索或研究 - 使用 handoff_to_research_agent() 进行研究任务\n"
"- 如果用户要求研究或网络搜索,立即交接给研究代理\n"
"- 完成数学任务后,提供清晰的结果和解释\n"
"- 需要研究或网络搜索时使用 handoff_to_research_agent()"
)
)
swarm_agent = create_swarm(
agents=[research_agent, math_agent],
default_active_agent="math_agent",
).compile()
display(Image(swarm_agent.get_graph().draw_mermaid_png()))
要测试流程:
def test_swarm_functionality():
"""使用特定的 GDP 查询测试群模式,以验证交接。"""
print(f"查询:查找 2024 年美国和纽约州的 GDP。纽约州占美国 GDP 的百分比是多少?")
print("-" * 80)
try:
for chunk in swarm_agent.stream(
{
"messages": [
{
"role": "user",
"content": "find US and New York state GDP in 2024. what % of US GDP was New York state?",
}
]
},
subgraphs=False
):
pretty_print_messages(chunk, last_message=True)
print(f"Test completed successfully")
except Exception as e:
print(f"Test failed with error: {str(e)}")
print("=" * 80)
# 运行
if __name__ == "__main__"orTrue:
test_swarm_functionality()
输出:
查询:查找 2024 年美国和纽约州的 GDP。纽约州占美国 GDP 的百分比是多少?
--------------------------------------------------------------------------------
Update from node math_agent:
================================= Tool Message =================================
Name: transfer_to_research_agent
Successfully transferred to research_agent
Update from node research_agent:
================================= Tool Message =================================
Name: transfer_to_math_agent
Successfully transferred to math_agent
Update from node math_agent:
================================== Ai Message ==================================
Name: math_agent
### Results:
- **U.S. GDP in 2024:** Approximately **$28.18 trillion**
- **New York State GDP in 2024:** Approximately **$2.29 trillion**
- **Percentage of U.S. GDP that is New York State:** Approximately **8.13%**
This means that New York State is projected to contribute about 8.13% of the total GDP of the United States in 2024.
Test completed successfully
================================================================================
6. 运行代理
6.1 调用模式
代理可以通过两种主要模式执行:
- 同步使用
.invoke()
或.stream()
:调用者(用户或系统)等待代理完成任务后再继续。 - 异步使用
await .ainvoke()
或async for
与.astream()
结合:代理接收请求,启动处理,并允许调用者继续其他任务而无需等待响应。结果通常通过回调、通知或轮询机制稍后传递。
同步调用:
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(...)
response = agent.invoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
异步调用:
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(...)
response = await agent.ainvoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
6.2 输入格式
代理使用期望messages
列表作为输入的语言模型。因此,代理的输入和输出存储为代理状态中messages
键下的消息列表。
您可以在输入字典中直接提供代理状态模式中定义的其他字段。这允许基于运行时数据或先前工具输出的动态行为。
代理输入必须是带有messages
键的字典。支持的格式为:
注意:messages
的字符串输入会转换为HumanMessage。此行为不同于create_react_agent
中的prompt
参数,当作为字符串传递时,该参数会被解释为SystemMessage。
6.3 输出格式
代理输出是一个包含以下内容的字典:
-
messages
:执行期间交换的所有消息的列表(用户输入、助手回复、工具调用)。 - 可选的
structured_response
(如果配置了结构化输出)。 - 如果使用自定义
state_schema
,输出中可能还会出现与您定义的字段对应的其他键。这些键可以保存来自工具执行或提示逻辑的更新状态值。
6.4 流式输出
代理支持流式响应,以实现更高的应用响应性。这包括:
- 每一步后的进度更新
- 生成的LLM tokens
- 执行期间的自定义工具消息
流式传输可在同步和异步模式下使用:
同步流式传输:
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode="updates"
):
print(chunk)
我们在之前的示例中使用过此方法。
异步流式传输:
async for chunk in agent.astream(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
stream_mode="updates"
):
print(chunk)
6.5 最大迭代次数
这定义了代理在引发错误之前可以执行的最大步数。我们可以在运行时或通过.with_config()
定义代理时进行定义:
运行时:
from langgraph.errors import GraphRecursionError
from langgraph.prebuilt import create_react_agent
max_iterations = 3
recursion_limit = 2 * max_iterations + 1
agent = create_react_agent(
model="anthropic:claude-3-5-haiku-latest",
tools=[get_weather]
)
try:
response = agent.invoke(
{"messages": [{"role": "user", "content": "what's the weather in sf"}]},
{"recursion_limit": recursion_limit},
)
except GraphRecursionError:
print("Agent stopped due to max iterations.")
.with_config():
from langgraph.errors import GraphRecursionError
from langgraph.prebuilt import create_react_agent
max_iterations = 3
recursion_limit = 2 * max_iterations + 1
agent = create_react_agent(
model="anthropic:claude-3-5-haiku-latest",
tools=[get_weather]
)
agent_with_recursion_limit = agent.with_config(recursion_limit=recursion_limit)
try:
response = agent_with_recursion_limit.invoke(
{"messages": [{"role": "user", "content": "what's the weather in sf"}]},
)
except GraphRecursionError:
print("Agent stopped due to max iterations.")
7. 隐藏的障碍
至于协调多个代理的挑战,以下几点值得密切关注:
研究人员考察了五个流行的 MAS 框架,涵盖超过 150 项任务,并结合了六位专家注释者的见解。他们确定了 14 种不同的失败模式,这些模式分为三个主要类别:
- 规范和系统设计失败:由不明确的任务定义或设计不良的系统架构引起的问题。
- 代理间不一致:由代理之间的沟通不畅或缺乏协调导致的问题。
- 任务验证和终止:与验证过程不足和任务完成协议不当相关的失败。
8. 突破障碍
为解决这些挑战,作者探索了两种主要干预措施:
- 改进代理角色的规范:提高代理角色的清晰度和准确性,以防止误解和重叠。
- 增强协调策略:开发更好的代理间协调机制,以简化交互和任务执行。
例如,Anthropic 宣布了模型上下文协议 (MCP),这是针对 AI 系统和流程如何相互集成的首个行业标准尝试。如果开发人员遵循推荐的代理模式,像这样的开源标准可能会对上述每个问题产生积极影响。
Google 于 2025 年 4 月 9 日推出的Agent2Agent (A2A) 协议,使 AI 代理能够使用基于 JSON 的“代理卡”描述其功能、输入和身份验证方案,跨不同平台进行通信和协作。A2A 和 MCP 相互补充:A2A 促进代理之间的互操作性(横向集成),而 MCP 为代理提供工具访问(纵向集成)。例如,两个代理可能使用 A2A 协作完成任务,同时各自利用 MCP 查询外部数据源,从而创建无缝的多代理生态系统。
9. 构建可扩展 AI 代理的路线图
将单体系统与代理系统区分开来的核心概念是其推理和正确使用工具的能力。
但如果没有适当的路线图,构建这些系统可能会非常混乱。
1. 选择您的模型选择具备以下特点的 LLM:
- 擅长推理和逻辑处理
- 支持逐步思考(思维链)
- 提供稳定一致的输出提示:从 Llama、Claude Opus 或 Mistral 等模型开始(开源权重提供更大的自定义和控制权)。
2. 设计代理的推理过程定义代理处理任务的方式:
- 回答前是否应暂停并思考?
- 应逐步规划行动还是立即行动?
- 需要额外帮助时是否应调用工具?提示:从简单的策略开始,如 ReAct 或先计划后执行框架。
3. 制定操作指南设定明确的交互规则:
- 定义响应行为和语气
- 指定何时使用外部工具
- 标准化响应格式(例如 JSON、markdown)提示:将此视为代理的内部操作协议。
4. 融入记忆通过以下方式弥补 LLM 缺乏长期记忆的问题:
- 对近期上下文应用滑动窗口记忆
- 总结过去的对话
- 持久化关键信息(用户偏好、决策)提示:MemGPT 或 ZepAI 等工具可以简化记忆管理。
5. 集成工具和 API使代理能够采取实际行动:
- 检索外部数据
- 更新 CRM 和数据库
- 执行计算或转换提示:使用 MCP 将工具无缝即插即用地集成到代理工作流程中。
6. 分配明确的目标为代理提供具体任务:“总结用户反馈并推荐改进措施”“提供帮助”提示: 专注于缩小工作范围——定义代理不应该做什么比留下开放式指令更有效。
7. 扩展到多代理团队创建协作的专门代理:
- 一个代理收集信息
- 另一个解释数据
- 第三个格式化并呈现结果提示:具有明确范围角色的工作专业化可打造更有效的多代理系统。
Reference
[1] 知乎【柏企】: https://www.zhihu.com/people/cbq-91
[2] 个人网站: https://www.chenbaiqi.com
本文转载自柏企阅文,作者:tailet
