多智能代理¶
如果单个智能代理需要专门处理多个领域或管理许多工具,它可能会遇到困难。为了解决这个问题,你可以将你的智能代理分解成更小的独立智能代理,并将它们组合成一个多智能代理系统。
在多智能代理系统中,智能代理需要彼此之间进行通信。它们通过交接来实现 — 这是一个原语,描述了要将控制权交给哪个智能代理以及要发送给该智能代理的有效负载。
两种最流行的多智能代理架构是:
- 监督者 — 单个智能代理由中央监督智能代理协调。监督者控制所有通信流和任务委派,根据当前上下文和任务需求决定调用哪个智能代理。
- 集群 — 智能代理根据其专业领域动态地将控制权交给彼此。系统记住最后活动的智能代理,确保在后续交互中,对话从该智能代理恢复。
监督者¶

使用 langgraph-supervisor 库创建监督者多智能代理系统:
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
# highlight-next-line
from langgraph_supervisor import create_supervisor
def book_hotel(hotel_name: str):
"""预订酒店"""
return f"Successfully booked a stay at {hotel_name}."
def book_flight(from_airport: str, to_airport: str):
"""预订航班"""
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",
# highlight-next-line
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="openai:gpt-4o",
tools=[book_hotel],
prompt="You are a hotel booking assistant",
# highlight-next-line
name="hotel_assistant"
)
# highlight-next-line
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")
使用 @langchain/langgraph-supervisor 库创建监督者多智能代理系统:
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
// highlight-next-line
import { createSupervisor } from "langgraph-supervisor";
function bookHotel(hotelName: string) {
/**预订酒店*/
return `Successfully booked a stay at ${hotelName}.`;
}
function bookFlight(fromAirport: string, toAirport: string) {
/**预订航班*/
return `Successfully booked a flight from ${fromAirport} to ${toAirport}.`;
}
const flightAssistant = createReactAgent({
llm: "openai:gpt-4o",
tools: [bookFlight],
stateModifier: "You are a flight booking assistant",
// highlight-next-line
name: "flight_assistant",
});
const hotelAssistant = createReactAgent({
llm: "openai:gpt-4o",
tools: [bookHotel],
stateModifier: "You are a hotel booking assistant",
// highlight-next-line
name: "hotel_assistant",
});
// highlight-next-line
const supervisor = createSupervisor({
agents: [flightAssistant, hotelAssistant],
llm: new ChatOpenAI({ model: "gpt-4o" }),
systemPrompt:
"You manage a hotel booking assistant and a " +
"flight booking assistant. Assign work to them.",
});
for await (const chunk of supervisor.stream({
messages: [
{
role: "user",
content: "book a flight from BOS to JFK and a stay at McKittrick Hotel",
},
],
})) {
console.log(chunk);
console.log("\n");
}
集群¶

