纲要
- 单智能体的局限与多智能体的兴起
- 多智能体架构类型
- 网状结构
- 监管者模式
- 智能体作为工具
- 分级架构
- 自定义混合模式
- 多智能体的优势与挑战
LangGraph简介:多智能体开发的新范式- 实战:用
LangGraph构建监管者多智能体系统- 项目结构
- 工具定义
- 工人智能体
- 监管者智能体
- 工作流图构建
- 完整可运行代码
- 总结与相关度说明
从单兵作战到群体智慧
在之前的单智能体实战中,我们构建了一个挂载多个工具、具备记忆和情感的钉钉助手。这种"一个大脑+一堆工具"的模式虽然能解决许多任务,但当场景变得复杂时------例如需要并行处理、多领域协作、相互校验------单智能体的局限性就暴露出来了。
多智能体系统通过引入多个专业化的智能体,让它们各司其职、相互通信,从而实现更强的鲁棒性、可扩展性和输出质量。这就像从"单兵王"升级为"特种小队"。
多智能体架构一览
多智能体并不是简单的"多个单智能体堆叠",它们的组织方式直接影响系统能力和复杂度。常见的架构有以下几种:
| 架构类型 | 特点 | 典型场景 |
|---|---|---|
| 网状结构 | 智能体之间双向通信,所有节点平等决策 | 分布式协商、去中心化协作 |
| 监管者模式 | 一个管理者负责拆分任务、分派给工人,并汇总结果 | 客服系统、复杂工作流 |
| 智能体作为工具 | 将多个智能体封装为工具,由主模型调用 | 过渡方案,简单扩展 |
| 分级架构 | 多层管理,上级监管下级,模拟公司组织 | 大型项目、多阶段任务 |
| 自定义混合 | 部分节点有决策权,部分只执行 | 需要灵活控制的场景 |
以监管者模式为例,它类似于一个团队:一个监管者接收用户需求,拆分后发送给不同的工人智能体,工人完成任务返回结果,监管者再整合输出。这种模式结构清晰,非常适合初次尝试多智能体开发的场景。
#mermaid-svg-uFx0B61Xnnt01dB9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uFx0B61Xnnt01dB9 .error-icon{fill:#552222;}#mermaid-svg-uFx0B61Xnnt01dB9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uFx0B61Xnnt01dB9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uFx0B61Xnnt01dB9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uFx0B61Xnnt01dB9 .marker.cross{stroke:#333333;}#mermaid-svg-uFx0B61Xnnt01dB9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uFx0B61Xnnt01dB9 p{margin:0;}#mermaid-svg-uFx0B61Xnnt01dB9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 .cluster-label text{fill:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 .cluster-label span{color:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 .cluster-label span p{background-color:transparent;}#mermaid-svg-uFx0B61Xnnt01dB9 .label text,#mermaid-svg-uFx0B61Xnnt01dB9 span{fill:#333;color:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 .node rect,#mermaid-svg-uFx0B61Xnnt01dB9 .node circle,#mermaid-svg-uFx0B61Xnnt01dB9 .node ellipse,#mermaid-svg-uFx0B61Xnnt01dB9 .node polygon,#mermaid-svg-uFx0B61Xnnt01dB9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-uFx0B61Xnnt01dB9 .rough-node .label text,#mermaid-svg-uFx0B61Xnnt01dB9 .node .label text,#mermaid-svg-uFx0B61Xnnt01dB9 .image-shape .label,#mermaid-svg-uFx0B61Xnnt01dB9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-uFx0B61Xnnt01dB9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-uFx0B61Xnnt01dB9 .rough-node .label,#mermaid-svg-uFx0B61Xnnt01dB9 .node .label,#mermaid-svg-uFx0B61Xnnt01dB9 .image-shape .label,#mermaid-svg-uFx0B61Xnnt01dB9 .icon-shape .label{text-align:center;}#mermaid-svg-uFx0B61Xnnt01dB9 .node.clickable{cursor:pointer;}#mermaid-svg-uFx0B61Xnnt01dB9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-uFx0B61Xnnt01dB9 .arrowheadPath{fill:#333333;}#mermaid-svg-uFx0B61Xnnt01dB9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-uFx0B61Xnnt01dB9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-uFx0B61Xnnt01dB9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uFx0B61Xnnt01dB9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-uFx0B61Xnnt01dB9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uFx0B61Xnnt01dB9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-uFx0B61Xnnt01dB9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-uFx0B61Xnnt01dB9 .cluster text{fill:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 .cluster span{color:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-uFx0B61Xnnt01dB9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-uFx0B61Xnnt01dB9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-uFx0B61Xnnt01dB9 .icon-shape,#mermaid-svg-uFx0B61Xnnt01dB9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uFx0B61Xnnt01dB9 .icon-shape p,#mermaid-svg-uFx0B61Xnnt01dB9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-uFx0B61Xnnt01dB9 .icon-shape .label rect,#mermaid-svg-uFx0B61Xnnt01dB9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uFx0B61Xnnt01dB9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-uFx0B61Xnnt01dB9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-uFx0B61Xnnt01dB9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 搜索结果
初稿
通过
不通过
用户输入
监管者智能体
工人A: 搜索专家
工人B: 写作专家
评估智能体
最终输出
LangGraph:多智能体的官方首选框架
LangChain 在 0.2 版本后将多智能体开发的核心迁移到了 LangGraph。它用"图"来建模工作流:每个节点可以是一个智能体、一个工具或一段处理逻辑,边定义了数据流转方向,包括条件边。通过组合节点和边,你可以快速构建出上述任意一种多智能体架构。
实战:用 LangGraph 构建监管者多智能体
下面我们实现一个简单的监管者系统:监管者分析用户问题,决定调用"搜索工人"还是"写作工人",最后整合输出。
项目结构
dir
multi_agent_demo/
├── main.py
├── .env
└── requirements.txt
依赖安装
bash
pip install langgraph langchain-openai langchain-community python-dotenv
完整代码 main.py
python
import os
from typing import TypedDict, Annotated, Sequence
import operator
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
from langgraph.graph import StateGraph, END
# 加载环境变量
load_dotenv()
# 初始化模型
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 定义状态:整个工作流共享的消息列表
class AgentState(TypedDict):
messages: Annotated[Sequence[BaseMessage], operator.add]
next_worker: str # 下一个要调用的工人
# 工人A:搜索专家(模拟)
def search_worker(state: AgentState) -> AgentState:
"""模拟搜索,实际可接入 SerpAPI"""
query = state["messages"][-1].content
# 模拟搜索响应
result = f"搜索结果:关于「{query}」的最新信息显示,多智能体架构正成为AI应用主流。"
return {"messages": [AIMessage(content=result)], "next_worker": "supervisor"}
# 工人B:写作专家(模拟)
def writer_worker(state: AgentState) -> AgentState:
"""根据素材生成最终回答"""
context = state["messages"][-1].content # 假设包含搜索结果
response = llm.invoke(f"根据以下素材,写一段专业总结:\n{context}")
return {"messages": [response], "next_worker": "end"}
# 监管者:决定下一步该调用哪个工人
def supervisor(state: AgentState) -> AgentState:
"""分析用户意图,决定下一个工人"""
user_msg = state["messages"][-1].content
# 简单规则:包含"搜索"或"最新"则调用搜索工人,否则直接写作
if "搜索" in user_msg or "最新" in user_msg:
next_worker = "search"
else:
next_worker = "writer"
return {"messages": [], "next_worker": next_worker}
# 条件边:根据 next_worker 字段路由
def route(state: AgentState) -> str:
return state["next_worker"]
# 构建图
workflow = StateGraph(AgentState)
workflow.add_node("supervisor", supervisor)
workflow.add_node("search", search_worker)
workflow.add_node("writer", writer_worker)
workflow.set_entry_point("supervisor")
# 添加边
workflow.add_conditional_edges(
"supervisor",
route,
{
"search": "search",
"writer": "writer",
}
)
workflow.add_edge("search", "writer") # 搜索完成后交给写作工人
workflow.add_edge("writer", END)
# 编译
app = workflow.compile()
# 运行
if __name__ == "__main__":
# 测试任务1:需要搜索
inputs = {"messages": [HumanMessage(content="搜索最新的多智能体发展趋势")], "next_worker": "supervisor"}
for output in app.stream(inputs):
for key, value in output.items():
if "messages" in value and value["messages"]:
last_msg = value["messages"][-1]
print(f"节点 '{key}': {last_msg.content}")
print("\n---\n")
# 测试任务2:无需搜索,直接写作
inputs2 = {"messages": [HumanMessage(content="写一段关于人工智能的介绍")], "next_worker": "supervisor"}
for output in app.stream(inputs2):
for key, value in output.items():
if "messages" in value and value["messages"]:
last_msg = value["messages"][-1]
print(f"节点 '{key}': {last_msg.content}")
运行说明
执行前确保 .env 中配置了 OPENAI_API_KEY。运行 python main.py,观察控制台输出,监管者会根据输入内容自动决定是先去搜索还是直接写作,搜索的结果会传递给写作工人,最终生成回答。
总结
多智能体架构为复杂 AI 应用提供了强大的组织能力,LangGraph 则是实现这些架构的利器。本文介绍了常见的多智能体模式,并通过一个监管者系统的完整代码展示了如何用图结构编排多个智能体协作。掌握这些基础后,你可以轻松扩展到分级架构、评估-修正循环等更高级的设计。
本文概括了单智能体与多智能体的对比、五种常见架构的特点,并用 LangGraph 实现了监管者模式的代码示例。