为什么需要多 Agent?
复杂的 Agent 产品基本都是多 Agent 架构。
单 Agent 的痛点
java
┌─────────────────────────────────────┐
│ 单 Agent 架构 │
│ ┌─────────────────────────────┐ │
│ │ System Prompt (巨大) │ │
│ │ - 所有 tool 描述 │ │
│ │ - 所有功能 prompt │ │
│ │ - 所有上下文 │ │
│ └─────────────────────────────┘ │
│ ↓ 每次都带上 │
│ Token 消耗高 + 干扰多 │
└─────────────────────────────────────┘
问题:
- 执行每个功能只需要一部分 prompt,但每次都带上全部
- Token 消耗高,无关信息干扰思考
- 准确率低,容易出错
多 Agent 的优势
css
┌─────────────────────────────────────┐
│ 多 Agent 架构 │
│ ┌─────────┐ ┌─────────┐ │
│ │ Agent A │ │ Agent B │ 并行 │
│ │(写代码) │ │(写测试) │ 处理 │
│ └────┬────┘ └────┬────┘ │
│ └──────┬───────┘ │
│ ↓ │
│ 主 Agent 协调 │
└─────────────────────────────────────┘
三个核心优势:
| 优势 | 说明 |
|---|---|
| 决策准确率高 | 每个 Agent 只带必要 Prompt,无冗余信息干扰 |
| 并行处理 | 主管分派子任务,子 Agent 并行执行,效率更高 |
| 互相纠错 | 多角色讨论,类似 AutoGen 的"法庭"机制 |
Agent = LLM(大脑) + Harness(tool + mcp + rag + skill...)
单 Agent 只有一个大脑,一步步思考调用 tool。 多 Agent 多个大脑,并行思考,按需组合。
LangChain → LangGraph 演进
| 框架 | 定位 | 特点 |
|---|---|---|
| LangChain | 基础模块库 | LLM API、Document Loaders、Embedding、Vector Store... |
| LangGraph | 工作流编排器 | 网状工作流,支持分支、循环、多 Agent 协作 |
scss
LangChain (基础积木)
↓
LangGraph (网状编排)
↓
复杂多 Agent 协作
网状工作流编排 API
核心概念:工作节点 + 组织方式
javascript
import {
Annotation, // 状态定义
END, // 结束节点
START, // 开始节点
StateGraph // 状态图编排器
} from '@langchain/langgraph';
状态定义:Annotation
javascript
const StateAnnotation = Annotation.Root({
text: Annotation({
reducer: (_prev, next) => next, // 新值覆盖旧值
default: () => "", // 默认空字符串
})
})
Annotation vs StateGraph 区别:
| Annotation | StateGraph | |
|---|---|---|
| 角色 | 📋 数据定义 | 🔧 流程编排 |
| 做什么 | 描述状态长什么样 | 描述节点怎么跑 |
| 类比 | 数据库表结构 | 程序主流程 |
基础示例:线性流程
javascript
// 定义节点函数
const step1 = (state) => ({ text: `${state.text} -> step1` });
const step2 = (state) => ({ text: `${state.text} -> step2` });
// 编排工作流
const graph = new StateGraph(StateAnnotation)
.addNode("step1", step1)
.addNode("step2", step2)
.addEdge(START, "step1")
.addEdge("step1", "step2")
.addEdge("step2", END)
.compile();
// 执行
const result = await graph.invoke({ text: "hello" });
console.log(result); // { text: "hello -> step1 -> step2" }
执行流程图:
graph TD;
__start__([__start__]) --> step1(step1)
step1 --> step2(step2)
step2 --> __end__([__end__])
分支与循环
条件分支
javascript
const StateAnnotation = Annotation.Root({
query: Annotation({ reducer: (_prev, next) => next, default: () => "" }),
route: Annotation({ reducer: (_prev, next) => next, default: () => "chat" }),
answer: Annotation({ reducer: (_prev, next) => next, default: () => "" })
});
// 路由节点:根据条件选择分支
const router = (state) => {
const isMath = /[+\-*/]/.test(state.query);
return { route: isMath ? "math" : "chat" };
};
// 条件边
const graph = new StateGraph(StateAnnotation)
.addNode("router", router)
.addNode("math", mathHandler)
.addNode("chat", chatHandler)
.addEdge(START, "router")
.addConditionalEdges("router", (state) => state.route) // 分支
.addEdge("math", END)
.addEdge("chat", END)
.compile();
分支流程图:
graph TD;
__start__ --> router{router}
router -->|math| math[math]
router -->|chat| chat[chat]
math --> __end__
chat --> __end__
可视化调试
LangGraph 内置 Mermaid 导出,方便可视化:
javascript
const drawable = await graph.getGraphAsync();
const mermaid = drawable.drawMermaid({ withStyles: true });
console.log(mermaid); // 直接粘贴到 Markdown 渲染
总结
| 场景 | 方案 |
|---|---|
| 简单任务 | 单 Agent + LangChain |
| 复杂流程 | LangGraph 网状编排 |
| 多角色协作 | 多 Agent + LangGraph |
一句话: LangGraph 是 LangChain 的"大脑连接器",把多个 Agent 组织成网状工作流,实现高效协作。
觉得有帮助的话,点个赞👍支持一下~