
AI Agents-8 | 构建Muti-Agent系统 原创
在 AI 的世界里,智能体(Agent)就像是一个个拥有独立思考能力的小机器人,它们能够根据任务需求做出决策、执行操作,甚至与其他智能体协作完成复杂的任务。今天,就让我们一起走进多智能体架构的世界,看看这些“变形金刚”是如何通过不同的模式和策略,为我们的生活和工作带来巨大变革的。
一、智能体的价值:从复杂任务中脱颖而出
当我们思考智能体能够为哪些场景带来价值时,不妨先看看那些传统自动化方法难以触及的领域:
- 复杂决策:那些需要细腻判断、处理异常情况或者依赖上下文的任务,比如在客户服务流程中决定是否批准退款。
- 难以维护的规则:当系统因为庞大的规则集变得难以更新,且每次更新都可能引入错误时,智能体或许能提供更灵活的解决方案。例如,对供应商进行安全审查时,复杂的规则判断往往让人头疼。
- 依赖非结构化数据:如果任务涉及自然语言理解、文档内容提取或者与用户进行对话交互,那么智能体可能就是最佳选择。比如处理家庭保险索赔时,需要理解和处理大量的文本信息。
在决定开发智能体之前,一定要明确你的用例是否符合这些场景。如果不符合,可能传统的确定性解决方案就已经足够了。
二、智能体设计的三大核心组件
智能体虽然功能强大,但它的基本构成其实并不复杂,主要包括以下三个核心部分:
(一)模型:智能体的“大脑”
模型是驱动智能体推理和决策的大语言模型(LLM)。不同的模型有不同的优势,比如有的模型擅长处理复杂的任务,而有的模型则在速度和成本上更具优势。并不是所有任务都需要最强大的模型,简单的任务(如检索信息或意图分类)可以用较小、较快的模型来完成,而复杂的任务(如决定是否批准退款)则可能需要更强大的模型。
一个实用的方法是:先用最强大的模型为每个任务构建智能体原型,以此建立性能基线。然后,尝试用更小的模型替换,看看是否仍能达到可接受的结果。这样既不会过早限制智能体的能力,也能帮助你诊断出哪些任务可以用小模型完成,哪些不行。
选择模型的原则其实很简单:
- 设置评估来建立性能基线。
- 用最好的模型来达到你的准确率目标。
- 在可能的情况下,用更小的模型替换大模型,以优化成本和延迟。
(二)工具:智能体的“手脚”
工具是智能体用来执行操作的外部函数或 API。通过调用这些工具,智能体可以与外部世界进行交互。例如,一个智能体可以调用一个 API 来获取天气信息,或者调用一个数据库接口来存储数据。
工具的定义应该是标准化的,这样可以实现智能体与工具之间的灵活、多对多的关系。工具的文档清晰、经过充分测试且可复用,能够提高工具的可发现性,简化版本管理,并避免重复定义。
一般来说,智能体需要以下三种类型的工具:
- 信息获取工具:用于从外部获取信息,如搜索引擎、数据库查询工具等。
- 数据处理工具:用于对数据进行处理和分析,如数据清洗、统计分析工具等。
- 交互工具:用于与用户或其他系统进行交互,如聊天界面、API 调用工具等。
(三)指令:智能体的行为准则
指令是明确指导智能体行为的规则和限制。高质量的指令对于任何基于 LLM 的应用都至关重要,尤其是对于智能体来说。清晰的指令可以减少歧义,提高智能体的决策能力,从而使工作流程更加顺畅,减少错误。
你可以使用先进的模型(如 o1 或 o3-mini)来自动生成指令,也可以手动编写指令。以下是一个自动生成指令的示例:
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from langgraph.graph import StateGraph, START, END
from langgraph.types import Command
from IPython.display import display, Image
# 定义一个简单的工具
@tool
def get_weather(location: str) -> str:
"""获取指定地点的天气信息"""
returnf"{location} 的天气是晴天"
# 创建智能体
agent = create_react_agent(
model="gpt-4o-mini",
tools=[get_weather],
name="weather_agent",
prompt=(
"You are a weather agent.\n\n"
"INSTRUCTIONS:\n"
"- Assist ONLY with weather-related tasks\n"
"- After you're done with your tasks, respond directly to the user\n"
"- Respond ONLY with the results of your work, do NOT include ANY other text."
)
)
三、协同作战:多智能体的编排模式
当智能体的基本组件准备就绪后,接下来要考虑的就是如何让它们协同工作,以高效地执行工作流程。多智能体系统可以被建模为一个图,其中智能体是节点,而节点之间的边则代表智能体之间的交互。
常见的编排模式包括:
(一)集中式模式:监督者说了算
在这种模式下,所有智能体都由一个监督者(Supervisor)智能体来管理和协调。监督者根据任务需求,将任务分配给不同的智能体,并收集它们的输出结果。这种模式的优点是管理集中,易于控制,但缺点是监督者可能会成为瓶颈。
(二)去中心化模式:智能体之间的“接力棒”
在这种模式下,智能体之间可以直接进行“交接”(Handoff),将任务的执行权从一个智能体转移到另一个智能体。这种模式的优点是灵活性高,智能体之间的协作更加自然,但缺点是可能会导致控制流的混乱。
(三)层次化模式:分级管理,各司其职
在这种模式下,智能体被组织成一个层次化的结构,每个层级的智能体负责管理下一层级的智能体。这种模式的优点是能够更好地应对复杂的任务,但缺点是层级过多可能会导致信息传递的延迟。
四、实战演练:构建一个监督者模式的多智能体系统
接下来,让我们通过一个具体的例子来感受一下多智能体系统的魅力。我们将构建一个监督者模式的多智能体系统,用来解答一个关于 GDP 的问题。
(一)准备工作
首先,我们需要安装必要的库,并设置 OpenAI 的 API 密钥:
pip install langgraph-supervisor langchain-openai
import os
os.environ["OPENAI_API_KEY"] = "<your_api_key>"
(二)定义智能体和工具
接下来,我们定义两个智能体:一个研究智能体(Research Agent),负责进行网络搜索和信息收集;一个数学智能体(Math Agent),负责进行数学计算。
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
# 选择 LLM
model = ChatOpenAI(model="gpt-4o", api_key=os.getenv("OPENAI_API_KEY"))
# 定义工具
def add(a: float, b: float) -> float:
"""加法"""
return a + b
def multiply(a: float, b: float) -> float:
"""乘法"""
return a * b
def divide(a: float, b: float) -> float:
"""除法"""
return a / b
# 创建研究智能体
research_agent = create_react_agent(
model=model,
tools=[TavilySearchResults(max_results=3, tavily_api_key=os.getenv("TAVILY_API_KEY"))],
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()
(四)运行测试
最后,我们来测试一下这个多智能体系统是否能够正确地回答问题:
def test_supervisor_functionality():
"""测试监督者模式的功能"""
print("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
):
print(chunk)
print("Test completed successfully")
except Exception as e:
print(f"Test failed with error: {str(e)}")
print("=" * 80)
if __name__ == "__main__":
test_supervisor_functionality()
运行测试后,我们可以看到智能体们是如何一步步协作完成任务的:
- 监督者智能体将任务分配给研究智能体,研究智能体进行网络搜索,收集关于美国和纽约州 GDP 的信息。
- 研究智能体将收集到的信息传递给监督者智能体,监督者智能体再将任务分配给数学智能体,数学智能体进行计算,得出纽约州 GDP 占美国 GDP 的百分比。
- 最终,监督者智能体将结果呈现给用户。
五、智能体的“记忆管理”:消息历史的控制
在多智能体系统中,每个智能体的消息历史管理是非常重要的。你可以选择将智能体的完整消息历史添加到整个系统的对话历史中,也可以只添加智能体的最终响应。
例如,如果你想保留完整的历史记录,可以在创建监督者时设置 output_mode="full_history"
;如果你想只保留最终响应,可以设置 output_mode="last_message"
。
supervisor = create_supervisor(
agents=[agent1, agent2],
output_mode="last_message"
)
六、多层级架构:构建“智能体的团队”
你可以通过创建管理多个监督者的监督者,来构建多层级的架构。例如,你可以创建一个研究团队和一个写作团队,每个团队都有自己的监督者,然后创建一个顶层监督者来管理这两个团队。
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")
七、自定义交接工具:让智能体的“交接”更灵活
默认情况下,监督者使用预定义的交接工具来在智能体之间传递任务。你也可以自定义这些交接工具,例如修改工具的名称和描述,或者添加工具调用的参数。
以下是一个自定义交接工具的示例:
from langgraph_supervisor import create_handoff_tool
# 创建一个自定义的交接工具
assign_to_research_agent = create_handoff_tool(
agent_name="research_agent",
descriptinotallow="Assign task to a researcher agent.",
)
# 将自定义工具传递给监督者
supervisor_agent = create_react_agent(
model="openai:gpt-4o-mini",
tools=[assign_to_research_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",
)
八、实战演练:构建一个“蜂群模式”的多智能体系统
除了监督者模式,我们还可以构建一个“蜂群模式”的多智能体系统。在这种模式下,智能体之间可以直接进行交互和协作,而不需要一个中央监督者来协调。
以下是一个使用 langgraph_swarm
库构建蜂群模式的示例:
from langgraph_swarm import create_swarm, create_handoff_tool
# 创建蜂群模式的智能体
swarm_agent = create_swarm(
agents=[research_agent, math_agent],
default_active_agent="math_agent",
).compile()
# 测试蜂群模式的功能
def test_swarm_functionality():
print("Query: find US and New York state GDP in 2024. what % of US GDP was New York state?")
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
):
print(chunk)
print("Test completed successfully")
except Exception as e:
print(f"Test failed with error: {str(e)}")
print("=" * 80)
if __name__ == "__main__":
test_swarm_functionality()
九、智能体的“召唤”:调用模式与输入输出格式
智能体可以通过同步或异步的方式被调用。同步调用会阻塞调用者,直到智能体完成任务;而异步调用则允许调用者在智能体处理任务的同时继续执行其他任务。
(一)同步调用
response = agent.invoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
(二)异步调用
response = await agent.ainvoke({"messages": [{"role": "user", "content": "what is the weather in sf"}]})
智能体的输入是一个包含消息列表的字典,消息列表中每个消息都是一个字典,包含角色(如用户或助手)和内容。智能体的输出也是一个字典,包含消息列表和可能的结构化响应。
此外,智能体还支持流式响应,可以在处理过程中逐步返回结果,这对于需要实时交互的应用非常有用。
十、智能体的“成长之路”:构建可扩展智能体的路线图
构建可扩展的智能体系统并不是一件容易的事,但以下路线图或许能为你提供一些思路:
(一)选择合适的模型
选择一个擅长推理和逻辑处理的 LLM,支持逐步思考,并且输出稳定一致。可以从 Llama、Claude Opus 或 Mistral 等开源模型开始,它们提供了更大的定制化和控制能力。
(二)设计智能体的推理过程
定义智能体如何处理任务,例如是否在回答前暂停并反思,是否逐步规划行动,或者是否在需要帮助时调用工具。可以从简单的 ReAct 或 Plan-then-Execute 框架开始。
(三)建立操作指南
为智能体设定清晰的交互规则,包括响应行为、语气、何时使用外部工具以及标准化响应格式(如 JSON 或 Markdown)。
(四)整合记忆
补偿 LLM 缺乏长期记忆的问题,例如应用滑动窗口记忆以保留最近的上下文,总结过去的对话,以及持久化关键信息(如用户偏好、决策等)。可以使用 MemGPT 或 ZepAI 等工具简化记忆管理。
(五)集成工具和 API
使智能体能够执行实际操作,例如检索外部数据、更新 CRM 和数据库、执行计算或转换。可以使用 MCP(Model Context Protocol)无缝地将工具集成到智能体工作流中。
(六)分配明确的目标
为智能体提供具体任务,例如“总结用户反馈并推荐改进”,而不是模糊的“提供帮助”。专注于缩小工作范围——定义智能体不应该做什么,而不是让指令过于开放。
(七)扩展到多智能体团队
创建具有明确角色的智能体团队,例如一个智能体收集信息,另一个智能体解释数据,第三个智能体格式化并呈现结果。明确的角色分工将使多智能体系统更加高效。
十一、智能体的“挑战与突破”:面对困难,勇往直前
尽管智能体系统带来了巨大的潜力,但也面临着一些挑战。研究人员在 150 多个任务中测试了 5 种流行的多智能体系统框架,并从 6 位专家标注者的见解中识别出 14 种不同的失败模式,这些失败模式被分为以下三大类:
(一)规范和系统设计失败
由于任务定义不清晰或系统架构设计不佳而导致的问题。
(二)智能体之间的不协调
由于智能体之间的沟通不畅或缺乏协调而导致的问题。
(三)任务验证和终止失败
由于验证流程不足或任务完成协议不当而导致的问题。
为了应对这些挑战,研究人员探索了以下两种主要干预措施:
(一)改进智能体角色的规范
提高智能体角色的清晰度和精确度,以防止误解和重叠。
(二)增强编排策略
开发更好的协调机制,以简化智能体之间的互动和任务执行。
例如,Anthropic 公司宣布了模型上下文协议(MCP),这是首次尝试为 AI 系统和流程之间的集成制定行业标准。如果开发者遵循推荐的智能体模式,这样的开源标准可能会对上述提到的每个问题产生积极影响。
谷歌于 2025 年 4 月 9 日推出的 Agent2Agent(A2A)协议,使 AI 智能体能够使用基于 JSON 的“智能体卡片”在不同平台之间进行通信和协作,这些卡片描述了它们的能力、输入和认证方案。A2A 和 MCP 互为补充:A2A 促进了智能体之间的互操作性(水平集成),而 MCP 为智能体提供了工具访问权限(垂直集成)。例如,两个智能体可以使用 A2A 协议协作完成任务,同时分别利用 MCP 查询外部数据源,从而创建一个无缝的多智能体生态系统。
十二、结语:开启智能体的无限可能
你已经走过了构建可扩展智能体系统的艺术与科学之旅,从基础设计到突破隐藏的障碍!现在,轮到你来掌控全局了。不妨思考一下:你的下一个智能体将由哪种模型驱动——快速简单的模型还是强大复杂的模型?监督者模式或蜂群模式将如何改变你项目的效率?你是否可以利用我们探索过的异步处理模式来为你的用例解锁新的潜力?
构建可扩展智能体系统的路线图就在你手中,但挑战依然存在。你预见到你的设计或实施中会有哪些障碍吗?在评论区分享你的想法吧——告诉我们你将如何定制交接工具或调整迭代以取得成功!尝试从编排到流式传输的各种策略,并加入创新者社区,共同突破界限,构建适应性强、强大的智能体系统。你的可扩展解决方案现在就开始——你的下一步是什么?
本文转载自Halo咯咯 作者:基咯咯
