
几个月前我还在用单个AI助手当“临时工”让它写摘要、补文档、刷单元测试还能顶一顶可真要它完整接手一个小迭代几乎是不可能的上下文一长就像金鱼记忆角色一混就飘代码写着写着开始“脑补”不存在的接口。后来我换了个思路——与其跟一个“全栈实习生”较劲不如自己搭一支由多个专业智能体组成的虚拟开发团队。这就是“Agency Agents”多智能体协作系统的起点一套把需求拆解、编码、评审、测试、部署拆给不同角色智能体并行协作的架构。这篇文章会把我整套系统怎么设计、怎么跑通、踩了哪些坑完整讲一遍适合正在折腾多智能体协作系统、或者打算用智能体重构团队工作流的开发者参考。1. 从“单智能体助手”到“多智能体团队”重构前想明白的三件事1.1 单智能体的瓶颈不是能力不够而是角色错位很多人第一次用AI编码助手时都会兴奋但用着用着就会撞上一堵隐形的墙。比如我让同一个智能体先写需求文档再写核心代码再自查Bug再补测试用例结果往往是文档写得像代码注释代码里混着测试代码最后自检环节它还会给有明显缺陷的代码打出“基本通过”的评价。问题不是模型不够聪明而是同一个上下文里塞进了太多互相冲突的角色要求。写代码需要关注具体实现细节写测试需要关注异常路径做评审需要怀疑一切。这些思维方式放在一次对话里等于让一个身兼数职的实习生同时干五份活而且每份活的标准还互相打架。另一个硬伤是串行依赖。单智能体处理任务时所有步骤都必须按顺序来先写代码才能测试先测试才能修Bug。可任何做过工程的人都知道真实的开发流程里写A模块和写B模块可以并行写代码和设计测试用例也可以并行单智能体根本没法做这件事。1.2 用“组织”的视角重新看待智能体一切都通了后来我试着转换视角把智能体当成“员工”而不是“工具”来用。我开始给它们设计岗位说明书明确每个智能体的职责边界、输入输出格式、工作标准和协作流程。我用的类比是“组建一支外包团队”需求来了先由一个人拆任务把需求翻译成开发能执行的规格说明然后开发的人只管按规格实现写完交给评审的人评审的人只负责挑毛病挑出来的问题再打回开发修改测试的人等代码稳定后再介入。每个岗位的信息传递都通过结构化的文档或消息而不是靠同一个大脑里“角色切换”。按照这个思路单个智能体的能力缺陷不再是瓶颈。规划智能体不需要会写代码它只需要把需求拆得足够清晰开发智能体不需要做架构决策它只需要理解规格并实现评审智能体不需要写修复方案它只需要找出问题并给出依据。专业分工带来的好处是每个智能体的提示词Prompt可以高度聚焦模型不需要在多个身份之间来回切换输出质量反而稳定了许多。1.3 重构的目标和边界先给虚拟团队设定工作范围我给自己定的重构目标很朴素让系统自动完成“小迭代”级别的开发任务。所谓小迭代就是需求明确、涉及模块不超过三到五个、不需要跨系统联调的任务比如给某个内部工具加一个导出功能或者修一批有明确复现路径的Bug。边界条件是三条硬规矩第一虚拟团队产出的代码只能进入内部项目的预发布分支不能直接碰生产环境的关键路径。第二所有智能体的输出都必须经过人审最终的合并动作必须由人类触发。第三单次任务的上下文预算和Token预算要封顶防止失控调用过多资源。先立好这三条边界后面所有架构设计都会围绕着“怎么让智能体在受限环境下安全协作”来展开而不是一味追求“全自动”。2. “Agency Agents”系统的总体架构五个核心组件和一条消息链路2.1 架构总览每个组件都在解决一个具体问题整个系统由五个核心组件组成每个组件都不是凑出来的而是被实际暴露的问题逼出来的。第一个是总控调度器Orchestrator它的职责是接收需求、生成总体计划、启动子任务、收集结果、判断是否继续推进。简单说它是虚拟团队的“项目经理”自己不写代码只做派单和验收。第二个是角色智能体池Agent Pool包含规划智能体Planner、开发智能体Coder、评审智能体Reviewer、测试智能体Tester和运维智能体Ops。每个角色对应一套独立的提示词、工具权限和模型配置。第三个是消息总线Message Bus负责智能体之间的异步通信。任务状态变更、评审意见、测试结果都通过它广播而不是让智能体之间直接对话这样能避免形成难以追踪的“人传人”链路。第四个是共享工作区Workspace一个真实的文件系统目录。代码文件、测试报告、需求文档都放在这里智能体之间通过读写文件来交换“工件”而不是在对话里传输大段代码。第五个是工具注册中心Tool Registry统一管理每个智能体可以调用哪些外部工具比如Git命令、文件检索、静态检查、测试执行器等。权限按角色最小化分配。# 系统级配置示例简化 orchestrator: work_mode: pipeline # 流水线模式默认执行顺序 max_iterations: 5 # 单个任务最多循环次数 require_human_approval: true agent_pool: planner: model: reasoning-class-model temperature: 0.2 tools: [file_read, task_create] coder: model: code-class-model temperature: 0.4 tools: [file_read, file_write, git_status] reviewer: model: reasoning-class-model temperature: 0.2 tools: [file_read, diff_view] tester: model: code-class-model temperature: 0.4 tools: [file_read, run_tests, file_write] ops: model: reasoning-class-model temperature: 0.3 tools: [file_read, docker_ps, deploy_dryrun]2.2 角色智能体不只是“换了个提示词”配置差别很大很多人以为多智能体就是把同一套大模型提示词复制五份改几个字而已。实际调试下来我发现角色之间的配置差异非常关键尤其是模型选择和温度参数。规划智能体和评审智能体我选的是推理能力更强的模型因为这两类任务高度依赖逻辑判断和长上下文理解。温度参数压得低尽量让输出稳定不追求灵感。开发智能体和测试智能体我选的是代码生成能力更好的模型温度可以稍微调高一点点让它们面对同一问题时有多种表达方式避免一遍遍生成雷同的代码。但也不能太高否则会出现变量名满天飞、风格不统一的问题。运维智能体的推理难度最低主要做执行类操作比如检查容器状态、执行预演部署命令。它的最大价值是“只读不动”权限被严格限制在沙箱环境内连真实生产环境都接触不到。# 开发智能体配置示例 coder: system_prompt: | 你是一名资深开发工程师只负责根据任务卡片中的技术方案编写代码。 你的输出必须符合以下规则 1. 只修改任务卡片指定范围内的文件。 2. 代码必须遵循项目根目录下的代码风格规范。 3. 完成后必须提交一份变更说明change_summary.md。 4. 如果发现技术方案存在缺陷在变更说明中标注blocked并写明理由。 max_context_tokens: 12000 allowed_paths: [/workspace/src, /workspace/tests]评审智能体的提示词则是另一个极端我要求它对一切代码保持“有罪推定”的态度。它不会主动补全代码只会指出问题、给出严重级别、引用具体行号。这样做的好处是评审和修复的职责彻底分离评审智能体不会因为“顺手改一下”就把自己的判断污染了。2.3 一条任务的完整流转链路跟踪下去就了解了系统全貌我用一个“给某跨平台系统增加CSV导出功能”的小任务来演示完整链路。需求进入总控调度器后第一步生成一张任务卡片状态为pending。接着规划智能体被唤醒读取需求文档、相关源码目录和已有接口规范输出一份技术方案内容包括要改哪些文件、导出功能的边界条件、性能考虑。任务卡片状态变成planned技术方案被写入共享工作区的plans/目录。总控调度器确认方案无异常后唤醒开发智能体。开发智能体读取技术方案和涉及到的源码文件按步骤实现CSV编码、字段映射、文件名生成和错误处理。完成后提交变更说明任务状态变成coding_done。评审智能体立即接管拉取本次变更的Diff逐行检查输出评审报告。如果报告中有阻断级问题任务卡片状态变成fix_required重新回到开发智能体手里。如果没有阻断问题测试智能体开始运行相关测试用例并把覆盖率结果和测试报告写回工作区。测试通过后运维智能体会在沙箱环境中执行一次预演部署验证功能在真实运行环境下的表现。最后总控调度器汇总方案、代码、评审记录、测试报告和预演结果生成一份完整交付包状态设置为awaiting_human_review等待我来验收。整条链路里没有任何两个智能体直接“开会讨论”所有信息都通过任务卡片、文件、消息总线来传递。这是有意设计的智能体之间的自然语言对话看似灵活实际上很容易跑题消息一长就没法追溯责任。用结构化工件传递信息每一步产生的中间产物都完整保留出了问题能直接回放是哪一步丢失了要求。3. 让多个智能体真正“协作”的关键机制共享上下文、编排协议与冲突消解3.1 三种通信模式各有使用场景别只用一种我调试过程中把通信模式整理成三种系统里其实都用了根据阶段来选择。同步请求响应适合“最快速度拿到单一结果”的场景比如开发智能体调用静态检查工具立刻得到检查结果。异步事件广播适合“通知多个角色并行干活”的场景比如开发任务完成、状态变更时评审和测试都能收到提醒谁先介入取决于编排规则。共享文件读写则是“大宗商品交易”适合传递完整代码、测试报告这种大数据量信息避免塞进消息里造成上下文膨胀。通信模式典型场景优点风险同步请求响应调用静态检查、读取单个配置实时、直接被调用方故障会阻塞主流程异步事件广播任务状态变更、结果通知解耦、支持并行事件风暴调试困难共享文件读写代码提交、评审报告、测试日志数据量大、可追溯文件冲突、路径不一致不要试图只用一种模式覆盖所有场景。把大量代码放进对话式消息里传到每个智能体的上下文中是我见过最贵也最容易出错的做法token开销直接翻几倍还容易超出上下文窗口的上限。我的经验是结构化文件优先短状态走事件实时查询才走同步调用。3.2 共享上下文怎么设计才不“串味”多智能体系统一个经典的翻车现场是上下文污染开发智能体在处理A任务时脑子里还残留着上一个小任务的历史记录结果新代码里出现了上一个需求才用到的变量名或设计风格。我的解决办法是给记忆分层。全局记忆存项目级知识比如目录结构、技术栈规范、常用依赖库版本所有智能体都可以读取但谁也没有写入权限只能由总控调度器在项目初始化时预置。任务记忆则跟着任务卡片走每个智能体在处理某个任务时只加载与该任务相关的信息包括方案文档、变更说明、评审意见。初始化新任务时旧任务的内容会被完整归档到历史存储区不会自动出现在新任务的上下文里。这个分层设计的核心原则是“按需注入”。不要让智能体自己决定读什么而是把该知道的内容由总控调度器打包好塞给它。智能体上下文中不该出现的信息越多出错的概率越大。3.3 冲突与仲裁代码冲突和决策冲突不是一回事多智能体并行一定会产生冲突这不完全是坏事冲突本身就是协作系统在正常运转的证据。代码层面的冲突处理起来最直接。两个开发智能体同时修改同一个文件时我在共享工作区上加了一层简单的文件锁粒度是整个文件。虽然粗粒度会降低一些并发度但避免了“两个人同时写同一个文件造成不可恢复的覆盖”这种灾难。文件锁之外我还强制要求每次变更都必须执行一遍增量测试确保合并后不会破坏已有功能。决策层面的冲突麻烦得多。比如评审智能体认为某个实现方式有安全风险开发智能体认为风险可以接受两边都有道理。我试过让两个智能体反复协商结果就是来回踢皮球token烧掉不少结论毫无进展。后来我换成了非常稳妥的仲裁规则安全评审和外部依赖变更评审拥有一票否决权。如果争议涉及接口设计或性能指标交由人来决策不在智能体层强制解决。争议内容必须沉淀成结构化记录方便我在复盘时了解系统为什么会卡住。3.4 编排协议把“下一步干什么”写成状态机智能体协作如果没有清晰的编排协议系统会很快陷入“看起来大家都在动实际上没人推进”的假活跃状态。我的做法是把每个任务的任务卡实现成状态机。状态定义成七种pending、planned、coding、reviewing、testing、fix_required、awaiting_approval、done。每次状态变更都会附带一个transition_reason字段记录是谁、基于什么证据把状态从哪一步推进到了哪一步。这样整条流程可以被完整审计。最关键的编排规则是状态只能按照依赖顺序推进不允许跳级。如果评审不通过代码必须回到coding状态重新修改即便测试智能体已经跃跃欲试了。这个强制顺序看起来牺牲了一点效率但在多智能体系统里规则清晰的流程比微小的并发效率重要得多。4. 真正常见问题Token成本失控、上下文污染、死锁循环4.1 每个智能体都在“独立思考”Token成本最容易翻车单智能体系统的成本是很好估算的一次对话多少Token乘以调用次数就行了。到了多智能体系统情况完全失控因为一次任务会产生大量中间过程规划智能体先读完一批文件开发智能体再读同一批文件评审智能体还要再读一遍。同一个文件被三个智能体各自读了一遍每一遍都是完整的Token计费。我踩过的坑就是第一次跑通完整流程后看账单的时候发现一次小迭代的成本大概是单智能体直接操作的六倍左右。成本主要消耗在反复读取项目文件、生成冗长的思考链、以及评审过程中多次拉取完整Diff。解决思路是对成本进行分层控制执行简单工具调用时使用轻量级模型不要一上来就调用最贵的推理模型。高成本推理模型只保留给规划、评审这类真正需要深度思考的节点。给每个智能体设置上下文窗口上限读取文件时强制使用文件摘要或局部检索而不是全量加载。对一个任务的总体Token预算进行封顶超出后自动停下来把控制权交回给人。痛点表现典型根因缓解手段账单翻好几倍多智能体重复读取同一批文件共享工作区预读并生成摘要输出质量不稳定角色职责边界模糊单独设计每个智能体的提示词任务卡死无法推进缺少超时和异常路径处理引入状态机超时机制上下文越用越乱历史记忆自动加载分层记忆、按需注入4.2 上下文污染不是技术故障而是设计缺陷上下文污染是我在调优阶段遇到最多的问题。典型症状是评审智能体在评审完一个关于异步消息队列的改动后紧接着评审一个关于错误码规范的改动结果把前者用到的框架概念带进了后者的评审标准里给出了一堆和本次变更无关的建议。根因是我把“记忆”错误地设计成了“不清理的缓存”。早期的实现里智能体会话是复用的想着这样可以减少重复上下文开销。结果就是旧任务的信息像抽屉里的陈年杂物越堆越多新任务一打开抽屉全被带了出来。解决方式前面提到过按任务隔离的上下文设计解决了这个问题。它看起来比复用会话“浪费”一点因为新任务需要重新加载一些公共信息但这部分开销是可控的。更重要的是隔离之后跨任务污染现象基本消失了智能体的判断依据变得干净输出的一致性和可信度都明显提高。4.3 三类死锁循环每一种都有对应的解法多智能体系统在工程上还会遇到三类典型的“死锁”我可是一个个踩过来的。第一类是等待死锁。两个智能体都需要对方的输出来推进自己的任务但系统没有设计好传递路径结果谁都等不到对方。后来我在所有协作节点上加上了超时和替代路径比如等待超时后直接向总控调度器报告“出口阻塞”由调度器重新分配任务或向人求助。第二类是失败重试死锁。某个步骤持续失败系统却不断重试每次重试都消耗大量Token。解决方案很简单设置重试上限上限之外必须触发人工介入流程。第三类是信心误判死锁。评审智能体对代码质量要求过于严格导致开发智能体永远修不完或者反过来评审过于宽松问题一路漏到测试阶段才暴露。我的对策是给评审智能体设置了明确的拒绝标准比如“阻断级问题的定义是导致安全风险、关键路径退化为不可用、或数据持久化逻辑有误”而不是让评审者凭直觉打分。标准一旦量化误判率立刻降下来了。5. 从Demo到稳定落地参数调优、可观测性与安全边界5.1 关键参数不是玄学每个参数背后都有代价多智能体系统的参数调节和单智能体调Prompt完全不是一回事。单智能体只需要关注输出效果多智能体系统还得同时考虑成本、延迟和整体收敛性。模型选择上我坚持“一个团队里不能全是博士生”的原则。某个开源代码模型写具体实现逻辑很利索但让它做复杂任务拆分就明显力不从心。某个推理能力更强的模型做方案设计很好但让它去执行几百次文件读写操作延迟高得让人无法接受。给角色配上合适的模型效果立竿见影。温度参数方面我把所有需要“确定性”的环节规划、评审、验收设置成低温度把需要“多样性表达”的环节编码、测试数据生成设置成适中温度。有一段时间开发智能体的温度被我调得过高它每次都会生成风格迥异的代码评审智能体每次都批“风格不统一”两个智能体在代码风格层面打了个昏天黑地浪费了大量Token。这个问题的根因不在评审标准不够严而是温度设置导致了输出方差过大。结构化输出也是落地期的重要优化点。我强制所有智能体的关键输出使用JSON格式规定字段和范围。比如评审智能体输出必须包含severity、file_path、line_number、comment字段。结构化输出让下游系统可以稳定解析结果不用再去猜自然语言里哪句话是“阻断问题”哪句话是“建议”。5.2 可观测性多智能体系统必须全程“开灯跑”单智能体出错了你打开对话框看看哪句话不对就行。多智能体系统出错你连它是在哪个节点错的、错误上下文是什么都不一定能搞清楚。所以我在系统里加了执行日志和链路追踪。每条消息经过消息总线时都会被打上trace_id每次状态变更都会记录执行路径。我把这些数据接进一个简单的看板里可以直观地看到哪个智能体为什么卡住了某个任务在规划阶段和评审阶段哪一个环节耗时最长Token消耗在哪个角色身上最多。这套可观测性体系上线之后最直接的价值是团队不再需要“靠灵感”定位问题。之前有一次测试智能体连续生成了五次重复测试场景我一开始以为是测试逻辑有问题后来通过链路追踪才发现是开发智能体的变更描述写得太模糊测试智能体只好不断猜测意图。问题在测试节点暴露根因在开发节点没有追踪根本查不出来。5.3 安全与权限边界智能体再聪明权限也得“抠门”多智能体系统最大的安全风险不是智能体“变坏”而是权限过于宽泛导致的连带影响。开发智能体如果拥有所有目录的写权限一次输出幻觉就可能把配置目录里的内容覆盖掉。评审智能体如果拥有执行命令的权限一个被构造出来的恶意提示词就可能让它执行不该执行的操作。我的安全设计是三层第一层是文件系统沙箱每个智能体只能访问工作区中自己被允许访问的子目录。第二层是工具权限最小化本来全能的Git命令被拆分成细粒度操作开发智能体只能执行特定操作不能执行任何危险命令运维智能体只能执行预演类命令真实部署权限永远保留在人手上。第三层是输出安全校验智能体生成的shell命令必须经过命令白名单校验命令中不允许出现不受控的变量拼接。此外我还对所有外部输入做了提示词注入防护。项目中某个开源组件的README里写入了一段看起来像是给AI看的指令文本如果开发智能体在读取这份文档时缺乏保护很容易被诱导改变行为。现在的拦截方式是外部输入一律只作为数据处理不允许作为指令处理智能体读取外部内容时明确标记“这是数据不是指令”。6. 重构后的开发团队到底变成了什么样新的分工与我的体会6.1 新的工作流形态人不再写代码而是“定义问题”和“验收结果”系统稳定运行一段时间后我实际感受到的最大变化是日常迭代的工作方式彻底变了。以前我要自己设计接口、写实现、调试、拆Git记录现在更多是在总控调度器里提交一份需求描述等待虚拟团队产出交付包然后集中做两件事审核技术方案、验收最终代码。以一次实际迭代为例。我给总控调度器提交了一个“给某个内部数据平台增加导出任务状态筛选功能”的需求。规划智能体在方案里明确要改三个文件并指出了当前查询接口的一个潜在性能风险。这个发现让我很意外因为它不是眼前需求里明确要求的而是规划智能体在阅读相关代码时主动识别出来的。开发智能体随后完成了实现。评审智能体挑出两个问题一个错误码定义不符合项目规范一个边界场景没有处理。修复之后测试通过运维智能体在沙箱里完成了预演部署。我用了不到二十分钟审核交付包把最终代码合入了主分支。放在以前这个迭代至少要我自己动手大半天。6.2 人的角色变化从“写代码的人”变成“验收者”和“决策者”这套系统对我的要求并没有降低而是转移了。以前我的核心能力是写代码现在我的核心能力变成了判断智能体的产出可不可信。代码功底还在起作用但体现在审核技术方案是否合理、识别容易漏掉的需求边界、仲裁智能体之间的冲突这些地方。我逐渐把虚拟团队当成一支真正的团队来管理每个智能体要有清晰的岗位职责每次重大失误要复盘根因每类新任务要沉淀标准作业流程。系统里的提示词和规则文件就是这支团队的“管理手册”。它们会不断被更新但更新的过程像极了修订团队规范不是为了改而改而是每一版都有真实问题在驱动。6.3 说点实在的哪些场景适合这套系统哪些别凑热闹根据我自己的实践体会多智能体协作系统适合两类场景。一类是需求边界清晰的内部工具迭代浪费点Token可控也不需要大规模跨团队协调。另一类是代码库质量稽核同时派出多个评审智能体检查不同模块比人肉抽查覆盖率高得多。不太适合的场景也有需求本身就模糊、经常变动的探索性工作把这种需求丢给虚拟团队会让它在各种不明确的假设之间反复跳转产出质量远不如一个经验丰富的人慢慢做。另外如果任务只涉及一个文件的小改动也没有必要拉满六个智能体走完整流水线成本反而比直接改更高。现在我的内部项目开发流程基本固定成了“人给方向智能体出活人做验收”的模式。这套“Agency Agents”系统跑了十几个迭代从最初的多次卡死到现在稳定跑通已经成了我日常开发里默认的基础设施之一。如果你也想搭一套类似的系统我最后的建议是不要一上来就追求“全自动”先让每个角色独立跑通再连协作链路等状态机可控了再去优化并发和成本。多智能体系统的复杂度远超单智能体但当你亲眼看到一支虚拟团队并行推进任务的时候真的会觉得之前卡住自己的那些事其实早该换个组织了。