使用 langgraph-swarm 库创建集群多智能代理系统:
from langgraph.prebuilt import create_react_agent
# highlight-next-line
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",
# highlight-next-line
tools=[book_flight, transfer_to_hotel_assistant],
prompt="You are a flight booking assistant",
# highlight-next-line
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
# highlight-next-line
tools=[book_hotel, transfer_to_flight_assistant],
prompt="You are a hotel booking assistant",
# highlight-next-line
name="hotel_assistant"
)
# highlight-next-line
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")
使用 @langchain/langgraph-swarm 库创建集群多智能代理系统:
import { createReactAgent } from "@langchain/langgraph/prebuilt";
// highlight-next-line
import { createSwarm, createHandoffTool } from "@langchain/langgraph-swarm";
const transferToHotelAssistant = createHandoffTool({
agentName: "hotel_assistant",
description: "Transfer user to the hotel-booking assistant.",
});
const transferToFlightAssistant = createHandoffTool({
agentName: "flight_assistant",
description: "Transfer user to the flight-booking assistant.",
});
const flightAssistant = createReactAgent({
llm: "anthropic:claude-3-5-sonnet-latest",
// highlight-next-line
tools: [bookFlight, transferToHotelAssistant],
stateModifier: "You are a flight booking assistant",
// highlight-next-line
name: "flight_assistant",
});
const hotelAssistant = createReactAgent({
llm: "anthropic:claude-3-5-sonnet-latest",
// highlight-next-line
tools: [bookHotel, transferToFlightAssistant],
stateModifier: "You are a hotel booking assistant",
// highlight-next-line
name: "hotel_assistant",
});
// highlight-next-line
const swarm = createSwarm({
agents: [flightAssistant, hotelAssistant],
defaultActiveAgent: "flight_assistant",
});
for await (const chunk of swarm.stream({
messages: [
{
role: "user",
content: "book a flight from BOS to JFK and a stay at McKittrick Hotel",
},
],
})) {
console.log(chunk);
console.log("\n");
}
交接¶
多智能代理交互中的一个常见模式是**交接**,其中一个智能代理将控制权_交接_给另一个。交接允许你指定:
- 目标: 要导航到的目标智能代理
- 有效负载: 要传递给该智能代理的信息
这由 langgraph-supervisor(监督者交接给单个智能代理)和 langgraph-swarm(单个智能代理可以交接给其他智能代理)使用。
要使用 create_react_agent 实现交接,你需要:
-
创建一个可以将控制权转移到不同智能代理的特殊工具
-
创建可以访问交接工具的单个智能代理:
-
定义包含单个智能代理作为节点的父图:
这由 @langchain/langgraph-supervisor(监督者交接给单个智能代理)和 @langchain/langgraph-swarm(单个智能代理可以交接给其他智能代理)使用。
要使用 createReactAgent 实现交接,你需要:
-
创建一个可以将控制权转移到不同智能代理的特殊工具
-
创建可以访问交接工具的单个智能代理:
-
定义包含单个智能代理作为节点的父图:
将所有这些放在一起,以下是如何实现一个具有两个智能代理的简单多智能代理系统 — 航班预订助手和酒店预订助手:
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(
# highlight-next-line
state: Annotated[MessagesState, InjectedState], # (1)!
# highlight-next-line
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)!
# highlight-next-line
goto=agent_name, # (3)!
# highlight-next-line
update={"messages": state["messages"] + [tool_message]}, # (4)!
# highlight-next-line
graph=Command.PARENT, # (5)!
)
return 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.",
)
# 简单的智能代理工具
def book_hotel(hotel_name: str):
"""预订酒店"""
return f"Successfully booked a stay at {hotel_name}."
def book_flight(from_airport: str, to_airport: str):
"""预订航班"""
return f"Successfully booked a flight from {from_airport} to {to_airport}."
# 定义智能代理
flight_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
# highlight-next-line
tools=[book_flight, transfer_to_hotel_assistant],
prompt="You are a flight booking assistant",
# highlight-next-line
name="flight_assistant"
)
hotel_assistant = create_react_agent(
model="anthropic:claude-3-5-sonnet-latest",
# highlight-next-line
tools=[book_hotel, transfer_to_flight_assistant],
prompt="You are a hotel booking assistant",
# highlight-next-line
name="hotel_assistant"
)
# 定义多智能代理图
multi_agent_graph = (
StateGraph(MessagesState)
.add_node(flight_assistant)
.add_node(hotel_assistant)
.add_edge(START, "flight_assistant")
.compile()
)
# 运行多智能代理图
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 指示我们需要导航到**父级**多智能代理图中的智能代理节点。
import { tool } from "@langchain/core/tools";
import { ChatAnthropic } from "@langchain/anthropic";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import {
StateGraph,
START,
MessagesZodState,
Command,
} from "@langchain/langgraph";
import { z } from "zod";
function createHandoffTool({
agentName,
description,
}: {
agentName: string;
description?: string;
}) {
const name = `transfer_to_${agentName}`;
const toolDescription = description || `Transfer to ${agentName}`;
return tool(
async (_, config) => {
const toolMessage = {
role: "tool" as const,
content: `Successfully transferred to ${agentName}`,
name: name,
tool_call_id: config.toolCall?.id!,
};
return new Command({
// (2)!
// highlight-next-line
goto: agentName, // (3)!
// highlight-next-line
update: { messages: [toolMessage] }, // (4)!
// highlight-next-line
graph: Command.PARENT, // (5)!
});
},
{
name,
description: toolDescription,
schema: z.object({}),
}
);
}
// 交接
const transferToHotelAssistant = createHandoffTool({
agentName: "hotel_assistant",
description: "Transfer user to the hotel-booking assistant.",
});
const transferToFlightAssistant = createHandoffTool({
agentName: "flight_assistant",
description: "Transfer user to the flight-booking assistant.",
});
// 简单的智能代理工具
const bookHotel = tool(
async ({ hotelName }) => {
/**预订酒店*/
return `Successfully booked a stay at ${hotelName}.`;
},
{
name: "book_hotel",
description: "Book a hotel",
schema: z.object({
hotelName: z.string().describe("Name of the hotel to book"),
}),
}
);
const bookFlight = tool(
async ({ fromAirport, toAirport }) => {
/**预订航班*/
return `Successfully booked a flight from ${fromAirport} to ${toAirport}.`;
},
{
name: "book_flight",
description: "Book a flight",
schema: z.object({
fromAirport: z.string().describe("Departure airport code"),
toAirport: z.string().describe("Arrival airport code"),
}),
}
);
// 定义智能代理
const flightAssistant = createReactAgent({
llm: new ChatAnthropic({ model: "anthropic:claude-3-5-sonnet-latest" }),
// highlight-next-line
tools: [bookFlight, transferToHotelAssistant],
stateModifier: "You are a flight booking assistant",
// highlight-next-line
name: "flight_assistant",
});
const hotelAssistant = createReactAgent({
llm: new ChatAnthropic({ model: "anthropic:claude-3-5-sonnet-latest" }),
// highlight-next-line
tools: [bookHotel, transferToFlightAssistant],
stateModifier: "You are a hotel booking assistant",
// highlight-next-line
name: "hotel_assistant",
});
// 定义多智能代理图
const multiAgentGraph = new StateGraph(MessagesZodState)
.addNode("flight_assistant", flightAssistant)
.addNode("hotel_assistant", hotelAssistant)
.addEdge(START, "flight_assistant")
.compile();
// 运行多智能代理图
for await (const chunk of multiAgentGraph.stream({
messages: [
{
role: "user",
content: "book a flight from BOS to JFK and a stay at McKittrick Hotel",
},
],
})) {
console.log(chunk);
console.log("\n");
}
- 访问智能代理的状态
Command原语允许将状态更新和节点转换指定为单个操作,使其对实现交接很有用。- 要交接到的智能代理或节点的名称。
- 获取智能代理的消息并将它们**添加**到父级的**状态**中作为交接的一部分。下一个智能代理将看到父状态。
- 向 LangGraph 指示我们需要导航到**父级**多智能代理图中的智能代理节点。
Note
此交接实现假设:
- 每个智能代理接收多智能代理系统中所有智能代理的整体消息历史记录作为其输入
- 每个智能代理将其内部消息历史记录输出到多智能代理系统的整体消息历史记录
查看 LangGraph 监督者和集群文档,了解如何自定义交接。