多 Agent 协作实战:LangGraph 编排模式
单个 Agent 跑复杂任务容易"一本正经地跑偏"。本文讲清多 Agent 的三种编排模式(supervisor / hierarchical / handoff),用 LangGraph 的 state graph 实现一个"主管 + 多专员"的协作系统,并讨论状态、循环、人工介入这些把多 Agent 推向生产的工程要点。
本文要点
- 主题聚焦:AI、AI Agent
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
当任务复杂到"一个 Agent 既要做需求分析、又要写代码、又要做 review",单 Agent 就开始力不从心:上下文被各种工具塞爆、不同子任务的 prompt 互相干扰、一旦跑偏整个流程全错。
解法是多 Agent 协作——把大任务拆给一组各司其职的 Agent,由编排层协调。这篇用 LangGraph(目前最主流的 Agent 编排框架)讲清怎么搭。
一、三种编排模式
多 Agent 怎么组织,本质就三种范式:
1. Supervisor(主管模式) ——最常用。一个"主管 Agent"负责拆任务、分派、汇总;多个"专员 Agent"各自完成一块。主管决定下一步找谁、专员干完汇报。
┌─────────┐
┌────▶│ 主管Agent│◀────┐
│ └────┬────┘ │
│ │ │
┌─────┴──┐ ┌────┴───┐ ┌───┴────┐
│专员 A │ │专员 B │ │专员 C │
│(检索) │ │(写代码)│ │(测试) │
└────────┘ └────────┘ └────────┘
2. Hierarchical(层级模式) ——supervisor 的递归版:主管把子任务再交给子主管,层层分解。适合特别大的任务(企业级流程自动化)。
3. Handoff(移交模式) ——没有中心主管,Agent 之间直接交接。一个 Agent 干到自己边界,就把会话连同状态交给下一个。OpenAI 的 Swarm、很多客服系统走这种。轻量、但要小心"踢皮球"。
新手默认选 Supervisor。 它可控、可观测、容易加人工介入,覆盖 80% 场景。
二、LangGraph 的核心:把流程画成状态图
LangGraph 的心智模型很干净:你的整个多 Agent 系统就是一张带状态的有向图。
- State:在所有节点间流动的共享数据(消息历史、当前子任务、中间结果)。
- Node:每个节点是一个 Agent(或一个函数),接收 state、返回 state 更新。
- Edge:节点之间的连线,可以是固定的,也可以是"条件边"(由某个节点的输出决定下一步去哪)。
一个 supervisor 系统的图长这样:
START → supervisor → ┬─→ researcher → supervisor
├─→ coder → supervisor
└─→ tester → supervisor
↓
(结束) END
supervisor 是个条件边出口:它每次被调用后,根据当前 state 决定"接下来找 researcher / coder / tester,还是结束"。
三、实战:主管 + 三个专员
import { StateGraph, MessagesAnnotation, END, START } from "@langchain/langgraph";
// 定义图:消息历史作为共享 state
const graph = new StateGraph(MessagesAnnotation)
// 主管:决定下一步
.addNode("supervisor", supervisorAgent)
// 三个专员
.addNode("researcher", researcherAgent)
.addNode("coder", coderAgent)
.addNode("tester", testerAgent)
// 主管 → 条件路由
.addConditionalEdges("supervisor", routeFromSupervisor, {
researcher: "researcher",
coder: "coder",
tester: "tester",
done: END,
})
// 每个专员干完回主管
.addEdge("researcher", "supervisor")
.addEdge("coder", "supervisor")
.addEdge("tester", "supervisor")
.addEdge(START, "supervisor");
const app = graph.compile();
// 主管的路由函数:读 state,决定下一个专员或结束
function routeFromSupervisor(state) {
if (state.next === "FINISH") return "done";
return state.next; // "researcher" | "coder" | "tester"
}
主管 agent 的 prompt 大致:
你是项目主管。根据当前任务进展,决定下一步交给谁:
- researcher:需要查资料、读文档
- coder:需要写或改代码
- tester:需要写测试或验证
- FINISH:任务完成
只输出一个选择。
跑起来:app.invoke({ messages: [{ role: "user", content: "给一个 Express 加上带限流的健康检查接口并验证" }] }),你会看到 supervisor → coder → tester → supervisor → FINISH 的轨迹。
四、工程要点
1. 状态要有 schema。 用 TypedDict/Annotation 明确 state 有哪些字段。无 schema 的 state 一周后就没人看得懂,调试灾难。
2. 控制循环。 多 Agent 最容易死循环(A 交给 B、B 交给 A)。给 supervisor 加一个"最大轮数"state 字段,超限强制 END。没有上限的多 Agent 就是烧钱定时炸弹。
3. 人工介入(human-in-the-loop)。 LangGraph 支持 interrupt:在关键节点(比如 coder 要执行代码前)暂停,等人确认再继续。生产系统涉及真实操作时,这层闸门必须有。
4. 流式 + trace。 多 Agent 的执行路径长,用户需要看到"现在在哪个专员"。用 streaming 把每个节点的开始/结束推给前端,并用 LangSmith(或自建 trace)记录整条图执行轨迹——出问题靠这个定位。
5. 专员之间别共享太多上下文。 每个专员只看它干活需要的最小 state,别把全局消息历史塞给所有人。上下文越窄,专注度越高、token 越省。
五、什么时候不该上多 Agent
多 Agent 不是银弹,它的协调成本和延迟都高于单 Agent。如果一个单 Agent + 好的工具集 + 清晰 prompt 就能搞定,就别上多 Agent。
判断标准:任务能不能被自然地切成"几个角色各自擅长的、相对独立"的子任务?能,且每个子任务都有独立的工具/知识需求,才值得拆。拆不开就硬拆,只会得到一坨互相打架的 Agent。
小结
多 Agent 把复杂任务从"一个全能选手硬扛"变成"一个主管调度一组专员",可扩展性和可控性都更好。LangGraph 用"状态图"这个统一模型把这件事讲透了:节点是 Agent、边是控制流、state 是共享记忆。
记住三个生产红线:有 schema 的状态、有上限的循环、有 trace 的执行。这三件事做到了,你的多 Agent 系统就从 demo 跨进了生产;做不到,再多花哨的编排模式都是空中楼阁。
Related