去年年中,我把我们团队从需求到发布的研发流程,系统性地拆给一组AI智能体去协作执行。这套系统内部代号叫Agency Agents,是一套多智能体协作系统,目标很直白:重构开发团队的工作方式。项目启动时争议不小,有人觉得这就是把多个聊天机器人串在一起,有人觉得一个能写代码的AI就够用了,没必要搞一群角色互相开会。但真正跑完一轮完整任务之后,团队里反对的声音少了很多,因为结果确实不一样:需求到代码的产出链路变短了,评审意见变具体了,连测试用例的覆盖思路都比原来人工写的时候更全。
这篇文章不炒概念,我把Agency Agents从架构设计、角色编排、通信机制,到落地踩坑、性能评估的完整过程整理出来。适合正在琢磨AI辅助研发落地的架构师、技术负责人,以及所有被"多Agent编排怎么搞"这个问题卡住的人。尤其如果你已经试过单Agent写代码但发现越到后期越失控,这篇内容应该能给你一个更系统化的答案。
1. 先想清楚:为什么需要多智能体系统来重构开发团队
1.1 传统开发协作的瓶颈到底在哪
先说一个很现实的观察:大多数团队的开发瓶颈不在"写代码"本身,而在上下文传递。需求从产品经理手里出来,经过技术评审变成设计文档,再拆成任务卡分给开发,开发写完后交给测试验证,最后评审合并。这中间每一步都在丢失信息——口头确认的需求细节没写进文档、架构决策只存在于某个人的脑子里、代码评审意见只停留在PR评论里。问题越积越多,最终表现为返工、扯皮、交付延期。
单人单Agent的模式解决不了这个困境。我也试过把"从需求到实现"整个任务直接丢给一个AI,让它一口气完成需求分析加编码。前几个任务看着还行,但任务一复杂就露馅:Agent在长对话里逐渐忘记最初的约束,写着写着开始自由发挥,需求说要A模块兼容B模块,它代码里直接拿掉了一个边界处理。核心原因在于,单个Agent身兼数职会导致指令混杂、上下文窗口被各种无关信息占满,角色边界一旦模糊,输出的稳定性和可解释性都急剧下降。
多智能体系统的设计动机恰恰来源于此:既然真实团队靠分工协作解决复杂度,为什么不让AI也按照同样的方法协作?每个Agent只承担一个明确的角色,只维护和自己角色相关的上下文,通过标准化的接口进行通信。这样一来,上下文隔离了,职责清晰了,每个环节还能独立评审和回溯。本质上,它是把软件工程里那套模块化、单一职责、接口契约、评审门禁的方法论,原样搬到了Agent系统里。
1.2 多智能体系统解决的核心问题
Agency Agents要解决的核心问题可以归纳成三句话:让任务可拆分、让过程可评审、让结果可追溯。
任务可拆分是指,一个高层级的目标进来之后,系统能把它拆成一棵任务树,树的每一个叶子节点都有明确的输入、输出和验收标准,而不是让一个Agent面对一个模糊的大任务硬干。过程可评审是指,每个Agent的产出都要经过另一个Agent(通常是评审Agent)的检查,评审不通过就退回重做,相当于在AI协作链路上内置了质量门禁。结果可追溯是指,所有Agent之间的消息、决策依据、状态流转都落在持久化存储里,任何一个环节出了问题都能回放整个协作过程,定位到具体是哪一步产生了偏差。
这种设计还有一个隐藏价值:它把"AI写代码"这件事从黑盒变成了白盒。团队负责人不必再怀疑"这个代码到底是不是AI乱写的",因为评审记录、测试结果、修改理由全都有迹可循。对于管理者和客户来说,这种透明性往往比AI本身的能力更重要。
1.3 系统定位与适用边界
Agency Agents定位在中小型软件团队的内部研发流程自动化,覆盖从需求解析、架构设计、编码实现、测试生成到代码评审的完整链路。它不追求完全无人化,而是把人类从重复性工作中解放出来,让人去盯关键决策和最终质量。
我必须强调适用边界。第一,它不适合完全没有人工介入的全自动场景,尤其是涉及外部客户承诺、合规要求、线上数据操作的任务,必须保留人类审批环节。第二,它不擅长处理那些需求模糊到连人都说不清楚的任务,输入的质量直接决定了协作系统的上限。第三,它不适合实时性要求极高的场景,多Agent之间多轮协商的耗时远高于单次模型调用。
2. 架构拆解:Agency Agents的总体设计与核心组件
2.1 分层架构:从接入到执行的四个层次
Agency Agents整体分四层:接入层、编排层、执行层、工具层。每层只依赖下一层提供的接口,内部实现互相隔离,这样后续替换任何一层都不至于牵动全局。
接入层对外提供两类入口:一类是RESTful API,方便集成到现有的研发管理平台里;另一类是交互式控制台,团队成员可以在界面上提交任务、查看任务树、观察每个Agent的状态和产出。控制台看起来像一个简化版的项目管理看板,但每一张卡片背后都对应一个Agent的完整执行链路。
编排层是整个系统的大脑,由任务拆解器、调度器、上下文管理器三个组件构成。任务拆解器负责把输入的自然语言目标解析成结构化的任务树;调度器根据任务依赖关系和Agent当前负载情况决定执行顺序;上下文管理器负责维护每个Agent在执行过程中的状态快照和跨Agent传递的摘要信息。
执行层就是我们常说的角色Agent集群,目前内置了需求解析Agent、架构设计Agent、编码Agent、测试Agent、评审Agent五类角色。每个Agent都是一个独立部署的服务进程,启动时将自己的角色能力、可用工具、输入输出Schema注册到系统里,运行时被动接收编排层派发的任务,执行完毕后把结果写回消息总线。
工具层是Agent能力的延伸,通过统一的工具适配器接入了Git仓库、CI管道、文档库、数据库查询接口。Agent本身不直接操作外部系统,而是通过调用工具适配器暴露的标准化方法来完成文件读写、命令执行、数据查询等动作。这种设计既保证了灵活性,又方便在工具层做权限控制和审计。
2.2 核心组件:注册中心、编排器与消息总线
Agent注册中心是系统里不起眼但极其关键的组件。每个Agent进程启动时,会向注册中心提交一份元信息:角色名、可处理的输入Schema、可调用的工具列表、输出格式约束、以及一个描述自身职责的文本说明。其他组件需要调用某个Agent时,先向注册中心查询匹配的Agent实例,而不是硬编码地址。
任务编排器维护着一张有向无环图,节点是任务卡片,边是依赖关系。用户提交一个大目标后,编排器先交给需求解析Agent做意图拆分,生成任务树,然后经过合法性检查(比如是否存在循环依赖、是否有缺失的必要条件)再进入调度队列。调度器按拓扑序遍历任务树,遇到无依赖的任务就派发给对应角色的空闲Agent,遇到依赖未完成的任务则挂起等待。这里有一个很重要的原则:调度器只负责派发,不负责判断任务结果好坏——结果是否符合要求由评审Agent判断,如果评审不通过,任务会被打回并重新进入队列。
消息总线采用异步事件驱动模型,所有Agent之间的通信都通过消息队列解耦。发送方不需要关心接收方是否在线,接收方通过订阅自己感兴趣的事件类型来获取消息。这套机制带来的直接好处是Agent可以独立扩缩容,某个Agent升级或重启不会阻塞其他Agent的工作。坏处则是消息顺序需要额外关注,在实现中我为每个任务加了一个全局递增的sequence字段,消费方按sequence排序后再处理,避免并发场景下消息乱序导致的状态错乱。
2.3 通信协议与协作机制
Agent之间不能直接互相对话,所有信息交换都必须封装成标准消息结构。Agency Agents的消息定义为五个核心字段:message_id用于全局唯一标识,sender和receiver标明消息来源和去向,task_id关联到具体任务,payload承载实际内容,schema_version标明消息结构的版本号。payload内部再细分为content_type、data、meta三个子段,其中meta专门用来放模型调用参数、置信度、token消耗等元信息。
协作流程的状态机分为六个状态:created(任务刚创建)、assigned(已派发给Agent)、in_progress(执行中)、review(等待评审)、approved(评审通过)、rejected(评审不通过需返工)。任何时刻一个任务只可能处于其中一个状态,状态变更事件会广播到消息总线,供监控面板和调度器消费。
在上下文传递上,我放弃了大一统的"全局黑板"思路,改用"轻量共享+局部私有"的组合策略。每个任务之间的跨Agent传递内容以结构化摘要和关键片段引用为主,比如编码Agent需要接收的不是需求解析Agent的全部历史,而是一份包含需求背景、约束条件、接口要求、验收标准的摘要卡片,加上可能用到的原始文档片段链接。这样既保证了必要信息的完整,又避免了大段无关上下文挤占模型窗口。
3. 关键环节实现:任务拆分与Agent角色编排
3.1 角色设计:每个Agent到底在干什么
Agency Agents内置了五个角色,每个角色的职责边界在开发前就做了严格划分,运行中不允许越界。下面这个表是各角色的核心定义。
| 角色 | 核心职责 | 关键能力 | 输出产物 |
|---|---|---|---|
| 需求解析Agent | 将模糊的自然语言目标拆解为结构化任务树 | 意图识别、边界澄清、依赖分析 | 需求卡片集、验收标准清单 |
| 架构设计Agent | 基于需求卡片产出模块级设计 | 系统建模、模块拆分、接口定义 | 模块设计文档、接口Schema |
| 编码Agent | 按设计文档实现具体模块代码 | 编码、重构、注释生成 | 源代码文件、变更说明 |
| 测试Agent | 生成单元测试与集成测试用例 | 用例生成、边界分析、回归补全 | 测试代码、覆盖率报告 |
| 评审Agent | 对所有产出进行质量检查和合规校验 | 代码审查、规范校验、缺陷定位 | 评审意见、整改要求 |
每个角色的Prompt模板在系统启动时从配置中心加载,模板里固定写清了该角色的职责描述、输入Schema示例、输出格式要求、以及几条不可违背的行为约束。比如编码Agent的行为约束里明确写着:如果设计文档中的接口定义与自己实现冲突,必须先发起评审咨询,不得擅自修改接口。
角色之间通过产物传递形成协作闭环:需求解析Agent产出需求卡片给架构设计Agent,架构设计Agent产出设计文档给编码Agent,编码Agent产出代码给测试Agent和评审Agent,评审Agent的意见会同时反馈给编码Agent和测试Agent。整条链路上,每一个Agent的目光只聚焦在自己的输入和输出上,不关心上下游之外的事情。这个看似简单的隔离设计,是系统后期稳定运行的最大功臣。
3.2 任务拆解流程:粒度控制是成败关键
任务拆解不是一个一次性的动作。用户提交高层目标后,需求解析Agent会先产出第一版任务树,然后架构设计Agent会基于这个任务树做第二轮细化,把每个任务卡片补充到可执行的粒度。两轮拆解的目的不同:第一轮保证不遗漏需求点,第二轮保证每个叶子任务可以被Agent独立执行。
任务粒度的控制规则,我在实践中总结成一句话:一个任务卡片只对应一个模块的一个改动点,编写时长建议控制在单次模型调用可完成的范围。粒度太粗,Agent容易在长输出中迷失方向;粒度太细,任务之间的交接成本会淹没收益。实际操作中,如果发现某个任务卡片需要编码Agent输出超过大约600行代码,就要触发自动拆分逻辑,把它按功能点拆成两个子任务。
每张任务卡片必须包含六个字段:任务编号、任务背景、验收标准、涉及模块路径、依赖任务列表、输出格式要求。验收标准不是泛泛的一句"功能正常",而是具体的可检查项,比如"新增接口需包含鉴权校验,非法token返回401",这样评审Agent才有明确的判断依据。我见过很多失败的Agent落地案例,最后复盘下来,问题根源都是任务卡片写得太稀,Agent在模糊指令下自由发挥,产出自然不可控。
3.3 上下文管理与状态同步
多智能体系统最容易被低估的技术难点是上下文管理。每个Agent的运行需要两类信息:一类是静态的Prompt和角色定义,另一类是动态的任务输入、相关历史摘要、以及中间产物引用。如果每次执行都把全部历史塞进去,模型窗口再大也不够用,而且无关信息越多,输出质量越差。
我采用的策略是三层摘要机制。第一层是任务级摘要,由需求解析Agent生成,包含任务目标、关键约束、验收标准,这是所有下游Agent都能看到的基础信息。第二层是角色级摘要,每个Agent在完成一次任务后,会把产出总结成一段结构化的摘要存入上下文管理器,摘要里包含做了什么决策、产出了哪些文件、遗留了哪些风险。第三层是对话级摘要,用于多轮返工场景,只记录最近几轮的关键分歧点和修改意见,避免返工过程中Agent把之前的错误结论又搬出来。
状态同步方面,上下文管理器内部使用了一个轻量级KV存储,键是task_id加agent_role,值是该角色对该任务的全部状态数据。每当调度器派发任务、Agent上报进度、评审节点产生意见时,KV存储都会更新并发布事件。这样做的好处是任务执行到任何阶段都可以随时被打断并恢复,比如某个Agent的服务重启了,重启后可以从KV存储拉取之前的执行状态继续工作,而不是推倒重来。
4. 实操落地:从原型到生产环境的踩坑记录
4.1 最小可行闭环怎么搭
从零开始搭一套Agency Agents,不建议一次上全所有角色。我一开始只搭了三个角色:需求解析Agent、编码Agent、评审Agent,跑通了一个简化链路,确认流程顺畅后才逐步加入架构设计和测试Agent。
技术选型上,编排服务用Python的FastAPI编写,因为Agent的逻辑大量涉及字符串处理、JSON解析和模型调用,Python生态更顺手。Agent进程采用独立服务部署,每个角色一个容器实例,通过内部消息队列通信。模型接入层做了一层统一封装,底层可以切换不同的商用大模型API或开源部署模型,上层Agent无感知。这套封装带来的好处在后来模型升级时体现得很明显,替换模型只需要改配置,Agent代码零改动。
第一个Demo任务我选了一个有明确边界的模块:生成用户登录模块并集成JWT鉴权。这类任务领域清晰、验收标准容易定义,非常适合做链路验证。启动任务后,首先看到的是需求解析Agent在几秒内产出一张包含登录接口、注册接口、令牌刷新、退出登录四个子任务的任务树,随后编码Agent开始按任务树逐个实现,每个文件生成后评审Agent马上对刚才的代码做检查并给出意见。整个流程跑完大约用了十几分钟,中间有一次编码Agent被评审驳回后自动返工,这让我第一次直观感受到"AI团队"的协作节奏。
4.2 关键配置与调优参数
生产环境落地时,参数配置的坑比想象中多。下面这几个参数是经过多轮压测后总结的经验值,可以作为参考起点,但不建议照搬,因为具体数值依赖模型能力和任务类型。
| 配置项 | 推荐值 | 调优说明 |
|---|---|---|
| 架构/评审Agent模型 | 大参数商用模型 | 这类任务需要强推理能力,模型参数量直接决定评审意见的质量 |
| 编码/测试Agent模型 | 中等参数模型 | 在质量与成本之间取平衡,编码任务的输出长度比推理深度更重要 |
| 摘要/格式化任务模型 | 轻量模型 | 这类任务简单但调用频繁,可以用小模型显著降低token成本 |
| 模型温度 | 评审0.2,编码0.4,创意类0.7 | 温度越低输出越确定,评审必须低温度保证判断的一致性 |
| API调用超时 | 60秒 | 模型服务的响应时间波动大,超时设置过短容易造成任务无意义失败 |
| 重试机制 | 3次,指数退避 | 瞬时错误重试有效,持续错误重试再多也是浪费成本 |
| 单Agent并发上限 | 3个并发任务 | 超过后容易触发模型服务限流,且并发太多会加剧消息乱序风险 |
其中温度参数是第一个要校准的变量。一开始我所有Agent都用默认温度,结果评审Agent给出的意见五花八门,同一个问题第一次说改模块A,第二次说改模块B。把评审Agent的温度压到0.2之后,意见的一致性立刻改善,这个调整对系统稳定性的贡献比任何代码修改都大。
上下文窗口预算也是一个容易忽视的细节。我要求所有Agent的单次调用输入长度控制在模型窗口的三分之一以内,预留足够的输出空间。超出预算时,上下文管理器会自动对输入做截断或摘要降级。这个策略有效避免了"输入太长导致模型截断、截断导致关键信息丢失、最终产出不符合要求"的恶性循环。
4.3 常见问题与排查技巧实录
第一类高发问题是任务死锁。多Agent协作中,AgentA等待AgentB的评审结果,AgentB又在等待AgentA补充信息,两边互相等待谁也不先动。排查后发现根因是评审驳回消息缺少明确的"回复截止期限"。解决办法是在评审意见中强制附加一个字段expected_fix_time,调度器收到后设置定时检查,超时未收到回复就自动升级到人工处理。这个机制上线后,死锁场景基本绝迹。
第二类问题是上下文污染。有一次编码Agent突然开始输出需求分析的内容,排查发现是消息总线在重试机制下重复投递了需求解析Agent的历史消息,导致编码Agent把旧消息当成了当前任务。修复方案是在消息结构里增加任务轮次编号,Agent只处理编号匹配自己当前轮次的消息,其他一律忽略。
第三类问题是模型幻觉和错误引用。编码Agent在生成代码时偶尔会引用不存在的依赖库版本,评审Agent如果不细查就会漏过去。我在编码Agent的行为约束里加了一条硬性要求:代码中涉及的外部依赖、文件路径、函数签名必须从提供的上下文或工具查询结果中复制,禁止凭记忆生成。同时评审Agent的Prompt里增加了一轮"依赖合法性检查"步骤,专门核对pom或requirements文件。
还有一个值得说的排查技巧:消息回放。系统里每个任务的所有消息和状态变更都按时间顺序记录到trace日志中,遇到疑难问题时,我会把trace导出并按sequence重放一遍,观察Agent之间的交互过程。大多数让人摸不着头脑的现象,在回放时会变得非常清晰——比如某个Agent为什么执意不改接口,原来是它收到的上下文摘要里残留了另一版本的需求描述。
5. 实测效果评估与不可回避的问题
5.1 传统人工流程与Agent协作的对比
系统稳定运行三个月后,我做了一次内部对比测试。选取了六个规模相近的中型功能模块,三个走传统人工流程,三个走Agency Agents流程,开发人员的技术水平基本相当。对比维度包括交付周期、代码评审问题密度、单元测试覆盖率、需求变更响应速度。
交付周期方面,Agent流程平均比人工流程缩短了约40%,主要耗时差异体现在编码和初步测试环节。人工开发需要写代码、自测、再等评审,而Agent链路里编码和测试生成几乎是连续完成的。代码评审问题密度上,Agent流程初期的评审意见数量明显多于人工流程,但大部分是风格类问题而不是逻辑错误,经过几轮Prompt优化后,问题密度降到了和人工接近的水平。单元测试覆盖率上,Agent生成的用例覆盖边界场景的能力更强,尤其在异常分支和参数校验方面,覆盖率平均高出15个百分点。
需求变更响应速度是差异最大的一项。人工流程下,需求变更意味着要通知开发、修改设计、重新排期,往往以天为单位计算;Agent流程下,变更需求输入后,系统会自动识别受影响的任务卡片,只重新执行相关子任务,通常几十分钟内就能出一版新代码。当然代价也不是没有,多轮模型调用让token消耗成倍增长,账单数字需要有人买单。
5.2 风险边界与成本控制
最需要冷静面对的现实是:多智能体系统不是万能的,它用成本换来了自动化程度,也引入了新的风险。
Token成本是最直接的问题。一个完整任务的多次Agent调用,token消耗可能是单Agent方案的3到5倍。控制成本的有效手段有三个:尽量用轻量模型处理摘要和格式化任务;严格控制返工轮次上限,评审驳回超过三次自动转人工处理;对模型输出长度设置合理上限,防止Agent在生成代码时无限发挥。
安全性方面,Agent工具调用权限必须收敛。我的原则是:Agent默认只能读取代码仓库和文档,写操作必须经过审批Agent确认;涉及数据库变更、生产环境部署等高危操作,一律要求人工二次确认。系统中每一个工具调用都记录了操作者Agent、目标资源、操作类型和时间,这样做不仅是安全要求,也让事后追溯有了依据。
还有一个容易被忽略的边界:多Agent系统会把知识盲区放大。如果团队本身对某个业务域的理解就不够清晰,Agent协作生成的设计文档和代码只会把这种模糊性包装成看似严谨的形式,实际上漏洞还埋在深层。所以我的建议是,多Agent系统最适合用在团队已经有明确方法论沉淀的领域,而不是用来探索全新的未知业务。
5.3 值得尝试的后续演进方向
运行几个月后,我发现有三个可优化的方向值得继续投入。第一个方向是评审经验的沉淀与复用。目前评审Agent每次都是基于Prompt模板做判断,如果能把过去的评审意见和对应的代码修改整理成历史案例库,在评审时作为参考示例注入Prompt,评审质量会随着系统的使用次数逐渐提升,相当于系统能自己"记住教训"。
第二个方向是跨项目复用任务模板。现在每个项目从零开始拆任务,拆解结果高度依赖需求解析Agent当时的发挥。如果能把历史项目中成功的任务树结构保存为模板,新项目输入时先做模板匹配再微调,不仅拆解速度会更快,任务质量也会更稳定。
第三个方向是引入人类反馈闭环。目前人类只是在评审链路的末端做终审,如果能把"人类终审时否决了哪些AI决策"记录下来,定期回灌到评审Agent和需求解析Agent的Prompt中做校准,系统就能持续贴近团队的真实偏好。
这几点我目前正在逐个验证,等有更完整的数据后再单独写一篇展开聊。
最后说一点个人的真实体会。做Agency Agents这套系统,技术难度最大的从来不是让Agent调用模型、生成代码这些单点能力,而是想清楚每个Agent的边界在哪里、任务切到什么粒度最合适、消息里哪些信息必须传哪些可以丢。这些看似啰嗦的工程约束,恰恰是系统从实验室Demo走向稳定生产力的关键。如果你也想在自己的团队里尝试类似方案,我的建议很直接:先用三个Agent跑通最小闭环,把任务卡片格式、评审规则、上下文摘要这三件事做扎实,再考虑扩展更多角色。先把协作的地基打好,多智能体才能真的替你干活,而不是替你添乱。