1. 从单打独斗到组队干活多 Agent 协作到底解决了什么问题如果你最近在折腾 AI Agent大概率会有一种感觉单个 Agent 能做的事情好像已经摸到天花板了。你给它一个复杂任务比如帮我调研一下某个行业的竞品情况整理成一份带数据支撑的报告它要么在中间某一步跑偏要么上下文塞爆了开始胡言乱语要么就是反复调用同一个工具陷入死循环。这不是模型不够聪明而是单 Agent 架构本身有结构性缺陷。我最早接触多 Agent 协作是在做一个自动化内容生产流程的时候。当时的需求听起来不复杂给定一个主题自动完成资料搜集、大纲生成、正文撰写、事实核查、格式排版五个环节。我一开始用单 Agent 串行做结果发现两个致命问题。第一是上下文污染——搜集阶段塞进去的大量原始资料会严重干扰后面撰写阶段的判断模型经常把调研笔记里的口语化表达直接写进正式文稿。第二是角色冲突——同一个 Agent 既要当创作者又要当审核者它在核查自己写的内容时倾向于认为我写的肯定没问题核查形同虚设。这两个问题本质上和人类团队协作中遇到的情况一模一样。你不会让同一个人既写方案又审方案还做终审因为角色混淆必然导致质量失控。多 Agent 协作的核心价值就是把角色从能力里拆出来让每个 Agent 只专注一件事通过结构化的协作流程把复杂任务拆解、分发、汇总。而 Leader-Worker 架构是目前工程落地中最常见、也最容易理解的一种多 Agent 组织方式。它的思路非常直白一个 Leader Agent 负责理解任务、拆解子任务、分派给合适的 Worker、收集结果、判断是否完成若干个 Worker Agent 各自负责一个具体能力域比如搜索、写代码、调 API、做总结。Leader 不干活只做调度和决策Worker 不决策只执行和回报。这个架构之所以火是因为它对应了真实工程里最朴素的分工逻辑。你想想一个外包项目的运作方式项目经理Leader接需求、拆任务、分配给开发、测试、设计Worker然后验收汇总。多 Agent 的 Leader-Worker 就是把这套流程自动化了。关键词里的多 Agent 协作Agent 架构分布式架构这些热词背后指向的都是同一个问题怎么让多个能力有限的 Agent通过协作完成单个 Agent 完不成的复杂任务。这篇文章我会从实操角度把 Leader-Worker 架构讲透。包括它适合什么场景、Leader 和 Worker 分别怎么设计、通信机制怎么选、任务拆解到什么粒度、以及最关键的——怎么防止它翻车。翻车这件事我踩过的坑太多了Leader 陷入无限分派、Worker 返回垃圾结果被当成有效输入、任务拆得太细导致通信开销爆炸、拆得太粗又退化成单 Agent。这些坑我都会给出具体的排查思路和修复方案。适合谁看如果你已经写过单 Agent 的 demo想往生产级的多 Agent 系统推进这篇内容会帮你少走至少两三个月的弯路。如果你还没接触过 Agent 开发建议先补一下工具调用Function Calling和 ReAct 循环的基础否则后面的调度逻辑会看得比较吃力。2. Leader-Worker 架构的骨架谁负责决策谁负责执行2.1 Leader 不是更聪明的 Agent而是更克制的调度器很多人第一次设计 Leader 的时候会本能地把它做成一个全能型 Agent——既能拆任务又能自己干活还能审核结果。这是个典型的误区。Leader 一旦开始干活它就会陷入细节失去全局视角最后退化成单 Agent。我现在的做法是给 Leader 设定三条硬性约束。第一Leader 不直接调用业务工具它只能调用分派任务和查询 Worker 状态这两个元工具。第二Leader 的输出必须是结构化的任务指令而不是自然语言描述比如输出一个 JSON 包含任务类型、输入参数、期望输出格式、超时时间。第三Leader 必须有明确的终止条件不能无限循环分派。Leader 的核心能力其实是三件事任务理解与拆解、Worker 能力匹配、结果聚合与终止判断。这三件事里最难的是拆解粒度。拆得太细比如把写一段代码拆成写第一行、写第二行通信开销会直接压垮系统拆得太粗比如把完成整个项目当成一个子任务丢给 Worker那 Worker 又变成了单 Agent问题原封不动地转移了。我的经验法则是一个子任务应该对应一个 Worker 的一次完整能力调用且这个子任务的输出可以被独立验证。比如搜索某个关键词并返回前 5 条结果的标题和链接就是一个合格的子任务因为它的输出可以独立检查对错。而帮我了解一下这个行业就不是因为它没有明确的完成标准。2.2 Worker 的设计能力单一化接口标准化Worker 的设计原则和微服务架构里的服务设计几乎一模一样单一职责、标准接口、无状态优先。每个 Worker 只负责一类任务比如搜索 Worker、代码执行 Worker、文档解析 Worker、数据计算 Worker。它的输入输出格式必须统一通常是结构化的 JSON这样 Leader 才能无差别地调度。这里有个容易被忽略的点Worker 需要有能力声明。也就是说Leader 在分派任务之前得知道每个 Worker 能干什么、不能干什么、当前是否可用。我通常会给每个 Worker 注册一份能力清单包含能力名称、输入 schema、输出 schema、预估耗时、并发上限。Leader 在匹配任务时先查能力清单再决定分派给谁。{ worker_id: search_worker_01, capabilities: [web_search, url_fetch], input_schema: {query: string, top_k: int}, output_schema: {results: array, status: string}, estimated_latency_ms: 3000, max_concurrency: 5, current_load: 2 }这份清单看起来简单但它解决了一个大问题Leader 不会把任务分派给不具备该能力的 Worker。我早期没做这个结果 Leader 经常把执行 Python 代码的任务分给搜索 Worker搜索 Worker 硬着头皮返回一堆搜索结果Leader 还以为是代码执行结果整个流程直接跑偏。2.3 通信机制消息传递还是共享状态Leader 和 Worker 之间的通信主流有两种模式。一种是消息传递Leader 把任务打包成消息发给 WorkerWorker 处理完把结果打包成消息发回来。另一种是共享状态所有 Agent 读写同一个状态存储比如一个共享的上下文对象或数据库通过状态变化来协调。消息传递的优点是解耦彻底Worker 可以分布在不同进程甚至不同机器上适合关键词里提到的分布式架构场景。缺点是调试麻烦消息丢了或者格式错了排查起来要翻日志。共享状态的优点是调试直观所有中间结果都在一个地方缺点是并发写容易冲突而且状态会越滚越大最后又变成上下文爆炸。我现在的选择是混合模式任务分派和结果回传走消息传递保证解耦中间产物和全局上下文走共享状态但只存引用不存全量数据。比如 Worker 返回一个大文档共享状态里只存文档的 ID 和摘要完整内容放在对象存储里需要的时候再取。这样既保留了调试便利又避免了状态膨胀。提示不管选哪种通信机制一定要给每条消息带上task_id和trace_id。前者用于关联任务和结果后者用于跨 Agent 的全链路追踪。没有这两个 ID多 Agent 系统出问题基本没法排查。3. 任务拆解与分派Leader 最容易翻车的三个环节3.1 拆解粒度从一句话需求到可执行子任务的翻译过程Leader 接收到的往往是模糊的自然语言需求比如帮我分析一下这份销售数据并给出改进建议。它需要把这个需求翻译成一系列可执行的子任务。这个过程我称之为任务翻译它是整个架构里最容易出问题的地方。我见过最常见的翻车方式是拆解不完整。Leader 拆出了读取数据计算统计量生成建议三个子任务但漏掉了数据清洗这一步。结果计算统计量的时候遇到空值和异常值Worker 要么报错要么返回错误结果Leader 拿到错误结果继续往下走最后生成的建议完全基于垃圾数据。另一个常见问题是拆解顺序错误。有些子任务之间有依赖关系比如生成建议必须在计算统计量之后。如果 Leader 没有正确识别依赖把任务并行分派出去就会出现建议基于不存在的统计结果生成的情况。我的做法是让 Leader 在拆解时显式输出一个依赖图标明哪些任务可以并行、哪些必须串行。{ tasks: [ {id: t1, type: read_data, depends_on: []}, {id: t2, type: clean_data, depends_on: [t1]}, {id: t3, type: compute_stats, depends_on: [t2]}, {id: t4, type: generate_advice, depends_on: [t3]} ] }有了依赖图Leader 的调度逻辑就清晰了先找出所有depends_on为空的任务并行分派等它们完成后再找出依赖已满足的任务继续分派直到所有任务完成。3.2 分派策略轮询、负载均衡还是能力优先任务分派看起来简单其实有不少讲究。最朴素的是轮询按顺序把任务分给 Worker。但问题是不同 Worker 的能力和负载不一样轮询会导致有的 Worker 忙死、有的闲着。我目前用的是能力优先 负载均衡的组合策略。先按能力筛选出能处理该任务的 Worker 集合再在这个集合里选当前负载最低的。负载的计算方式是current_load / max_concurrency比值越低越优先。这个策略在 Worker 数量不多十几个以内的时候效果很好实现也简单。如果 Worker 数量上百就需要更复杂的调度比如基于历史响应时间的加权调度或者引入独立的调度器组件。但说实话大部分多 Agent 应用根本到不了这个规模过早优化调度策略是浪费时间。我建议先把能力匹配和基础负载均衡做好等真的遇到性能瓶颈再升级。3.3 结果聚合怎么判断 Worker 返回的是有效结果而不是看起来像结果的垃圾这是我认为整个 Leader-Worker 架构里最被低估的环节。Worker 返回的结果Leader 不能无条件信任。因为 Worker 也是 LLM 驱动的它完全可能返回一个格式正确、但内容完全错误的结果。我踩过的一个典型坑搜索 Worker 被要求查找某公司 2023 年的营收数据它返回了一个格式完美的 JSON包含数字、单位、来源链接。Leader 直接采信写进了最终报告。后来人工核查发现那个数字是 2021 年的Worker 把年份搞错了但格式完全正确Leader 没有任何机制发现这个错误。解决这个问题的核心思路是引入验证环节。有两种做法。一种是让 Leader 自己做轻量验证比如检查返回结果的字段是否齐全、数值是否在合理范围内、来源链接是否可访问。另一种是设置专门的验证 Worker对关键结果做交叉验证。我通常对高价值任务用第二种对低价值任务用第一种。验证的具体手段包括格式校验JSON schema 匹配、范围校验数值是否在预期区间、来源校验引用的链接是否真实存在、一致性校验多个 Worker 对同一问题的回答是否一致。这几种校验组合起来能拦掉大部分看起来像结果的垃圾。注意验证环节本身也有成本。如果每个结果都做全量交叉验证系统延迟会翻倍。我的经验是只对影响最终输出的关键结果做验证中间过程的辅助结果可以放宽。4. 防翻车实战五类高频故障的排查与修复4.1 无限分派循环Leader 停不下来的根因与解法这是 Leader-Worker 架构最经典的故障。Leader 分派任务给 WorkerWorker 返回结果Leader 觉得结果不够好又分派一个类似的任务如此循环直到 token 耗尽或者超时。根因通常有两个。第一是Leader 没有明确的完成标准它不知道什么样的结果算够了。第二是Worker 返回的结果质量不稳定Leader 反复尝试期望得到更好的结果但每次都不满意。我的解法是给 Leader 设置三重保险。第一最大迭代次数比如整个任务最多分派 20 次超过就强制终止并返回当前最优结果。第二任务去重Leader 分派新任务前先检查是否已经分派过相同或高度相似的任务如果是直接复用之前的结果而不是重新分派。第三质量阈值给每类任务设定一个可接受的质量下限达到下限就停止优化。def should_continue(leader_state): if leader_state.iteration_count MAX_ITERATIONS: return False if leader_state.has_duplicate_task(): return False if leader_state.current_quality QUALITY_THRESHOLD: return False return True这三个条件任意一个不满足Leader 就停止分派进入结果聚合阶段。实测下来这套机制能把无限循环的概率降到几乎为零。4.2 Worker 返回格式错误从 schema 校验到自动重试Worker 返回的结果格式不对是另一个高频问题。比如要求返回 JSON它返回了一段带 markdown 代码块的文本要求返回数组它返回了一个对象。Leader 解析失败整个流程卡住。这个问题分两层解决。第一层是输出约束在 Worker 的 prompt 里明确要求输出格式并给出示例。同时用结构化输出Structured Output能力让模型直接生成符合 schema 的内容而不是生成文本再解析。第二层是解析容错Leader 在解析 Worker 结果时先尝试直接解析失败则尝试提取代码块内容再解析再失败则触发重试。重试策略也有讲究。不能无脑重试因为同样的 prompt 重试大概率还是同样的错误。我的做法是重试时附加错误信息告诉 Worker你上次返回的格式不对错误是 XXX请重新返回符合 YYY 格式的内容。这样 Worker 有了明确的修正方向重试成功率会高很多。4.3 上下文爆炸多 Agent 协作中的信息传递瘦身多 Agent 协作的一个隐性成本是上下文膨胀。每个 Worker 的输入输出都要经过 LeaderLeader 的上下文里堆积了所有历史任务和结果很快就会超出模型窗口。我见过最夸张的案例是一个 Leader 的上下文里塞了 30 多个 Worker 的完整返回结果加起来十几万 token模型直接开始丢失早期信息调度逻辑完全混乱。瘦身的核心原则是只传必要信息不传全量数据。具体做法有三条。第一Worker 返回结果时只返回摘要和引用 ID完整数据存到外部存储。第二Leader 维护一个任务状态表只记录每个任务的 ID、状态、结果摘要不记录完整结果。第三定期清理已完成任务的中间数据只保留最终输出。# 不推荐把完整结果塞进 Leader 上下文 leader_context.append({task: t1, result: full_document_text}) # 推荐只存摘要和引用 leader_context.append({ task: t1, status: completed, summary: 找到 5 条相关数据关键指标为 XXX, result_ref: storage://results/t1.json })这样 Leader 的上下文大小基本恒定不会随任务数量增长而爆炸。4.4 Worker 之间结果冲突谁说了算当多个 Worker 对同一问题给出不同答案时Leader 该信谁这个问题在事实核查、数据查询类任务里特别常见。我的处理策略分三级。第一级是来源可信度排序给每个 Worker 设定可信度权重冲突时优先采信高权重 Worker 的结果。第二级是多数投票如果多个 Worker 独立给出结果取多数一致的那个。第三级是人工介入如果前两级都无法解决把冲突标记出来交给人工判断。这里有个经验不要让 Leader 自己编一个折中答案。我早期试过让 Leader 综合两个冲突结果生成一个新答案结果它经常生成一个既不是 A 也不是 B 的第三种答案而且看起来还挺合理实际上完全是幻觉。冲突就是冲突要么按规则裁决要么上报不要试图让模型调和。4.5 单点故障Leader 挂了整个系统就瘫了Leader 是整个架构的单点。如果 Leader 因为某种原因失败模型超时、解析错误、状态丢失整个任务就卡住了。基础的解法是状态持久化 断点续跑。Leader 的每一步状态都持久化到外部存储失败后可以从最后一个成功状态恢复而不是从头开始。进阶的解法是Leader 冗余部署多个 Leader 实例通过选举机制选出一个主 Leader主 Leader 挂了备用顶上。不过说实话对于大部分应用状态持久化 断点续跑已经够用了。Leader 冗余的复杂度很高除非你的系统对可用性要求极高否则不值得。我现在的项目里Leader 失败后自动从最近 checkpoint 恢复恢复时间通常在几秒内用户基本无感知。5. 从 Demo 到生产多 Agent 系统的工程化细节5.1 可观测性没有 trace 的多 Agent 系统等于黑盒多 Agent 系统的调试难度是单 Agent 的好几倍因为问题可能出在任何一个 Agent、任何一次通信、任何一个决策点。没有完善的可观测性排查问题基本靠猜。我现在的标配是三样东西结构化日志、全链路 trace、实时监控面板。结构化日志记录每个 Agent 的输入输出、决策理由、耗时全链路 trace 用trace_id把一次任务涉及的所有 Agent 调用串起来监控面板实时展示任务成功率、平均耗时、各 Worker 负载、错误分布。这里特别说一下决策理由的记录。Leader 每次分派任务时让它输出为什么分派给这个 Worker为什么拆成这几个子任务。这些理由在排查问题时极其有用。我遇到过 Leader 把任务分派给错误 Worker 的情况看日志发现它的理由是这个 Worker 名字里有 search应该能搜索实际上那个 Worker 是搜索日志分析不是网络搜索。有了决策理由这种问题一眼就能定位。5.2 成本控制多 Agent 的 token 消耗是单 Agent 的数倍多 Agent 协作的 token 消耗远高于单 Agent因为每次通信、每次决策都要消耗 token。一个原本单 Agent 花 5000 token 的任务多 Agent 化之后可能花 30000 token。控制成本的手段有几个。第一用小模型做简单决策比如任务分派、格式校验这些不需要强推理的环节用便宜的小模型。第二缓存重复结果相同或相似的子任务直接复用缓存不重新调用。第三限制上下文长度前面说的瘦身策略同时也是成本控制手段。第四设置预算上限每个任务设定 token 预算超了就降级处理或终止。我实测下来合理优化后多 Agent 的成本可以控制在单 Agent 的 2 到 3 倍而不是无脑实现的 5 到 10 倍。这个成本换来的质量提升在复杂任务上是值得的。5.3 测试策略怎么验证一个多 Agent 系统是可靠的多 Agent 系统的测试比传统软件难得多因为输出是非确定性的。同样的输入两次运行可能得到不同结果。我的测试策略分三层。第一层是单元测试针对每个 Worker 单独测试验证它在给定输入下能返回符合 schema 的输出。第二层是集成测试用固定的任务集测试整个 Leader-Worker 流程验证端到端能跑通。第三层是回归测试维护一个黄金任务集每次改动后跑一遍对比输出质量是否下降。这里的关键是建立评估标准。不能只看跑通了没有还要看结果质量如何。我的做法是给每个黄金任务定义一组检查点比如是否包含至少 3 个数据来源是否给出了可执行的建议是否有明显的事实错误。每次回归测试自动检查这些点任何一个不通过就标记为回归。提示多 Agent 系统的测试用例要覆盖异常路径而不只是正常路径。比如 Worker 超时、Worker 返回格式错误、Leader 分派失败、依赖任务失败等场景都要有对应的测试用例。这些异常路径在生产环境里出现的频率远比你想象的高。6. 一些踩坑之后的个人体会Leader-Worker 架构看起来简单但真正落地的时候细节多到让人头皮发麻。我做了几个多 Agent 项目之后最大的体会是架构的复杂度应该匹配任务的复杂度。如果你的任务用单 Agent 加几个工具就能搞定千万别上多 Agent那是给自己找麻烦。多 Agent 的价值只在任务确实需要多角色协作、且单 Agent 确实做不好的时候才体现。另一个体会是先跑通再优化。我见过太多人一上来就设计复杂的调度算法、完善的容错机制、精美的监控面板结果核心流程还没跑通。正确的顺序是先做一个最简版本——一个 Leader、两个 Worker、最简单的消息传递——跑通一个真实任务然后再逐步加验证、加重试、加监控。每加一个机制都要问自己它解决了什么具体问题解决不了具体问题的机制就是过度设计。最后分享一个我常用的调试技巧把 Leader 的决策过程完整打印出来。不是打印最终结果而是打印它每一步的思考——为什么这样拆解、为什么分派给这个 Worker、为什么认为任务完成了。多 Agent 系统出问题90% 的情况是 Leader 的某个决策错了而决策错误的原因往往藏在它的思考过程里。把这个过程可视化大部分问题都能自己浮出来。这套架构还在快速演进新的模式比如层级式 LeaderLeader 下面还有子 Leader、动态角色分配Worker 根据任务临时切换角色都在出现。但底层的核心逻辑没变拆解、分派、执行、验证、聚合。把这五个环节做扎实不管架构怎么变你都能快速适配。
