在智能体开发过程中,我们常常会遇到这样的困境:当单个智能体需要同时处理多个领域的任务(如同时管理航班预订和酒店预订)时,其处理效率和专业性会大幅下降。是让单个智能体强行兼容多领域?还是寻找更合理的架构方案?今天我们就来聊聊 LangGraph 中的多智能体系统,看看如何通过分解任务到独立智能体,再组合成高效协作的系统,解决这一现实挑战。
想象一下,一个客服智能体既要处理产品咨询,又要负责订单查询,还要处理售后问题,这样的 "全能型" 智能体往往会因为任务复杂而出现响应延迟或错误。多智能体系统的核心思想就是 "分而治之":将复杂任务分解为多个专业子任务,每个子任务由专门的智能体处理,再通过协调机制实现整体协作。
LangGraph 中的多智能体系统具有以下显著优势:
LangGraph 支持两种最受欢迎的多智能体架构,它们就像两种不同的团队管理模式:
监督式多智能体系统就像一个公司的管理层:有一个总经理(监督智能体)负责接收所有任务,然后根据任务性质分配给不同的部门(子智能体)。这种架构的核心在于中央监督智能体的决策逻辑,它需要能够:
下面我们通过一个旅行预订的例子,看看如何使用 langgraph-supervisor 库创建监督式多智能体系统:
python
# 首先安装必要的库
# pip install langgraph-supervisor langchain-openai
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langgraph_supervisor import create_supervisor
# 定义航班预订工具
def book_flight(from_airport: str, to_airport: str):
"""预订航班"""
return f"成功预订从{from_airport}到{to_airport}的航班"
# 定义酒店预订工具
def book_hotel(hotel_name: str):
"""预订酒店"""
return f"成功预订{hotel_name}酒店"
# 创建航班预订智能体
flight_assistant = create_react_agent(
model="openai:gpt-4o",
tools=[book_flight],
prompt="你是一个航班预订助手",
name="flight_assistant"
)
# 创建酒店预订智能体
hotel_assistant = create_react_agent(
model="openai:gpt-4o",
tools=[book_hotel],
prompt="你是一个酒店预订助手",
name="hotel_assistant"
)
# 创建监督智能体
supervisor = create_supervisor(
agents=[flight_assistant, hotel_assistant],
model=ChatOpenAI(model="gpt-4o"),
prompt=(
"你管理着一个酒店预订助手和一个航班预订助手。请根据用户需求分配工作。"
)
).compile()
# 测试多智能体系统
print("用户请求: 预订从波士顿到纽约的航班和麦克基特里克酒店的住宿")
for chunk in supervisor.stream(
{
"messages": [
{
"role": "user",
"content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
}
]
}
):
print(chunk)
print("\n")
监督式架构特别适合以下场景:
群体式多智能体系统的灵感来源于自然界的群体行为(如蚁群、鸟群),没有中央控制者,每个智能体根据自身规则和环境状态自主决策。在 LangGraph 中,群体式架构的核心是 "交接(Handoff)" 机制:
这种架构就像一个专业团队,成员之间根据专长自然协作:当遇到财务问题时,自动转交给财务专家;遇到技术问题时,转交给技术专家,无需层层上报。
下面我们使用 langgraph-swarm 库创建一个群体式多智能体系统:
python
# 安装必要的库
# pip install langgraph-swarm
from langgraph.prebuilt import create_react_agent
from langgraph_swarm import create_swarm, create_handoff_tool
# 创建交接工具:转交给酒店预订助手
transfer_to_hotel_assistant = create_handoff_tool(
agent_name="hotel_assistant",
description="将用户转交给酒店预订助手"
)
# 创建交接工具:转交给航班预订助手
transfer_to_flight_assistant = create_handoff_tool(
agent_name="flight_assistant",
description="将用户转交给航班预订助手"
)
# 定义工具函数
def book_flight(from_airport: str, to_airport: str):
"""预订航班"""
return f"成功预订从{from_airport}到{to_airport}的航班"
def book_hotel(hotel_name: str):
"""预订酒店"""
return f"成功预订{hotel_name}酒店"
# 创建航班预订智能体,包含转交工具
flight_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_flight, transfer_to_hotel_assistant],
prompt="你是一个航班预订助手",
name="flight_assistant"
)
# 创建酒店预订智能体,包含转交工具
hotel_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_hotel, transfer_to_flight_assistant],
prompt="你是一个酒店预订助手",
name="hotel_assistant"
)
# 创建群体智能体系统
swarm = create_swarm(
agents=[flight_assistant, hotel_assistant],
default_active_agent="flight_assistant"
).compile()
# 测试群体智能体系统
print("用户请求: 预订从波士顿到纽约的航班和麦克基特里克酒店的住宿")
for chunk in swarm.stream(
{
"messages": [
{
"role": "user",
"content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
}
]
}
):
print(chunk)
print("\n")
群体式架构更适合以下场景:
交接(Handoff)是多智能体系统中智能体之间通信的基本原语,它包含两个关键要素:
在 LangGraph 中,交接机制同时支持监督式和群体式架构,但实现方式略有不同:
下面我们深入了解如何自定义交接工具,这是实现灵活多智能体系统的关键:
python
from typing import Annotated
from langchain_core.tools import tool, InjectedToolCallId
from langgraph.prebuilt import create_react_agent, InjectedState
from langgraph.graph import StateGraph, START, MessagesState
from langgraph.types import Command
def create_handoff_tool(*, agent_name: str, description: str | None = None):
"""创建自定义交接工具的工厂函数"""
name = f"transfer_to_{agent_name}"
description = description or f"转交给{agent_name}"
@tool(name, description=description)
def handoff_tool(
state: Annotated[MessagesState, InjectedState],
tool_call_id: Annotated[str, InjectedToolCallId],
) -> Command:
# 创建工具消息,记录交接动作
tool_message = {
"role": "tool",
"content": f"成功转交给{agent_name}",
"name": name,
"tool_call_id": tool_call_id,
}
# 返回Command对象,指定交接目标和传递的消息
return Command(
goto=agent_name, # 目标智能体名称
update={"messages": state["messages"] + [tool_message]}, # 传递消息历史
graph=Command.PARENT, # 指示在父图中导航
)
return handoff_tool
# 创建具体的交接工具
transfer_to_hotel_assistant = create_handoff_tool(
agent_name="hotel_assistant",
description="将用户转交给酒店预订助手"
)
transfer_to_flight_assistant = create_handoff_tool(
agent_name="flight_assistant",
description="将用户转交给航班预订助手"
)
# 定义工具函数
def book_hotel(hotel_name: str):
"""预订酒店"""
return f"成功预订{hotel_name}酒店"
def book_flight(from_airport: str, to_airport: str):
"""预订航班"""
return f"成功预订从{from_airport}到{to_airport}的航班"
# 创建智能体并添加交接工具
flight_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_flight, transfer_to_hotel_assistant],
prompt="你是一个航班预订助手",
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_hotel, transfer_to_flight_assistant],
prompt="你是一个酒店预订助手",
name="hotel_assistant"
)
# 定义多智能体图
multi_agent_graph = (
StateGraph(MessagesState)
.add_node(flight_assistant)
.add_node(hotel_assistant)
.add_edge(START, "flight_assistant") # 设置起始智能体
.compile()
)
# 运行多智能体系统
print("用户请求: 预订从波士顿到纽约的航班和麦克基特里克酒店的住宿")
for chunk in multi_agent_graph.stream(
{
"messages": [
{
"role": "user",
"content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
}
]
}
):
print(chunk)
print("\n")
在使用上述交接实现时,需要注意 LangGraph 的两个关键假设:
选择监督式架构:
选择群体式架构:
通过本文的解析,我们深入了解了 LangGraph 多智能体系统的两种核心架构 —— 监督式和群体式,以及关键的交接机制。从集中式协调到去中心化协作,多智能体系统为复杂任务的分解与协作提供了高效解决方案。
如果本文对你有帮助,别忘了点赞收藏,关注我,一起探索更高效的开发方式~