第十一章 多 Agent 协作(含 Swarm)¶
导读¶
单 Agent 在简单任务上很顺手,但任务一旦复杂起来,瓶颈就显现:上下文窗口被塞满导致注意力分散,一个 Agent 既要规划又要执行还要批评,每种职责都做不专精;串行执行慢且无法利用并行性;出问题时一条 trace 里什么都有,定位难。**多 Agent 协作**是自然演进——把一个大任务拆成多个角色,每个 Agent 专精一职,上下文互不污染,可以并行跑,每个 Agent 单独 traceable。但多 Agent 不是银弹,它带来新的工程难题:Agent 之间怎么通信、怎么分工、怎么避免循环、怎么处理上下文不一致。本章讲清 5 种主流协作模式(Supervisor+workers / Sequential pipeline / Debate / Hierarchical / Swarm)、3 种通信协议、4 种角色设计、3 种失败模式,并对 OpenAI Swarm(github.com/openai/swarm,2024 年 10 月发布的概念原型)做深入剖析。读完本章你能判断什么时候该用多 Agent、用什么模式、怎么避免常见坑。
11.1 为什么需要多 Agent¶
把单 Agent 比作"全栈工程师"——什么都能干一点但都不深;多 Agent 比作"专业团队"——每个角色专精一职。多 Agent 出现的四个根本动因:
上下文专精¶
单个 Agent 的上下文窗口是有限的——即便是 200K 上下文模型,塞进规划、工具调用历史、中间结果、错误日志后注意力会被稀释,关键信息容易被忽略。多 Agent 让每个 Agent 只看自己角色的上下文——规划 Agent 只看任务目标与子任务列表,执行 Agent 只看当前子任务与可用工具,批评 Agent 只看执行轨迹与结果。**一个 Agent 一职**意味着上下文精简专精,每个 Agent 在自己的领域内保持高注意力。例如一个客服 Agent 不应该把产品技术文档、售后政策、订单数据库 schema 都塞进上下文——分给售前 / 售后 / 技术三个子 Agent 后,每个 Agent 上下文都更干净,回答质量都更高。
并行¶
单 Agent 本质是串行的——一次只走一步 Thought-Action-Observation 循环。多 Agent 可以并行——多个子 Agent 同时跑各自的任务。典型场景:用户问"对比 A、B、C 三个产品的价格与功能"——单 Agent 要串行查 3 次;多 Agent 可以派 3 个子 Agent 同时查,总耗时约等于单次查询。**并行**让多 Agent 在 IO 密集任务(网络请求、数据库查询、文件读取)上有数量级提速。但要注意:并行要求子任务之间无依赖,有依赖的子任务还是要串行。
角色分工¶
复杂任务天然有不同角色——规划者(拆任务)/ 执行者(做任务)/ 批评者(检查任务结果)/ 裁判(综合多 Agent 意见)。单 Agent 一人扮多角容易"自己写的代码自己评不出 bug"——心理学上叫"确认偏差"。多 Agent 让不同角色由不同 Agent 实例扮演,**角色分工**让批评者与执行者上下文隔离——批评者看到的是执行者的产出而非其思考过程,能更客观地发现问题。这种"角色分离"是 Reflexion(第 8 章)的进阶版——Reflexion 是单 Agent 自我反思,多 Agent 是不同 Agent 互相批评,更彻底。
可观测¶
单 Agent 一条 trace 什么都塞在里面——规划、工具调用、错误、修正,问题定位像大海捞针。多 Agent 每个 Agent 独立 traceable——主管 Agent trace 显示分派了哪些任务,子 Agent trace 显示各自执行情况,问题在哪一环节一目了然。**可观测**让多 Agent 系统在生产环境更易调试——出问题时先看主管 Agent 的分派日志,定位到哪个子 Agent 出错,再看那个子 Agent 的 trace。LangSmith / Langfuse(第 13 章详述)的 trace 都支持多 Agent 嵌套视图,能看到完整的 Agent 间调用链。
多 Agent 不是越多越好¶
虽然有上述优势,多 Agent 不是越多越好。每加一个 Agent 都增加:通信开销(Agent 间消息往返)、上下文压缩损耗(handoff 时上下文要序列化可能丢信息)、调试复杂度(多 Agent trace 嵌套深)、成本(每个 Agent 都要调 LLM)。经验法则:3 个 Agent 是甜蜜点——主管 + 2-3 个子 Agent;超过 5 个 Agent 时收益递减,工程复杂度暴涨。简单任务(单步工具调用、单轮回答)不要上多 Agent——单 Agent 加好 prompt 工程就够,多 Agent 是过度设计。
11.2 5 种协作模式¶
多 Agent 协作有 5 种主流模式,下面逐一讲清——每种模式的拓扑、适用场景、典型例子、优势与局限。
模式 1:Supervisor + workers¶
拓扑:一个主管 Agent(Supervisor)作为中心,多个子 Agent(workers)作为叶节点。主管接收用户请求后决定派给哪个子 Agent,子 Agent 执行完返回结果,主管汇总后回用户。如果一次没搞定,主管可以再派给另一个子 Agent。
例子:客服主管 + 售前 / 售后 / 技术专家子 Agent。用户问"我买的 X 产品怎么部署"——主管判断这是技术问题,派给技术子 Agent;技术子 Agent 调知识库工具回方案;主管收到方案转给用户。
优势:第一,控制流清晰——所有任务都过主管,主管是单一可信源。第二,子 Agent 可独立迭代——换一个售前 Agent 实现不影响其他子 Agent。第三,主管可做路由 / 汇总 / 重试——主管看到子 Agent 失败可以重试或换 Agent。局限:第一,主管是瓶颈——所有请求过主管,主管慢则全慢。第二,中心化——主管挂了整个系统挂。第三,子 Agent 之间无直接通信——所有协作都要过主管,多一跳延迟。
模式 2:Sequential pipeline¶
拓扑:A → B → C 串行——前一个 Agent 的输出是后一个 Agent 的输入,无分叉无循环(或仅简单重试)。
例子:翻译 Agent → 校对 Agent → 润色 Agent。翻译 Agent 把英文译成中文,校对 Agent 检查翻译错误并修正,润色 Agent 让中文更通顺。
优势:第一,最简单——线性流水,无需复杂调度。第二,每步可独立测试——A 的输出存档,B 直接用 A 的输出测,无需跑完整流水。第三,职责清晰——每步 Agent 只做一件事。局限:第一,只能串行——前一步没完下一步不能开始,无并行。第二,错误传播——前一步错了后面全错,要在每步加质检。第三,不适合需要回溯的任务——后面发现问题想回头改前面,pipeline 模式不擅长。
模式 3:Debate¶
拓扑:多个 Agent 同时回答同一问题,再由一个裁判 Agent 综合多 Agent 的回答给出最终答案。Agent 之间可以看到彼此回答并互相质疑(多轮辩论)或一次性独立回答(single-shot)。
例子:多模型多视角回答"这个架构方案合理吗"——A Agent 从性能视角批评,B Agent 从成本视角批评,C Agent 从可维护性视角批评,裁判 Agent 综合三方意见给最终结论。
优势:第一,降低单 Agent 偏见——多视角覆盖,单 Agent 局限视角的问题被其他 Agent 补。第二,质量提升明显——研究表明多模型辩论在数学 / 代码任务上比单模型准 5-15%。局限:第一,贵——N 个 Agent + 1 裁判,成本是单 Agent 的 N+1 倍。第二,慢——多轮辩论要等所有 Agent 说话。第三,只在难题有用——简单任务多 Agent 辩论是浪费,单 Agent 一步出答案即可。Debate 模式只在难题用——这是关键工程原则。
模式 4:Hierarchical¶
拓扑:树状层级——根 Agent(CEO)→ 中层 Agent(经理)→ 叶 Agent(IC)。CEO 把大任务拆给经理,经理再拆给 IC,IC 执行后结果逐层上报。
例子:CEO Agent 接到"做一个公司内部知识助手"任务——拆给"前端经理 Agent"(管 UI)与"后端经理 Agent"(管 RAG 流水线);前端经理再拆给"IC Agent 1:登录页"、"IC Agent 2:聊天 UI";后端经理拆给"IC Agent 3:文档入库"、"IC Agent 4:检索接口"。
优势:第一,可扩展——树结构可挂任意多层,适合超大规模任务。第二,分层抽象——CEO 只关心战略,经理只管部门,IC 只管具体活。局限:第一,过度工程——简单任务套多层 Agent 是浪费。第二,上下文逐层压缩——每层 Agent 把下层结果汇总上报,汇总过程会丢信息。第三,调试难——树深了 trace 嵌套深。Hierarchical 只适合真正大规模任务——如多团队协作的复杂软件工程项目。
模式 5:Swarm(OpenAI handoff)¶
来源:OpenAI Swarm 是 OpenAI 2024 年 10 月发布的开源概念原型仓库(github.com/openai/swarm),定位为"educational framework"——不是生产框架,是教学概念原型。注意 Swarm 已被 OpenAI 标记为不再维护,但其"Agent 之间通过 handoff 转移控制权"的思想被业界广泛吸收——OpenAI Agents SDK(官方生产框架)与多个第三方框架都借鉴了 Swarm 的 handoff 抽象。
核心思想:Agent 之间通过 handoff 函数转移控制权。前一个 Agent 调用 handoff(other_agent, context) 后,控制权转给 other_agent——other_agent 接管后看到的是前一个 Agent 打包传过来的上下文(messages 列表 + 任意变量)。每个 Agent 在自己的 prompt 里声明"什么情况下 handoff 给谁"——Agent 自己决定路由,无中央调度。
与 Supervisor 模式的根本区别:Supervisor 是中心化的——所有任务过主管,主管决定派给谁,子 Agent 之间不直接通信;Swarm 是去中心化的——无中央调度,每个 Agent 自己决定下一步 handoff 给谁,Agent 之间直接转移控制权。Supervisor 像公司经理(员工不能直接找别的部门),Swarm 像接力赛(每棒交给下一棒,没有中央指挥)。
适用场景:客服流程路由是 Swarm 的经典场景——用户问题进 triage Agent(分类),triage 判断是售前问题就 handoff 给售前 Agent,售前 Agent 处理中发现需要技术确认就 handoff 给技术 Agent,技术 Agent 解决后直接回用户。整个流程无主管,Agent 之间相互 handoff。
局限:第一,上下文压缩可能丢信息——handoff 时上下文要序列化打包,长历史可能被压缩,关键细节可能丢。第二,handoff 链过长难调试——A→B→C→D→E 一条链,E 出问题要回溯整条链才知道哪一步开始出错。第三,死锁风险——两个 Agent 互相 handoff(A 觉得该 B 处理,B 觉得该 A 处理)会无限循环。第四,Swarm 本身已不再维护——生产不要直接用 Swarm 仓库,要用 OpenAI Agents SDK 或 LangGraph 的 handoff 抽象(第 12 章详述)。
Swarm 的 handoff 函数签名:Swarm 的 handoff 实现极简——handoff 是一个普通函数,接收 agent_name 与可选 context_vars,返回一个特殊对象告诉框架"控制权转给 X"。Agent 在自己的 functions 里调 handoff 函数即可触发路由——LLM 决定调哪个工具就决定路由到哪个 Agent。这种"工具即路由"的设计让 handoff 与 Function Calling 无缝整合——Agent 把 handoff_to_tech 当一个普通工具暴露给 LLM,LLM 根据上下文决定调用就触发 handoff。这种设计哲学启发了后来的 OpenAI Agents SDK——Agent 的 handoffs 字段就是从这里演化的。
Swarm 的适用与不适用:适用场景——客服流程路由(用户问题分类后转不同专家)、多专家协作(一个 Agent 觉得需要其他专家就 handoff)、灵活路由(无固定流程,Agent 按需 handoff)。不适用场景——严格流程控制(如金融交易必须按 A→B→C 顺序)应该用 LangGraph 显式图编排而非 Swarm 的隐式 handoff;大规模多 Agent(10+ Agent)Swarm 难调试易死锁,应该用 Supervisor 模式中心化调度;强一致性要求(多 Agent 必须看到同一 state)Swarm 的上下文打包传递容易不一致,应该用 LangGraph typed state。
5 种模式的对比¶
| 模式 | 拓扑 | 调度 | 典型场景 | 工程复杂度 |
|---|---|---|---|---|
| Supervisor + workers | 1 中心 + N 叶 | 中心化 | 客服 / 多专家咨询 | 中 |
| Sequential pipeline | 线性 A→B→C | 无 | 翻译 / 校对 / 润色 | 低 |
| Debate | N 辩手 + 1 裁判 | 中心化裁判 | 难题多视角 | 高(成本) |
| Hierarchical | 树状层级 | 逐层分派 | 大规模项目 | 高 |
| Swarm | 图状 handoff | 去中心化 | 客服路由 | 中 |
生产首选 Supervisor 模式——控制流清晰、可观测、可控;Swarm 适合需要灵活路由的客服场景;Debate 只在难题用;Hierarchical 只在大规模任务用;Pipeline 适合线性流水。
11.3 通信协议¶
多 Agent 之间怎么交换信息?这是多 Agent 系统的核心工程问题。主流有 3 种通信协议:
消息传递(message passing)¶
Agent 之间通过 LLM 消息 channel 通信——A Agent 在自己的 messages 里写一条"给 B 的消息",B Agent 在自己的 messages 里收到。这种通信方式最自然——LLM 本来就是用 messages 通信的,A 的输出直接作为 B 的输入。LangGraph 的 StateGraph 用这种方式——每个节点是一个 Agent,节点之间的边传递 messages。消息传递的优势:第一,语义自然——Agent 用自然语言交流,无需定义结构化 schema。第二,灵活——A 可以告诉 B 任意信息,B 自己理解。局限:第一,不可靠——A 的自然语言消息 B 可能误解。第二,难审计——自然语言消息不好做 schema 校验。生产场景需要把消息 schema 化(见工程要点)。
黑板模式(blackboard)¶
Agent 之间通过一个共享的"黑板"(shared state)通信——每个 Agent 把自己的中间结果写到黑板上,从黑板上读其他 Agent 的结果。黑板是一个结构化数据结构(如 dict),所有 Agent 都能读写。黑板模式的优势:第一,解耦——Agent 不需要知道彼此,只与黑板交互。第二,异步——Agent 任何时候都能读写黑板,无需同步等待。第三,可观测——黑板是单一可信源,调试时看黑板即可。局限:第一,并发冲突——多个 Agent 同时写黑板要加锁。第二,黑板膨胀——所有 Agent 的中间结果都堆在黑板上,黑板可能很大。第三,schema 演进难——黑板 schema 改了所有 Agent 都要适配。LangGraph 的 StateGraph 是黑板模式的实现——state dict 是黑板,节点是 Agent。
共享状态(shared state dict)¶
Agent 之间通过一个共享的 state dict 通信——与黑板模式类似但更结构化。state dict 是 typed schema(如 Pydantic / dataclass),每个字段有类型与语义。Agent 读 state 的某些字段,写某些字段。共享状态的优势:第一,类型安全——typed schema 让字段类型错误在编译时发现。第二,可校验——可以加 validator 检查 state 合法性。第三,可版本化——state schema 可以版本化,Agent 可以声明支持哪个版本。局限:第一,schema 设计成本——要预先设计好 state 字段。第二,schema 演进难——schema 改了所有 Agent 都要适配。共享状态是生产多 Agent 系统推荐的方式——schema 化的 state 让系统更健壮、更可观测。
三种协议的选择¶
按场景选通信协议。第一,快速原型:消息传递最简单——Agent 用自然语言交流,无需设计 schema。第二,生产系统:共享状态最稳——typed schema 让系统更健壮,便于审计。第三,异步松耦合系统:黑板模式——Agent 异步读写黑板,无同步等待。LangGraph 的 StateGraph 同时支持黑板(state dict)与消息传递(messages 字段),生产建议用 typed state schema + messages 字段的混合方式。
11.4 角色设计¶
多 Agent 系统的 4 种核心角色——规划者 / 执行者 / 批评者 / 裁判。每个角色有不同的 prompt 与工具集。
规划者(Planner)¶
规划者把用户大目标拆成子任务列表。prompt 要点:第一,强调"只规划不执行"——规划者不调工具,只输出子任务列表。第二,给出拆分原则——按依赖关系拆、按角色拆、按数据流向拆。第三,要求输出结构化——子任务列表用 JSON 输出,每个子任务有 id / description / required_role 字段。工具集:规划者通常无工具——它的产出是子任务列表,不是工具调用。典型 prompt:"你是任务规划者。把用户目标拆成 3-5 个子任务,按依赖顺序排列。输出 JSON:[{id, description, role}]。"规划者对应第 8 章的规划能力,但在多 Agent 系统里规划是单独 Agent 而非单 Agent 的一个 step。
执行者(Executor)¶
执行者接子任务,调工具完成。prompt 要点:第一,明确当前子任务——执行者 prompt 里塞入当前子任务描述。第二,给出可用工具列表——执行者只能调白名单工具。第三,要求输出结构化——执行结果用 JSON 输出,含 status / result / error 字段。工具集:执行者是主要调工具的 Agent——根据角色配不同工具集。售前执行者配"查价 / 报价"工具,技术执行者配"查文档 / 跑诊断"工具。典型 prompt:"你是 {role} 执行者。当前子任务:{task}。可用工具:{tools}。完成子任务后输出 JSON:{status, result, error}。"执行者对应第 6 章 ReAct 的 Action 步——但多 Agent 系统里执行者是单独 Agent 而非单 Agent 的一个 step。
批评者(Critic)¶
批评者检查执行者产出,发现问题。prompt 要点:第一,强调"只批评不修补"——批评者发现问题但不直接改,把问题反馈给执行者或主管。第二,给出批评维度——正确性 / 完整性 / 一致性 / 安全性。第三,要求输出结构化——批评结果用 JSON 输出,含 pass / issues / severity 字段。工具集:批评者配只读工具——查文档 / 查规则 / 查历史。典型 prompt:"你是批评者。检查执行者产出:{output}。按正确性 / 完整性 / 一致性 / 安全性 4 维批评。输出 JSON:{pass, issues:[{severity, description}]}。"批评者对应第 8 章 Reflexion 的反思步——但多 Agent 系统里批评是单独 Agent 而非单 Agent 的一个 step。
裁判(Judge / Aggregator)¶
裁判综合多个 Agent 的意见给最终答案,主要用于 Debate 模式。prompt 要点:第一,强调"综合而非取平均"——裁判不是简单投票,是基于论据强度综合。第二,给出综合原则——哪个 Agent 的论据更可信(基于其角色专精度 / 论据质量)。第三,要求输出最终答案与理由。工具集:裁判通常无工具——它的产出是综合判断。典型 prompt:"你是裁判。多 Agent 意见:{opinions}。综合给最终答案,说明理由。输出 JSON:{final_answer, reasoning, dissent}。"裁判是 Debate 模式独有的角色——Supervisor 模式里的 Supervisor 兼任裁判,但 Debate 模式里裁判是单独 Agent。
角色分离的工程价值¶
角色分离的工程价值是"对抗确认偏差"。单 Agent 一人扮多角容易"自己写的代码自己评不出 bug"——心理学上叫"确认偏差"。多 Agent 让不同角色由不同 Agent 实例扮演——批评者与执行者上下文隔离,批评者看到的是执行者的产出而非其思考过程,能更客观地发现问题。这种"角色分离"是 Reflexion(第 8 章)的进阶版——Reflexion 是单 Agent 自我反思,多 Agent 是不同 Agent 互相批评,更彻底。
11.5 失败模式¶
多 Agent 系统有 3 类典型失败模式——通信爆炸 / 上下文不一致 / 死锁。每种都有应对策略。
通信爆炸¶
症状:Agent 之间消息无限增长——A 给 B 发一条,B 回 A 一条,A 再回 B 一条更长的,每条消息越来越长,最终上下文爆炸。原因:Agent 不知道何时该停止通信,每个 Agent 都倾向于"把更多上下文塞给对方以防万一"。应对:第一,消息 schema 化——每条消息有 max length,超长截断。第二,通信轮数上限——设置 max_communication_rounds,超过强制终止。第三,summary message——每隔几轮把历史消息压成 summary,新 Agent 只看 summary。第四,显式终止信号——Agent prompt 里明确"任务完成就发 'DONE' 信号,不要再通信"。
上下文不一致¶
症状:各 Agent 看到的状态不同——A Agent 看到订单状态是"已发货",B Agent 看到的是"未发货",做决策时基于不一致状态出错。原因:多 Agent 系统无单一可信源——每个 Agent 维护自己的 state view,没及时同步。应对:第一,共享 state——所有 Agent 读写同一个 state dict(黑板模式),不维护自己的副本。第二,event sourcing——所有 state 变更走 event log,Agent 从 log 重建 state,保证一致。第三,乐观锁——Agent 写 state 前先 check version,version 变了就 re-read。第四,TTL 失效——Agent 缓存的 state view 有 TTL,超时强制 re-read。
死锁¶
症状:两个 Agent 互相 handoff——A 觉得该 B 处理,B 觉得该 A 处理,A→B→A→B 无限循环。原因:Agent 路由逻辑设计错误——两个 Agent 的 handoff 条件互相满足。应对:第一,handoff 深度上限——设置 max_handoff_depth(如 5),超过强制终止返回错误。第二,visited set——Agent handoff 时记录 visited set,不能 handoff 给已访问过的 Agent。第三,全局超时——整个任务有 timeout,超时强制终止。第四,显式终止条件——Agent prompt 里明确"任务完成就发 'DONE',不要 handoff"。死锁是 Swarm 模式特别容易出现的失败模式——去中心化路由容易成环,必须加 visited set + max_depth。
失败模式的检测¶
失败模式要靠 trace 与 metrics 检测。trace——LangSmith / Langfuse 的 trace 能看到 Agent 间消息往返次数、handoff 链深度、每个 Agent 的 token 消耗;trace 异常长(消息数 > 50 / handoff 深度 > 5)通常是通信爆炸或死锁。metrics——监控每个任务的 (agent_count, message_count, handoff_depth, total_tokens);阈值告警。日志——每个 Agent 的 thought / action / observation 落日志,事后能回溯。详见第 13 章可观测性。
11.6 检索子 Agent¶
本节复用第 5 章 RAG——在 Supervisor 模式中,检索子 Agent 是常见角色,本质上是一个封装了 RAG 流水线的 Agent。第 5 章详细讲了 RAG 流水线(文档切分 / 嵌入 / 向量检索 / 重排 / 生成),本节不重复 RAG 内部细节,只讲它怎么作为子 Agent 嵌入多 Agent 系统。
检索子 Agent 的角色¶
在 Supervisor 多 Agent 系统里,检索子 Agent 通常是子 Agent 之一——主管 Agent 接到用户问题后,如果判断"这需要查知识库",就 handoff 给检索子 Agent。检索子 Agent 内部跑 RAG 流水线:embedding 查询 → 向量检索 top-K → 重排 → 把检索结果塞进 prompt → 调 LLM 生成答案 → 返回给主管。主管拿到答案后转给用户或继续派给其他子 Agent(如技术子 Agent 做进一步处理)。
检索子 Agent 的工具集¶
检索子 Agent 的工具集是 RAG 流水线的封装——search_knowledge_base(query, top_k) 工具调向量库检索;rerank(documents) 工具做重排;generate_answer(query, context) 工具调 LLM 生成。这些工具复用第 5 章的实现——把第 5 章的 RAG 代码包装成 MCP 工具(第 10 章)或 LangChain Tool 即可。
检索子 Agent 的优势¶
把 RAG 包装成子 Agent 而非直接调函数的优势:第一,主管可路由——主管判断"需查知识库"才派检索子 Agent,避免每次都查库。第二,可观测——检索子 Agent 的 trace 显示检索了哪些文档、重排后保留哪些、生成耗时多少,便于调试。第三,可替换——换一个 RAG 实现(如换向量库 / 换 embedding 模型)只换检索子 Agent 内部,主管与其他子 Agent 不感知。第四,可组合——检索子 Agent 可以与其他子 Agent 协作——如技术子 Agent 先问检索子 Agent 查文档,再用查到的文档回答用户。
检索子 Agent 的工程要点¶
工程上把 RAG 包装成子 Agent 几个要点:第一,检索子 Agent 工具集**要 minimal——只暴露 search_and_answer(query) 一个工具给主管,主管不需要知道 RAG 内部步骤。第二,**结果 schema 化——检索子 Agent 返回 JSON:{answer, sources, confidence},便于主管决策。第三,confidence 阈值——检索子 Agent 返回 confidence 低于阈值时主管可以再派给人工或换其他子 Agent。第四,复用第 5 章 RAG——检索子 Agent 的 RAG 流水线就是第 5 章的实现,本章不重复——把它包装成 Agent 接口即可。
代码片段:最小 Supervisor + workers 实现¶
下面用 LangGraph StateGraph 实现最小 Supervisor + workers 多 Agent 系统——主管 Agent 接任务后决定派给售前 / 技术哪个子 Agent,子 Agent 执行后返回主管,主管汇总回用户:
# pip install langgraph langchain-openai
from typing import TypedDict, Literal
from langgraph.graph import StateGraph, START, END
class AgentState(TypedDict):
question: str
role: str | None
answer: str | None
history: list[str]
def supervisor(state: AgentState) -> dict:
"""主管 Agent:判断派给哪个子 Agent。"""
q = state["question"]
if any(k in q for k in ["价格", "报价", "买"]):
role = "presales"
else:
role = "tech"
return {"role": role, "history": [f"supervisor→{role}"]}
def presales_worker(state: AgentState) -> dict:
"""售前子 Agent:查价 / 报价。"""
return {"answer": f"售前报价:{state['question']} → 999 元/年",
"history": state["history"] + ["presales done"]}
def tech_worker(state: AgentState) -> dict:
"""技术子 Agent:查文档 / 给方案。"""
return {"answer": f"技术方案:{state['question']} → 部署文档 xxx",
"history": state["history"] + ["tech done"]}
def route(state: AgentState) -> Literal["presales", "tech"]:
return state["role"]
g = StateGraph(AgentState)
g.add_node("supervisor", supervisor)
g.add_node("presales", presales_worker)
g.add_node("tech", tech_worker)
g.add_edge(START, "supervisor")
g.add_conditional_edges("supervisor", route, {"presales": "presales", "tech": "tech"})
g.add_edge("presales", END)
g.add_edge("tech", END)
app = g.compile()
# 跑一次
result = app.invoke({"question": "X 产品多少钱", "history": []})
print(result["answer"], result["history"])
# 售前报价:X 产品多少钱 → 999 元/年 ['supervisor→presales', 'presales done']
这段代码约 35 行,演示了 Supervisor + workers 的核心——主管 supervisor 节点决定路由,presales / tech 两个子 Agent 节点各自执行,route 函数实现条件边。AgentState 是 shared state dict(黑板模式),所有 Agent 读写它。
工程实战要点¶
- 多 Agent 不是越多越好:3 个 Agent 是甜蜜点(主管 + 2-3 子 Agent),超过 5 个收益递减复杂度暴涨;简单任务用单 Agent + 好 prompt 就够,多 Agent 是过度设计。
- Swarm handoff 要记上下文:handoff 时要把 messages 与 vars 序列化打包传给下一个 Agent;上下文压缩要谨慎——关键信息(如用户身份、订单号)要明确保留,不能被 summary 丢掉。
- Supervisor 模式最适合生产:控制流清晰(所有任务过主管)、可观测(主管 trace 显示分派了哪些任务)、可控(主管可重试 / 换 Agent);生产首选 Supervisor,Swarm / Debate / Hierarchical 按场景用。
- Debate 模式贵——只在难题用:N 个 Agent + 1 裁判成本是单 Agent 的 N+1 倍,简单任务用 Debate 是浪费;只在难题(如架构决策、复杂推理)用 Debate,简单任务单 Agent 一步出答案。
- Agent 间消息要 schema 化:自然语言消息不可靠(B 可能误解 A 的意思)也不可审计;用 typed schema(Pydantic / dataclass)让消息字段类型化,便于校验与调试;LangGraph 的 StateGraph typed state 是推荐做法。
小结¶
- 多 Agent 出现的四个动因:上下文专精(一 Agent 一职)、并行(多 Agent 同时跑)、角色分工(规划 / 执行 / 批评 / 裁判)、可观测(每 Agent 单独 traceable)。
- 5 种协作模式:Supervisor + workers(中心化,生产首选)/ Sequential pipeline(线性串行,最简单)/ Debate(多 Agent 辩论 + 裁判,难题用)/ Hierarchical(树状层级,大规模用)/ Swarm(去中心化 handoff,客服路由用)。
- OpenAI Swarm(github.com/openai/swarm,2024.10 发布,已不再维护):核心思想是 Agent 间通过
handoff函数转移控制权与上下文;与 Supervisor 的根本区别是去中心化无中央调度;局限是上下文压缩丢信息 / handoff 链难调试 / 死锁风险。 - 3 种通信协议:消息传递(LLM messages channel,最自然)/ 黑板模式(shared state,解耦异步)/ 共享状态(typed state dict,生产推荐)。
- 4 种角色:规划者(拆任务,无工具)/ 执行者(调工具做任务)/ 批评者(检查产出,只读工具)/ 裁判(综合多 Agent 意见,Debate 独有)。
- 3 类失败模式:通信爆炸(消息 schema 化 + 轮数上限应对)/ 上下文不一致(共享 state + event sourcing 应对)/ 死锁(visited set + max_depth 应对)。
- 检索子 Agent 复用第 5 章 RAG——把 RAG 流水线包装成 Agent 接口嵌入 Supervisor 模式,让主管可路由、可观测、可替换、可组合。
练习题¶
- 列出多 Agent 协作的 5 种模式。
- Supervisor 模式与 Swarm 模式的根本区别?
- OpenAI Swarm 的 handoff 机制是什么?
- 多 Agent 通信协议的三种实现?
- 多 Agent 协作的三种失败模式?
- 检索子 Agent 在 Supervisor 模式中的角色是什么?
参考答案¶
第 1 题答案
多 Agent 协作的 5 种模式:第一,**Supervisor + workers**——一个主管 Agent 中心化调度,多个子 Agent 执行;典型场景是客服主管 + 售前 / 售后 / 技术子 Agent。第二,**Sequential pipeline**——A → B → C 线性串行,前一个输出是后一个输入;典型场景是翻译 → 校对 → 润色。第三,**Debate**——多个 Agent 同时回答同一问题再由裁判综合;典型场景是多模型多视角回答架构问题。第四,**Hierarchical**——树状层级 CEO → 经理 → IC;典型场景是多团队协作的大规模项目。第五,**Swarm(OpenAI handoff)**——Agent 之间通过 handoff 函数转移控制权,无中央调度;典型场景是客服流程路由。生产首选 Supervisor(控制流清晰可观测),Debate 只在难题用,Hierarchical 只在大规模任务用,Pipeline 适合线性流水,Swarm 适合灵活路由的客服场景。第 2 题答案
Supervisor 模式与 Swarm 模式的根本区别是**中心化 vs 去中心化**。**Supervisor 模式是中心化的**——所有任务过主管 Agent,主管决定派给哪个子 Agent,子 Agent 之间不直接通信,子 Agent 之间协作都要过主管多一跳。Supervisor 像公司经理——员工不能直接找别的部门,所有跨部门协作要过经理。**Swarm 模式是去中心化的**——无中央调度,每个 Agent 自己决定下一步 handoff 给谁,Agent 之间直接转移控制权。Swarm 像接力赛——每棒交给下一棒,没有中央指挥。具体差异:第一,**调度位置**——Supervisor 在主管,Swarm 在每个 Agent 自己。第二,**Agent 间通信**——Supervisor 子 Agent 之间不直接通信,Swarm Agent 之间直接 handoff。第三,**控制流清晰度**——Supervisor 控制流清晰可观测,Swarm 控制流分散难调试。第四,**死锁风险**——Supervisor 主管决定不会成环,Swarm 容易成环死锁要加 visited set。生产首选 Supervisor,Swarm 适合灵活路由场景。第 3 题答案
OpenAI Swarm 的 handoff 机制是"Agent 之间通过 `handoff` 函数转移控制权与上下文"。具体来说:第一,**handoff 函数**——前一个 Agent 调用 `handoff(other_agent, context)` 后控制权转给 `other_agent`。第二,**上下文打包**——前 Agent 把已积累的 messages 列表与任意变量序列化打包传给后 Agent,后 Agent 看到的是前 Agent 的完整上下文。第三,**Agent 自决路由**——每个 Agent 在自己的 prompt 里声明"什么情况下 handoff 给谁",Agent 自己决定路由,无中央调度。第四,**典型场景**——客服流程:用户问题进 triage Agent 分类,triage 判断是售前就 handoff 给售前 Agent,售前处理中发现需要技术确认就 handoff 给技术 Agent,技术解决后回用户。第五,**来源与现状**——Swarm 来自 OpenAI 2024 年 10 月发布的开源仓库 github.com/openai/swarm,定位为教学概念原型,现已不再维护,但 handoff 思想被 OpenAI Agents SDK 与多个第三方框架吸收。第六,**局限**——上下文压缩可能丢信息 / handoff 链过长难调试 / 死锁风险(A↔B 互相 handoff)。第 4 题答案
多 Agent 通信协议的三种实现:第一,**消息传递(message passing)**——Agent 之间通过 LLM messages channel 通信,A 在 messages 里写"给 B 的消息",B 收到。优势是语义自然(LLM 本来就用 messages 通信)、灵活(A 可告诉 B 任意信息);局限是不可靠(自然语言 B 可能误解 A)、难审计(无 schema 校验)。LangGraph StateGraph 节点间用这种方式。第二,**黑板模式(blackboard)**——Agent 之间通过一个共享"黑板"(shared state dict)通信,每个 Agent 把中间结果写到黑板上,从黑板上读其他 Agent 的结果。优势是解耦(Agent 不需知道彼此)、异步(任何时候都能读写)、可观测(黑板是单一可信源);局限是并发冲突(多 Agent 同时写要加锁)、黑板膨胀。LangGraph StateGraph 是黑板模式的实现。第三,**共享状态(shared state dict)**——与黑板类似但更结构化,state dict 是 typed schema(Pydantic / dataclass),每个字段有类型与语义。优势是类型安全、可校验、可版本化;局限是 schema 设计成本高、schema 演进难。生产推荐 typed state + messages 字段混合方式。第 5 题答案
多 Agent 协作的三种失败模式:第一,**通信爆炸**——Agent 之间消息无限增长,A 给 B 发一条,B 回一条更长的,每条越来越长最终上下文爆炸。原因是 Agent 不知道何时该停止通信,每个 Agent 都倾向于"把更多上下文塞给对方以防万一"。应对策略:消息 schema 化(每条 max length 截断)、通信轮数上限(max_communication_rounds)、summary message(定期压缩历史)、显式终止信号(prompt 里要求发 'DONE')。第二,**上下文不一致**——各 Agent 看到的状态不同,A 看到订单已发货 B 看到未发货,决策基于不一致状态出错。原因是多 Agent 系统无单一可信源,每个 Agent 维护自己的 state view 没及时同步。应对:共享 state(所有 Agent 读写同一个 state dict 不维护副本)、event sourcing(所有 state 变更走 event log)、乐观锁(写前 check version)、TTL 失效(缓存超时强制 re-read)。第三,**死锁**——两个 Agent 互相 handoff,A→B→A→B 无限循环。原因是 Agent 路由逻辑设计错误,两个 Agent 的 handoff 条件互相满足。应对:handoff 深度上限、visited set(不 handoff 给已访问过的 Agent)、全局超时、显式终止条件。死锁是 Swarm 模式特别容易出现的失败模式。第 6 题答案
检索子 Agent 在 Supervisor 模式中的角色是**封装了 RAG 流水线的子 Agent**——本节复用第 5 章 RAG 的实现。具体角色:第一,**作为子 Agent 之一**——在 Supervisor 多 Agent 系统里,检索子 Agent 是常见子 Agent 角色,与售前 / 售后 / 技术子 Agent 并列。第二,**主管路由**——主管 Agent 接到用户问题后判断"需查知识库"就 handoff 给检索子 Agent,避免每次都查库。第三,**内部跑 RAG 流水线**——检索子 Agent 内部封装第 5 章的 RAG 流水线:embedding 查询 → 向量检索 top-K → 重排 → 检索结果塞 prompt → 调 LLM 生成答案 → 返回主管。第四,**工具集 minimal**——只暴露 `search_and_answer(query)` 一个工具给主管,主管不需知道 RAG 内部步骤。第五,**结果 schema 化**——返回 JSON:`{answer, sources, confidence}`,便于主管决策。第六,**confidence 阈值**——confidence 低于阈值时主管可再派给人工或换其他子 Agent。第七,**工程价值**——把 RAG 包装成子 Agent 让主管可路由(按需查库)、可观测(trace 显示检索了哪些文档)、可替换(换 RAG 实现不影响其他 Agent)、可组合(与技术子 Agent 协作)。下一章:第十二章 框架对比与选型