ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

多 Agent 协作实战:从角色划分到 handoff 的 Skill 设计

多 Agent 协作实战:从角色划分到 handoff 的 Skill 设计 多 Agent 协作这件事我从去年下半年开始断断续续折腾到现在中间推翻过至少三套方案。最早我天真地以为多开几个对话窗口让它们各干各的就叫协作结果上下文互相污染、任务边界模糊、改到一半发现两个 Agent 在改同一个文件最后交付的东西还不如我自己写。后来我才慢慢想明白多 Agent 协作的核心根本不是多而是协作协议——谁负责什么、什么时候交接、交接时带哪些上下文、冲突了听谁的。这套东西想清楚了两个 Agent 也能跑得很顺想不清楚开十个也是互相添乱。这篇文章我想把自己现在正在用的这套多 Agent 协作方式完整拆开讲一遍包括我为什么这么设计、每个环节踩过什么坑、以及我沉淀下来的一个协作 Skill 到底长什么样。关键词会围绕多 Agent、协作、Skill、handoff、AGENTS.md这几个点展开适合已经用过单个 Agent 干活、但一上多 Agent 就乱套的朋友。如果你还在纠结要不要上多 Agent我的建议是先看完这篇再决定因为多 Agent 不是免费的午餐它带来的协调成本是实打实的。1. 先想清楚多 Agent 到底解决的是哪类问题1.1 单 Agent 的天花板在哪里单个 Agent 干活能力上限其实受两个东西限制上下文窗口和角色一致性。上下文窗口是硬约束任务一复杂、文件一多前面读的东西后面就忘了或者被压缩得只剩个摘要细节全丢。角色一致性则是软约束你让一个 Agent 既当架构师又当实现者还当测试它在不同阶段的心态是漂移的——写架构的时候想着赶紧写完去写代码写代码的时候又想着测试应该能过吧最后每个环节都差一口气。我举个具体的例子。之前我让一个 Agent 帮我重构一个中等规模的模块大概两千行代码。它一开始分析得头头是道列了七八个重构点。等它真正动手改到第五个文件的时候前面分析里提到的这个函数被三个地方调用改签名要同步已经被它忘干净了直接改了签名没管调用方编译直接炸。这不是它笨是上下文被挤掉了。单 Agent 处理这种需要全局视野 长链路操作的任务天然吃亏。1.2 多 Agent 不是人多力量大很多人对多 Agent 的第一反应是并行加速这个理解只对了一半。多 Agent 真正值钱的地方是关注点分离让一个 Agent 只干一件事它的上下文里就只有这件事相关的信息角色也不会漂移。至于并行那是顺带的好处而且并行本身会引入新的问题——资源竞争、结果合并、顺序依赖。我现在的判断标准很简单如果一个任务能被清晰地切成几个输入输出明确、彼此耦合低的子任务那多 Agent 就值得上如果切完之后子任务之间还要频繁来回沟通那还不如单 Agent 一口气干完。切分带来的沟通成本很容易超过并行省下的时间。1.3 什么场景我才会真的上多 Agent结合我自己的实践下面这几类场景我会毫不犹豫地上多 Agent研究 实现分离一个 Agent 专门去读文档、读代码、做调研产出一份结构化的事实清单另一个 Agent 拿着这份清单去写代码。调研 Agent 的上下文里全是原始资料实现 Agent 的上下文里全是结论和接口两边都干净。实现 审查分离写代码的 Agent 和审代码的 Agent 必须是两个而且审查的那个不能看到实现过程的纠结只看最终 diff。这样它才不会被作者的解释带偏。多方案并行探索同一个问题让三个 Agent 用不同思路各做一版最后我来挑或者融合。这种场景下并行是真的省时间。长流程流水线比如抓数据 → 清洗 → 分析 → 出报告每一段都是独立的天然适合拆。反过来下面这些我踩过坑、现在坚决不拆的需求本身还在反复变的、需要大量来回讨论才能推进的、子任务之间共享大量隐式知识的。这些拆了就是自找麻烦。2. 我的协作骨架角色、handoff 与共享上下文2.1 角色划分少即是多我试过最夸张的一次是分了六个角色规划、调研、架构、实现、测试、文档。结果协调开销爆炸光是把一个决策从规划传到实现中间经过架构这一层就变形了。现在我基本收敛到三到四个角色而且角色是按产出物定义的不是按职能定义的。角色核心产出物上下文里应该有什么上下文里不该有什么调研 Agent事实清单、接口约定原始文档、代码、外部资料实现细节、个人偏好实现 Agent可运行的代码/diff事实清单、接口约定、验收标准调研过程的纠结、被否决的方案审查 Agent问题列表、修改建议最终 diff、验收标准实现者的解释、实现过程协调 Agent可选任务分派、状态跟踪各角色的产出摘要任何具体实现细节这张表是我踩了无数坑之后总结的核心原则就一条每个角色的上下文里只放它做决策需要的东西多一点都不放。上下文越干净Agent 的表现越稳定。2.2 handoff交接才是多 Agent 的命门handoff 这个词直译是交接我觉得特别贴切。多 Agent 协作里90% 的翻车都发生在交接环节。交接做得好整个流程丝滑交接做得烂后面全在擦屁股。我现在的 handoff 遵循三个原则第一交接必须有明确的交付物格式。不能是我把我的想法告诉下一个 Agent而必须是结构化的东西。比如调研 Agent 交给实现 Agent 的一定是一份固定格式的清单涉及哪些文件、每个文件的职责、需要暴露的接口签名、边界条件、已知的坑。格式固定了实现 Agent 就不用去猜。第二交接要带为什么但只带结论级的为什么。比如这里用队列而不是直接调用是因为上游是突发流量——这种结论级的背景要带因为它影响实现决策。但我一开始想用 A 方案后来觉得 B 更好纠结了半小时这种过程坚决不带纯属噪音。第三交接要显式声明未决问题。调研 Agent 没搞清楚的地方必须明确标出来交给下一个 Agent而不是假装自己都懂了。我吃过这个亏调研 Agent 对一个边界条件含糊其辞实现 Agent 默认它懂了结果实现出来完全跑偏。2.3 共享上下文用文件而不是用记忆多 Agent 之间共享信息我强烈建议用文件不要靠对话历史传递。原因很简单对话历史是不可靠的会被压缩、会被截断、会随着轮次增加而失真。而文件是持久的、可版本化的、可被任何 Agent 随时读取的。我现在的做法是在项目根目录放一个AGENTS.md作为所有 Agent 的公共黑板。这个文件里放什么、不放什么我后面会专门讲。除了AGENTS.md每个角色还会有自己的产出文件比如research.md、plan.md、review.md这些文件就是 handoff 的载体。Agent 之间不直接说话而是通过读写这些文件来协作。这个设计有个额外的好处整个协作过程是可追溯的。出了问题我翻一遍这些文件就知道是哪一步交接出的错而不是去翻几千行对话记录。3. AGENTS.md 到底该写什么不该写什么3.1 AGENTS.md 的定位项目的协作宪法AGENTS.md这个东西现在越来越常见但很多人把它写成了项目说明书什么都往里塞最后变成一个没人看的巨型文档。我的理解是AGENTS.md是给 Agent 看的协作宪法不是给人看的项目文档。它要回答的是在这个项目里Agent 应该怎么干活而不是这个项目是什么。项目是什么README 里写。Agent 怎么干活AGENTS.md里写。这两个受众不同别混。3.2 必须写进去的四类内容我现在的AGENTS.md基本就四块每块都很克制第一块项目的基本约束。技术栈、目录结构约定、命名规范、必须遵守的硬性规则。比如所有对外接口必须放在api/目录下禁止在业务代码里直接读环境变量统一走config模块。这些是 Agent 做任何决策的前提。第二块角色的定义和边界。这个项目里有哪些角色、每个角色负责什么、产出物是什么格式、什么情况下该 handoff 给谁。这块是协作的核心必须写清楚。第三块handoff 的格式约定。每种交接的交付物长什么样字段有哪些。这块越具体越好最好直接给模板。第四块禁止事项。这个特别重要。比如禁止修改migrations/下的历史文件禁止在没有测试的情况下改核心逻辑禁止自作主张升级依赖版本。Agent 很听话你写了的它基本会遵守你没写的它就可能乱来。3.3 千万别写进去的三类内容第一别写详细的实现步骤。步骤是 Agent 自己该想的你写死了它反而不会变通。你只需要告诉它目标和约束。第二别写会频繁变化的信息。比如当前正在做的任务是什么这种信息应该放在单独的任务文件里而不是AGENTS.md。AGENTS.md应该是相对稳定的。第三别写和协作无关的项目背景。什么本项目始于某年某月旨在解决某某问题这些对 Agent 干活没有任何帮助纯占上下文。提示AGENTS.md的长度我一般控制在 200 行以内。超过这个长度Agent 读取的时候注意力会被稀释重点反而不突出了。宁可拆成多个文件也不要堆成一个巨无霸。3.4 一个我实际在用的 AGENTS.md 骨架下面这个骨架我脱敏之后放出来你可以直接拿去改# 项目协作约定 ## 技术栈与硬性约束 - 语言/框架... - 目录约定... - 命名规范... ## 角色定义 ### 调研 Agent - 职责... - 产出research.md格式见下 - 交接对象实现 Agent ### 实现 Agent - 职责... - 产出代码 diff impl-notes.md - 交接对象审查 Agent ### 审查 Agent - 职责... - 产出review.md - 交接对象实现 Agent如需返工 ## Handoff 格式 ### research.md 模板 - 涉及文件 - 接口签名 - 边界条件 - 未决问题 ## 禁止事项 - ...这个骨架的关键在于每个角色都能从里面找到我该干什么、我该产出什么、我该交给谁不需要额外的解释。4. 一个能直接用的协作 Skill 长什么样4.1 Skill 的本质把协作流程固化成可复用的指令Skill 这个东西说白了就是把一套怎么做某件事的经验写成 Agent 能直接执行的指令集。它和AGENTS.md的区别在于AGENTS.md是项目级的、相对静态的约定Skill 是任务级的、可复用的流程。一个项目可以有很多个 Skill每个 Skill 负责一类任务。我沉淀下来的这个协作 Skill核心就是把我前面讲的那套角色划分 handoff 共享上下文固化下来让 Agent 一看到这个 Skill 就知道该怎么组织协作。4.2 Skill 的结构拆解我的协作 Skill 大致分四段第一段触发条件。什么情况下该用这个 Skill。我写的是当任务满足以下任一条件时启用涉及三个以上文件、需要调研外部资料、需要多方案对比、任务预计超过单次上下文能承载的规模。第二段角色编排。定义这次协作要用哪些角色、顺序是什么、每个角色的输入输出。这一段基本就是把AGENTS.md里的角色定义具体化到当前任务。第三段handoff 协议。每次交接的交付物格式、必须包含的字段、未决问题怎么标记。这一段是 Skill 的核心价值所在。第四段终止条件与回退。什么情况下算完成、什么情况下要回退到上一个角色、什么情况下要停下来问我。这一段很多人会忽略但没有它Agent 很容易陷入无限循环或者自作主张。4.3 关键设计让 handoff 可验证我在 Skill 里加了一个我觉得特别有用的设计每次 handoff 都要做一次自检。具体来说交出方在写交付物的时候必须对照一个 checklist 自查比如接口签名是否完整边界条件是否覆盖未决问题是否标注。这个 checklist 是写在 Skill 里的Agent 每次交接都会跑一遍。这个设计的价值在于它把交接质量从一个模糊的东西变成了可检查的东西。以前我只能事后发现交接出了问题现在 Agent 在交接前自己就会拦一道。实测下来因为交接不清导致的返工至少少了一半。4.4 Skill 里我踩过的坑坑一Skill 写得太抽象。我第一版 Skill 写的是调研 Agent 应该充分调研这种话等于没说。Agent 需要的是调研 Agent 必须产出涉及文件清单、接口签名、边界条件三项缺一不可这种可执行的标准。坑二角色之间职责重叠。我一开始让调研 Agent 和实现 Agent 都能提出优化建议结果两边都在提互相打架。后来我把提优化建议这个职责单独给了审查 Agent调研和实现都不许提世界清净了。坑三没有回退机制。早期版本里实现 Agent 如果发现调研 Agent 给的信息不够它只能硬着头皮猜。后来我在 Skill 里加了实现 Agent 有权打回给调研 Agent并明确指出缺什么这个问题才解决。5. 实战一次完整的多 Agent 协作是怎么跑起来的5.1 任务背景我拿一个真实的任务来演示给一个已有的服务加一个批量导出功能。这个功能涉及新增接口、改数据层、加异步任务、写测试大概要动六七个文件。单 Agent 做也能做但容易顾此失彼所以我用多 Agent 跑。5.2 第一步调研 Agent 出场调研 Agent 的任务是搞清楚现状是什么。它要读现有的接口定义、数据层结构、异步任务的现有实现方式然后产出一份research.md。这份research.md里必须包含现有接口的签名和调用方、数据层有哪些可复用的方法、异步任务框架的用法示例、以及它没搞清楚的问题。注意它不负责提方案只负责把事实摆清楚。这一步我踩过的坑是调研 Agent 很容易越界去提方案。所以我在 Skill 里明确写了调研 Agent 禁止提出实现方案只陈述事实。这条约束一加它的产出干净多了。5.3 第二步handoff 到实现 Agent调研 Agent 写完research.md之后触发 handoff。实现 Agent 读这份文件然后开始干活。它读到的上下文里只有事实清单和接口约定没有调研过程的纠结也没有被否决的方案。实现 Agent 干活的时候我要求它同步写一份impl-notes.md记录它做了哪些决策、为什么这么决策、哪些地方它不确定。这份文件是给审查 Agent 看的也是给我看的。这里有个细节实现 Agent 不允许修改research.md。如果它发现调研有误只能在impl-notes.md里标注然后打回。这个约束保证了每个文件只有一个作者避免了并发修改的混乱。5.4 第三步handoff 到审查 Agent实现 Agent 完成后审查 Agent 出场。它读的是最终 diff 和impl-notes.md但不读实现过程的对话历史。这样它才能以一个局外人的视角去审。审查 Agent 产出review.md里面是问题列表每条问题要标注严重程度和修改建议。如果问题严重它会把任务打回给实现 Agent如果不严重它就直接标记为可合并。我实测下来审查 Agent 抓出的问题里有相当一部分是实现 Agent 自己也知道但偷懒没做的。这就是分离角色的价值——自己审自己永远会放水。5.5 第四步我来做最终决策整个流程跑完我拿到的是三份文件research.md、impl-notes.md、review.md。我花十分钟翻一遍就能判断这次改动靠不靠谱。比起翻几千行对话记录这个效率高太多了。如果审查 Agent 和实现 Agent 意见不一致最终由我拍板。这也是为什么我坚持保留协调者这个角色——Agent 可以协作但最终决策权必须在我手里。6. 那些让我返工好几次的坑6.1 上下文污染最隐蔽的杀手上下文污染是多 Agent 协作里最隐蔽的问题。它不会让流程直接崩掉但会让 Agent 的表现慢慢变差。典型表现是Agent 开始引用一些它不该知道的信息或者对某些细节过度纠结。我的应对方式是严格隔离每个角色的上下文。具体做法是每个角色只读它该读的文件不读其他角色的对话历史。如果确实需要跨角色信息就通过文件传递而不是通过对话。6.2 任务边界模糊切分切错了我踩过最惨的一次是把一个需要频繁来回讨论的任务硬切成了两个 Agent。结果两个 Agent 来回 handoff 了七八次每次都要重新建立上下文效率比单 Agent 还低。后来我总结出一个判断标准如果两个子任务之间的 handoff 次数预计超过三次那就别拆了合并成一个 Agent 干。handoff 是有成本的成本超过收益就不值得。6.3 无限循环Agent 互相打回审查 Agent 打回给实现 Agent实现 Agent 改完又被打回来回几次之后两个 Agent 开始在一些细枝末节上较劲。这个坑我踩过解决方案是在 Skill 里加最大迭代次数同一个任务handoff 往返超过三次就强制停下来问我。6.4 状态丢失Agent 忘了自己在干嘛长流程里Agent 很容易忘记当前处于哪个阶段。我的应对是在每个产出文件的开头加一个状态头标明当前阶段、上一个阶段是什么、下一个阶段是什么。Agent 每次读文件都会看到这个状态头相当于一个持续的状态提醒。7. 关于多 Agent 协作我现在的几个真实判断7.1 多 Agent 的收益是质量不是速度很多人上多 Agent 是冲着快去的但我实测下来多 Agent 在速度上的收益其实有限因为 handoff 本身要花时间。它真正的收益是质量因为每个环节都有独立的角色把关最终产出的东西更靠谱。如果你追求的是速度单 Agent 往往更快如果你追求的是质量多 Agent 才值得。7.2 Skill 的价值在于可复现我一开始觉得 Skill 就是个提示词模板后来才意识到它的真正价值是可复现。没有 Skill 的时候我每次组织多 Agent 协作都要重新想一遍角色怎么分、handoff 怎么设计每次都不一样质量也不稳定。有了 Skill 之后这套流程被固化下来每次跑出来的质量都差不多。这种稳定性才是 Skill 最值钱的地方。7.3 别追求全自动我见过一些人追求全自动多 Agent 协作就是给一个目标Agent 自己拆解、自己协作、自己交付人完全不介入。我试过结论是在需要判断力的任务上全自动目前还不靠谱。Agent 会在一些关键决策上做出你完全无法接受的选择而且它自己觉得很合理。我现在的方式是半自动Agent 负责执行和初步判断关键决策点必须停下来问我。这样既享受了多 Agent 的效率又保住了最终的控制权。7.4 协作的复杂度要和任务复杂度匹配最后一条也是我觉得最重要的一条别为了多 Agent 而多 Agent。一个简单的任务单 Agent 五分钟搞定你非要拆成三个角色跑一遍流程纯属浪费时间。我现在的原则是任务复杂度到了单 Agent 明显吃力的程度才上多 Agent否则老老实实单 Agent 干。工具是拿来解决问题的不是拿来炫技的。这套协作方式我用了大半年中间还在不断微调。最近在琢磨的一件事是怎么让 handoff 的交付物格式更自动化一点比如用 schema 去校验而不是靠 Agent 自己对照 checklist。等这套跑通了我再写一篇来分享。如果你也在折腾多 Agent 协作欢迎交流尤其是你在 handoff 环节踩过的坑我特别感兴趣。
返回列表