如何讓多個(gè)AI Agent高效協(xié)作?手把手教你構(gòu)建企業(yè)級(jí)AI智能體系統(tǒng) 原創(chuàng)
在AI技術(shù)快速發(fā)展的今天,多智能體系統(tǒng)(Multi-Agent Systems)被稱為"AI的第三波浪潮",而LangGraph作為新一代的智能體編排框架,為構(gòu)建復(fù)雜的多智能體系統(tǒng)提供了強(qiáng)大的基礎(chǔ)設(shè)施。
本文將深入探討LangGraph中的兩個(gè)核心概念:**Handoffs(交接)和Supervisor(主管)**模式,通過詳細(xì)的技術(shù)分析和代碼示例,幫助你掌握構(gòu)建生產(chǎn)級(jí)多智能體系統(tǒng)的關(guān)鍵技術(shù)。
一、LangGraph多智能體架構(gòu)概述
1.1 什么是多智能體系統(tǒng)?
在多智能體架構(gòu)中,智能體可以被表示為圖節(jié)點(diǎn)。每個(gè)智能體節(jié)點(diǎn)執(zhí)行其步驟并決定是完成執(zhí)行還是路由到另一個(gè)智能體,包括可能路由到自己(例如,在循環(huán)中運(yùn)行)。這種設(shè)計(jì)使得系統(tǒng)能夠動(dòng)態(tài)地在不同專業(yè)化的智能體之間協(xié)調(diào)任務(wù)。
1.2 LangGraph的核心優(yōu)勢
LangGraph基于Google的Pregel系統(tǒng)設(shè)計(jì)理念,采用事件驅(qū)動(dòng)架構(gòu),提供了以下關(guān)鍵特性:
- 狀態(tài)管理:內(nèi)置的狀態(tài)持久化和管理機(jī)制
- 流式處理:原生支持token級(jí)別的流式輸出
- Human-in-the-loop:支持人工干預(yù)和審批流程
- 靈活的控制流:支持單智能體、多智能體、層級(jí)式等多種架構(gòu)模式
二、Handoffs(交接)機(jī)制詳解
2.1 Handoffs的核心概念
Handoffs是多智能體交互中的常見模式,其中一個(gè)智能體將控制權(quán)移交給另一個(gè)智能體。Handoffs允許你指定:destination(目標(biāo)智能體)和payload(要傳遞給該智能體的信息)。
2.2 Command原語的引入
2024年12月,LangGraph引入了??Command??原語,這是一個(gè)革命性的改進(jìn)。Command是LangGraph中的一種特殊類型,當(dāng)從節(jié)點(diǎn)返回時(shí),它不僅指定狀態(tài)更新(如常規(guī)),還指定接下來要去的節(jié)點(diǎn)。
2.3 實(shí)現(xiàn)Handoffs的核心代碼
from typing import Literal, Annotated
from langchain_core.tools import tool
from langgraph.types import Command
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import InjectedState
# 創(chuàng)建handoff工具的函數(shù)
def create_handoff_tool(*, agent_name: str, description: str = None):
name = f"transfer_to_{agent_name}"
description = description orf"Ask {agent_name} for help."
@tool(name, description=description)
def handoff_tool(
task_description: Annotated[
str,
"Description of what the next agent should do"
],
state: Annotated[MessagesState, InjectedState],
) -> Command:
# 創(chuàng)建任務(wù)描述消息
task_message = {"role": "user", "content": task_description}
# 準(zhǔn)備下一個(gè)智能體的輸入
agent_input = {**state, "messages": [task_message]}
return Command(
goto=agent_name, # 指定下一個(gè)智能體
update=agent_input, # 傳遞的狀態(tài)更新
graph=Command.PARENT # 在父圖中導(dǎo)航
)
return handoff_tool2.4 智能體節(jié)點(diǎn)中使用Command
def agent_node(state: MessagesState) -> Command[Literal["agent_a", "agent_b", "END"]]:
# 智能體邏輯處理
messages = state["messages"]
# 基于某種條件決定路由
if need_expert_help(messages):
return Command(
goto="agent_b", # 路由到agent_b
update={"messages": messages + [new_message]}
)
elif task_completed(messages):
return Command(
goto="END",
update={"messages": messages + [final_message]}
)
else:
# 繼續(xù)當(dāng)前智能體的處理
return Command(
goto="agent_a", # 路由回自己
update={"messages": messages + [processing_message]}
)三、Supervisor(主管)模式深度剖析
3.1 Supervisor架構(gòu)設(shè)計(jì)
supervisor模式中,各個(gè)智能體由中央主管智能體協(xié)調(diào)。主管控制所有通信流和任務(wù)委派,根據(jù)當(dāng)前上下文和任務(wù)要求決定調(diào)用哪個(gè)智能體。
3.2 使用langgraph-supervisor庫
LangGraph提供了預(yù)構(gòu)建的??langgraph-supervisor??庫,簡化了主管系統(tǒng)的創(chuàng)建:
from langgraph_supervisor import create_supervisor
from langchain.chat_models import init_chat_model
# 初始化模型
supervisor_model = init_chat_model("openai:gpt-4")
# 創(chuàng)建專業(yè)智能體
research_agent = create_react_agent(
model="openai:gpt-4",
tools=[web_search_tool, document_reader_tool],
prompt="You are a research expert. Focus on finding accurate information.",
name="research_expert"
)
math_agent = create_react_agent(
model="openai:gpt-4",
tools=[calculator_tool, equation_solver_tool],
prompt="You are a mathematics expert. Solve complex calculations.",
name="math_expert"
)
# 創(chuàng)建主管系統(tǒng)
supervisor_app = create_supervisor(
agents=[research_agent, math_agent],
model=supervisor_model,
prompt=(
"You are a supervisor managing two agents:\n"
"- a research agent for information gathering\n"
"- a math agent for calculations\n"
"Assign work to one agent at a time based on the task."
),
add_handoff_back_messages=True,
output_mode="full_history"
).compile()3.3 自定義Handoff工具
默認(rèn)情況下,主管使用預(yù)構(gòu)建的create_handoff_tool創(chuàng)建的交接工具。你也可以創(chuàng)建自己的自定義交接工具:
from typing import Annotated
from langchain_core.tools import tool, BaseTool, InjectedToolCallId
from langchain_core.messages import ToolMessage
from langgraph.types import Command
from langgraph.prebuilt import InjectedState
def create_custom_handoff_tool(
*,
agent_name: str,
name: str = None,
description: str = None
) -> BaseTool:
@tool(name, description=description)
def handoff_to_agent(
# LLM填充的任務(wù)描述
task_description: Annotated[
str,
"Detailed description of the task including context"
],
# 可以添加額外的參數(shù)
priority: Annotated[
str,
"Priority level: high, medium, low"
],
# 注入的狀態(tài)
state: Annotated[dict, InjectedState],
tool_call_id: Annotated[str, InjectedToolCallId],
):
# 創(chuàng)建工具消息
tool_message = ToolMessage(
content=f"Successfully transferred to {agent_name} with priority {priority}",
name=name,
tool_call_id=tool_call_id,
)
# 更新狀態(tài)并路由
return Command(
goto=agent_name,
update={
"messages": state["messages"] + [tool_message],
"current_task": task_description,
"priority": priority
},
graph=Command.PARENT
)
return handoff_to_agent四、高級(jí)特性與最佳實(shí)踐
4.1 狀態(tài)管理與持久化
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.store.memory import InMemoryStore
# 短期記憶(對(duì)話狀態(tài))
checkpointer = InMemorySaver()
# 長期記憶(知識(shí)存儲(chǔ))
store = InMemoryStore()
# 編譯時(shí)添加持久化支持
app = supervisor_app.compile(
checkpointer=checkpointer,
store=store
)4.2 輸出模式控制
LangGraph提供了靈活的輸出模式控制:
# 創(chuàng)建主管時(shí)指定輸出模式
supervisor = create_supervisor(
agents=[agent1, agent2],
model=model,
output_mode="last_message", # 只返回最后的消息
# output_mode="full_history" # 返回完整歷史
)4.3 消息轉(zhuǎn)發(fā)工具
你可以為主管配備一個(gè)工具,直接將從工作智能體收到的最后一條消息轉(zhuǎn)發(fā)到圖的最終輸出:
from langgraph_supervisor.handoff import create_forward_message_tool
# 創(chuàng)建轉(zhuǎn)發(fā)工具
forwarding_tool = create_forward_message_tool("supervisor")
# 在創(chuàng)建主管時(shí)添加
workflow = create_supervisor(
[research_agent, math_agent],
model=model,
tools=[forwarding_tool] # 添加轉(zhuǎn)發(fā)工具
)4.4 處理復(fù)雜的多智能體工作流
class MultiAgentState(TypedDict):
messages: Annotated[list, add_messages]
current_agent: str
task_queue: list
results: dict
def create_complex_workflow():
workflow = StateGraph(MultiAgentState)
# 添加智能體節(jié)點(diǎn)
workflow.add_node("supervisor", supervisor_agent)
workflow.add_node("researcher", research_agent)
workflow.add_node("analyst", data_analyst_agent)
workflow.add_node("writer", content_writer_agent)
# 使用Command進(jìn)行動(dòng)態(tài)路由
def supervisor_agent(state: MultiAgentState) -> Command:
task = state["task_queue"][0] if state["task_queue"] elseNone
ifnot task:
return Command(goto="END", update=state)
# 基于任務(wù)類型分配給不同智能體
if task["type"] == "research":
return Command(
goto="researcher",
update={**state, "current_agent": "researcher"}
)
elif task["type"] == "analysis":
return Command(
goto="analyst",
update={**state, "current_agent": "analyst"}
)
# ... 更多路由邏輯
return workflow.compile()五、Swarm模式vs Supervisor模式
5.1 Swarm模式特點(diǎn)
在Swarm架構(gòu)中,智能體基于其專業(yè)化動(dòng)態(tài)地相互傳遞控制權(quán)。系統(tǒng)會(huì)記住哪個(gè)智能體最后處于活動(dòng)狀態(tài),確保在后續(xù)交互中,對(duì)話從該智能體恢復(fù)。
5.2 選擇合適的模式
- Supervisor模式適用于:
- 需要集中控制和決策的場景
- 任務(wù)分配規(guī)則明確的系統(tǒng)
- 需要嚴(yán)格的執(zhí)行順序控制
- Swarm模式適用于:
- 智能體間平等協(xié)作的場景
- 需要更靈活的動(dòng)態(tài)路由
- 去中心化的決策制定
六、性能優(yōu)化與注意事項(xiàng)
6.1 避免狀態(tài)膨脹
在長對(duì)話中,消息歷史可能變得非常大。考慮實(shí)施消息摘要或選擇性傳遞:
def selective_handoff(state: MessagesState) -> Command:
# 只傳遞最近的N條消息
recent_messages = state["messages"][-10:]
# 創(chuàng)建摘要
summary = create_summary(state["messages"][:-10])
return Command(
goto="next_agent",
update={"messages": [summary] + recent_messages}
)6.2 錯(cuò)誤處理與恢復(fù)
def robust_agent(state: MessagesState) -> Command:
try:
# 智能體邏輯
result = process_task(state)
return Command(goto="success_handler", update={"result": result})
except Exception as e:
# 錯(cuò)誤恢復(fù)
return Command(
goto="error_handler",
update={"error": str(e), "fallback_agent": "supervisor"}
)七、實(shí)戰(zhàn)案例:構(gòu)建智能客服系統(tǒng)
讓我們通過一個(gè)完整的例子來展示如何使用LangGraph構(gòu)建一個(gè)多智能體客服系統(tǒng):
from langgraph_supervisor import create_supervisor
from langgraph.prebuilt import create_react_agent
import os
# 設(shè)置API密鑰
os.environ["OPENAI_API_KEY"] = "your-api-key"
# 1. 創(chuàng)建專業(yè)智能體
# FAQ智能體
faq_agent = create_react_agent(
model="openai:gpt-3.5-turbo",
tools=[search_faq_tool, get_product_info_tool],
prompt="You handle frequently asked questions about products and services.",
name="faq_specialist"
)
# 技術(shù)支持智能體
tech_agent = create_react_agent(
model="openai:gpt-4",
tools=[diagnose_issue_tool, check_system_status_tool],
prompt="You are a technical support specialist. Help users solve technical problems.",
name="tech_specialist"
)
# 訂單處理智能體
order_agent = create_react_agent(
model="openai:gpt-3.5-turbo",
tools=[check_order_status_tool, process_return_tool],
prompt="You handle order-related inquiries and returns.",
name="order_specialist"
)
# 2. 創(chuàng)建主管系統(tǒng)
customer_service_system = create_supervisor(
agents=[faq_agent, tech_agent, order_agent],
model="openai:gpt-4",
prompt="""
You are a customer service supervisor managing three specialists:
- FAQ specialist: handles general questions
- Tech specialist: handles technical issues
- Order specialist: handles order and shipping issues
Analyze the customer's query and delegate to the appropriate specialist.
If the query spans multiple areas, handle them sequentially.
""",
add_handoff_back_messages=True,
output_mode="last_message"# 返回最終響應(yīng)
)
# 3. 編譯并運(yùn)行
app = customer_service_system.compile(
checkpointer=InMemorySaver() # 添加對(duì)話記憶
)
# 4. 處理客戶查詢
asyncdef handle_customer_query(query: str, thread_id: str):
config = {"configurable": {"thread_id": thread_id}}
result = await app.ainvoke(
{"messages": [{"role": "user", "content": query}]},
config=config
)
return result["messages"][-1]["content"]
# 使用示例
response = await handle_customer_query(
"My laptop won't turn on and I want to check if it's still under warranty",
thread_id="customer_123"
)八、最佳實(shí)踐建議
- 始終為智能體定義清晰的職責(zé)邊界
- 實(shí)施適當(dāng)?shù)腻e(cuò)誤處理和回退機(jī)制
- 使用checkpointer保持對(duì)話狀態(tài)的連續(xù)性
- 監(jiān)控和優(yōu)化智能體間的交互效率
- 定期評(píng)估和調(diào)整智能體的提示詞和工具配置
本文轉(zhuǎn)載自???AI 博物院??? 作者:longyunfeigu

















