多智能体¶
单个智能体如果需要在多个领域进行专业化或管理许多工具,可能会感到吃力。为了解决这个问题,您可以将您的智能体分解为更小、独立的智能体,并将它们组合成一个多智能体系统。
在多智能体系统中,智能体需要相互通信。它们通过移交进行通信——移交是一种原语,描述将控制权移交给哪个智能体以及发送给该智能体的有效载荷。
两种最流行的多智能体架构是:
- 监督者——由一个中心监督者智能体协调各个智能体。监督者控制所有通信流和任务委托,根据当前上下文和任务需求决定调用哪个智能体。
- 群集——智能体根据其专业化动态地相互移交控制权。系统会记住上次活动的智能体,确保在后续交互中,对话与该智能体继续进行。
监督者¶
使用 langgraph-supervisor
库创建监督者多智能体系统
API 参考:ChatOpenAI | create_react_agent | create_supervisor
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langgraph_supervisor import create_supervisor
def book_hotel(hotel_name: str):
"""Book a hotel"""
return f"Successfully booked a stay at {hotel_name}."
def book_flight(from_airport: str, to_airport: str):
"""Book a flight"""
return f"Successfully booked a flight from {from_airport} to {to_airport}."
flight_assistant = create_react_agent(
model="openai:gpt-4o",
tools=[book_flight],
prompt="You are a flight booking assistant",
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="openai:gpt-4o",
tools=[book_hotel],
prompt="You are a hotel booking assistant",
name="hotel_assistant"
)
supervisor = create_supervisor(
agents=[flight_assistant, hotel_assistant],
model=ChatOpenAI(model="gpt-4o"),
prompt=(
"You manage a hotel booking assistant and a"
"flight booking assistant. Assign work to them."
)
).compile()
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-swarm
库创建群集多智能体系统
API 参考:create_react_agent | create_swarm | create_handoff_tool
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 user to the hotel-booking assistant.",
)
transfer_to_flight_assistant = create_handoff_tool(
agent_name="flight_assistant",
description="Transfer user to the flight-booking assistant.",
)
flight_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_flight, transfer_to_hotel_assistant],
prompt="You are a flight booking assistant",
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_hotel, transfer_to_flight_assistant],
prompt="You are a hotel booking assistant",
name="hotel_assistant"
)
swarm = create_swarm(
agents=[flight_assistant, hotel_assistant],
default_active_agent="flight_assistant"
).compile()
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")
移交¶
多智能体交互中一个常见的模式是**移交**,即一个智能体将控制权“移交”给另一个智能体。移交允许您指定:
- 目的地:要导航到的目标智能体
- 有效载荷:传递给该智能体的信息
langgraph-supervisor
(监督者将控制权移交给单个智能体)和 langgraph-swarm
(单个智能体可以将控制权移交给其他智能体)都使用了这一点。
要使用 create_react_agent
实现移交,您需要:
-
创建一个特殊工具,可以控制权转移到另一个智能体
-
创建可以使用移交工具的单个智能体
-
定义一个包含单个智能体作为节点的父图
综合来看,以下是如何实现一个包含两个智能体(一个航班预订助手和一个酒店预订助手)的简单多智能体系统:
API 参考:tool | InjectedToolCallId | create_react_agent | InjectedState | StateGraph | START | Command
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"Transfer to {agent_name}"
@tool(name, description=description)
def handoff_tool(
state: Annotated[MessagesState, InjectedState], # (1)!
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( # (2)!
goto=agent_name, # (3)!
update={"messages": state["messages"] + [tool_message]}, # (4)!
graph=Command.PARENT, # (5)!
)
return handoff_tool
# Handoffs
transfer_to_hotel_assistant = create_handoff_tool(
agent_name="hotel_assistant",
description="Transfer user to the hotel-booking assistant.",
)
transfer_to_flight_assistant = create_handoff_tool(
agent_name="flight_assistant",
description="Transfer user to the flight-booking assistant.",
)
# Simple agent tools
def book_hotel(hotel_name: str):
"""Book a hotel"""
return f"Successfully booked a stay at {hotel_name}."
def book_flight(from_airport: str, to_airport: str):
"""Book a flight"""
return f"Successfully booked a flight from {from_airport} to {to_airport}."
# Define agents
flight_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_flight, transfer_to_hotel_assistant],
prompt="You are a flight booking assistant",
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
tools=[book_hotel, transfer_to_flight_assistant],
prompt="You are a hotel booking assistant",
name="hotel_assistant"
)
# Define multi-agent graph
multi_agent_graph = (
StateGraph(MessagesState)
.add_node(flight_assistant)
.add_node(hotel_assistant)
.add_edge(START, "flight_assistant")
.compile()
)
# Run the multi-agent graph
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")
- 访问智能体的状态
Command
原语允许将状态更新和节点转换指定为一个单一操作,这对于实现移交很有用。- 要移交控制权的智能体或节点的名称。
- 获取智能体的消息,并在移交过程中将它们**添加到**父级的**状态**中。下一个智能体将看到父级状态。
- 向 LangGraph 指示我们需要导航到**父级**多智能体图中的智能体节点。
注意
此移交实现假定:
- 每个智能体接收多智能体系统中整体消息历史(跨所有智能体)作为其输入
- 每个智能体将其内部消息历史输出到多智能体系统的整体消息历史