资讯详情

多智能体协作系统架构与实践:从单Agent瓶颈到开发团队重构

📅 2026/10/22 5:11:40 | 华诺云谱 👁 阅读
多智能体协作系统架构与实践:从单Agent瓶颈到开发团队重构
去年年初我们团队做了一次不太常见的重构重构对象不是某个服务也不是某段代码而是开发团队自己干活的方式。我们试着把需求拆解、方案评审、编码、测试、交付这些原本需要人不断同步信息的工作交给一套内部代号叫 Agency Agents 的多智能体协作系统来推进。这篇文章想把它的架构设计、落地过程和踩坑经历完整写出来。Agency Agents 不是什么玄学本质上是把“一个开发团队如何协作”这件事显式地建模成角色、契约、路由、状态和验收规则。如果你正在考虑多智能体系统或者被各种 Agent 概念绕晕可以参考我们的做法哪些环节值得自动化哪些地方必须留给人又有哪些坑是只有在真实项目里才会撞上的。1. 传统研发协作的真正瓶颈不是人手不够是上下文断裂1.1 为什么单Agent到了某个阶段就推不动了我们最开始尝试的并不是多智能体而是一个“超级助手”把一整份需求文档丢给一个大模型让它一次性产出方案、代码和测试。结果并不理想。代码表面上能跑但方案和需求对不上甚至会把上一个项目的旧逻辑带进新代码。后来复盘问题不在模型能力而是我们把任务结构想得太简单了。开发团队真正能高效运转靠的不是某个人特别聪明而是信息在角色之间传递时损耗小。产品说“用户点击按钮后要看到反馈”开发听到的可能是另一个意思测试理解的又是第三个版本。人工协作时这种偏差依靠会议、评审来纠正但每一次纠偏都消耗时间。到了单 Agent 场景问题被放大了一个模型要同时记住需求、技术约束、代码现状、测试口径上下文窗口再大也扛不住。而且它没有“反馈回路”自己写完代码自己评审等于既当运动员又当裁判。我们试了几轮发现单 Agent 在中型模块上勉强能干活一旦需求稍微复杂输出的稳定性就断崖式下跌。1.2 从“流水线”到“Agent团队”的思想转换传统开发流程通常被描述成一条流水线需求 → 设计 → 编码 → 测试 → 发布。这条流水线强调的是“顺序执行”而不是“协作”。但真实开发团队不是这么运转的架构师会回头质疑需求测试会反馈代码问题开发会补充设计遗漏。信息流是网状的不是直线型的。Agency Agents 借鉴的正是这种网状协作。我们不再试图用一个 Agent 完成所有事而是定义了一批各有边界的角色需求分析 Agent 只负责把模糊输入整理成结构化需求架构 Agent 只负责基于需求产出技术方案研发 Agent 只负责按方案写代码评审 Agent 只负责提出修改意见测试 Agent 只负责验证行为是否符合验收标准。每个角色都不掌握全局但它们通过事件和共享状态交换信息。这样做的好处是上下文可以被切碎到每个角色够用的程度任何一个 Agent 的失败都不会拖垮整个系统因为失败会落到一个可观测的任务单元里。1.3 这套系统适合谁不适合谁先说适合的场景。我们团队当时负责的是一批流程已经相对固定的业务模块需求格式、编码规范、测试要求都有历史沉淀。这类模块很适合多智能体化因为“协作规则”是明确的Agent 只是在执行已经被人总结过无数遍的流程。不适合的场景也很多。如果需求本身极不明确连人都说不清验收标准多智能体系统只会加速混乱因为每个 Agent 都会基于自己那部分碎片信息作出自信但错误的判断。小规模原型探索也没必要上这套系统两三个 Agent 的编排成本可能比人工协作还高。我们内部的原则是一个流程如果还没有稳定跑通三个月就不要急着交给 Agent。2. Agency Agents的整体架构编排层、执行层与记忆层各司其职2.1 架构总览五层各干什么Agency Agents 虽然听起来复杂但架构上我们只分了五层。接入层负责接收外部请求把自然语言需求转成系统内部的标准任务单编排层是大脑决定每个任务该交给谁、失败了怎么办执行层是所有 Agent 的运行时负责调用模型和工具记忆层保存短期会话、项目级长期记忆和全局状态审计层记录每一次决策、每一次工具调用供事后追溯。这五层里最容易被人忽视的是记忆层和审计层。很多团队搭多智能体时只关注“Agent 能干什么”却忽略了“Agent 记着什么”和“Agent 干过什么”。缺少记忆层Agent 之间就像一群没有共同文档的员工各自凭印象干活缺少审计层出了问题根本没办法复盘只能靠猜。2.2 角色即配置用类与Profile定义Agent我们在系统里把每个 Agent 定义成一份配置而不是写死在代码里。这么做是希望角色边界能随时调整毕竟不同项目的流程细节不一样。下面是一段简化过的角色配置示例agents: requirement_analyst: model: backend-v3 context_window: 32k memory: project_memory tools: [read_repo, search_docs, write_spec] output: requirement_spec tech_lead: model: backend-v3-max context_window: 64k tools: [read_repo, read_spec, write_plan] output: architecture_plan developer: model: backend-v3 context_window: 128k tools: [read_spec, read_plan, list_files, edit_code, run_tests] output: code_changes配置里最关键的不是模型选择而是tools权限列表。一个 Agent 能调用什么工具决定了它的能力边界。后面我会专门讲权限失控带来的事故这里先记住一个结论角色配置的核心是收敛不是堆能力。我们也没有给所有 Agent 都用最强模型。需求分析 Agent 用中等模型就够技术方案 Agent 需要用更强模型来权衡利弊而研发 Agent 反而要选上下文窗口更大的模型因为它要同时读方案、读代码、跑测试。不同模型各司其职成本比全部拉满低很多。2.3 通信与状态事件总线、全局状态与消息补偿多个 Agent 之间怎么通信是最容易走偏的设计点。我们踩过的最深的一个坑是让 Agent 直接调用彼此的接口。比如需求分析 Agent 处理完直接调架构 Agent 的接口。表面看链路很清晰一旦某个环节失败整个调用链就被卡死了而且问题发生在哪一层很难定位。后来我们改成事件总线模式。Agent 之间不直接调用而是把结果作为事件发布到总线上编排层根据订阅关系决定下一步触发谁。每个事件都带唯一的 trace_id可以从需求入口一路追踪到交付物。这样即使某个 Agent 处理失败消息也不会丢失而是进入补偿队列由编排层决定重试还是转人工。全局状态我们用的是一套带命名空间的键值存储。每个写入状态的操作必须声明自己是哪个 Agent、属于哪个项目、是哪一轮任务。这个设计听起来笨但在排查问题上帮了大忙。没有命名空间的时候两个 Agent 往同一个 key 上写数据后写的人会覆盖先写的人而且毫无感知。2.4 一次典型任务流转的时序描述为了让你对整体运行有画面感我描述一次典型任务收到一条用户需求后接入层先把需求标准化成 ticket包含描述、优先级、验收标准初稿。编排层根据 ticket 类型路由给需求分析 Agent。分析 Agent 读取项目既有文档产出结构化需求规格发布事件。架构 Agent 订阅到需求规格事件后读取代码库结构和历史架构决策产出技术方案。研发 Agent 接着按方案修改代码每改完一个文件就运行相关测试所有测试通过后发布“代码就绪”事件。评审 Agent 把代码变更和需求规格放一起对照审查提出意见。如果意见为空意味着可以交付如果有意见事件回传给研发 Agent 继续修改。最终编排层把交付清单发给人工确认由人来执行最后一步。这里每一步都不是串行阻塞而是围绕事件驱动的异步推进。3. 把开发流程改写成Agent协作脚本拆解、路由与验收3.1 从需求到验收六个角色的职责边界如果把整个系统当成一个开发团队那么角色划分就是组织架构。我们当时用六个角色跑通了完整链路需求分析 Agent、架构 Agent、研发 Agent、评审 Agent、测试 Agent、交付 Agent。每个角色都有明确的输入、输出和兜底策略。角色核心职责主要输入主要产出兜底策略需求分析 Agent将模糊需求转成结构化规格用户工单、历史文档需求规格、验收标准补采问题超过3轮转入人工架构 Agent输出技术方案与风险点需求规格、代码结构架构方案、变更清单方案引用不存在文件则重试并告警研发 Agent按方案实现代码与自测架构方案、任务说明代码变更、测试结果测试失败时最多重试2次评审 Agent对照需求和方案审查代码代码变更、需求规格评审意见列表意见循环超过5轮自动升级人工测试 Agent按验收标准执行验证测试计划、运行环境验证报告环境异常转人工运维交付 Agent生成发布清单等待人工确认验证报告、变更记录发布说明、回滚方案任何一步失败则阻塞发布这个表背后有一条原则职责只保留“完成一项可交付物”所需的最小范围。比如评审 Agent 不需要写代码能力测试 Agent 不需要架构规划能力。角色职责越窄上下文越干净失败定位也越容易。3.2 任务路由规则与失败兜底有了角色之后编排层要回答一个问题一个任务进来到底该推进给谁我们用的不是自然语言让 Agent 自行判断而是一张显式路由表。每个入站任务都带 type、project_id、source_agent、required_permission 等元数据路由逻辑直接用代码表达。def route_task(task): if task.type requirement_refinement: return requirement_analyst if task.type architecture_review: return tech_lead if task.type implementation: return developer if task.phase review: return reviewer if task.phase test: return tester raise UnroutableTaskError(task.id)这段伪代码朴素但可靠。一开始我们想让路由也由大模型决定后来发现模型对路由的判断不稳定经常把测试任务发给研发 Agent或者把评审任务发给需求 Agent。手工维护路由表虽然不够“智能”却保证了行为可预期。失败兜底同样重要。我们给每个任务设置了最大重试次数和超时时间。比如评测任务最多重试 2 次评审循环最多 5 轮。达到上限后任务自动进入人工接管队列。我们团队每天有一个固定的值班角色处理接管队列这个角色不会去改 Agent 的代码而是把卡住的任务手动推进到下一个合理的环节。3.3 让结果可验证结构化输出与签名校验多智能体系统里最危险的信号是 Agent 之间的交流使用自由文本。自由文本看着灵活但下游 Agent 解析时很容易出错而且错误是静默发生的。我们要求所有 Agent 之间传递的消息必须是结构化对象并且带版本号和校验字段。例如需求分析 Agent 的产出不是一段散文而是一个包含目标、范围、验收条件列表的数据结构。研发 Agent 的提交说明也不是“完成了功能”而是一份包含文件路径、变更类型、测试结果的结构化报告。编排层对每份产出做 JSON Schema 级别的校验不满足结构就直接丢弃并触发重试。这种设计让系统里的人机协作也变得顺畅。人工确认交付清单时看到的不是一个聊天窗口里的长篇大论而是一份字段清晰的审批单。哪些需求被实现、哪些测试通过、回滚步骤是什么一目了然。我们后来总结过一句话Agent 之间要讲协议不要讲段子。4. 落地过程中最难啃的三块硬骨头循环、污染与权限4.1 Agent互相“踢皮球”循环调用的定位过程多智能体系统上线后的第一次重大事故发生在事件总线上。某个深夜总线消息量突然飙到了平时的几十倍我们第一反应是流量攻击查了半天发现是内部两个 Agent 在互发消息。现象如下需求分析 Agent 发布一条“需求约束不足”的事件架构 Agent 收到后回复“需要更明确的验收标准才可估算工期”需求分析 Agent 又基于这个回复生成了新的约束补丁架构 Agent 又指出新的问题。两个 Agent 都认为自己只是按规则“询问必要信息”但实际上陷入了无限循环。我们通过 trace_id 过滤出整条链路一次一次查看两边的输入输出最后定位到根因这两个 Agent 都调用了一个共同的意图分类工具工具会鼓励 Agent 在信息不足时主动追问但系统里没有定义“追问次数上限”。修复方案分三层给每个协作任务增加最大交互轮数超过后强制升级人工把“请求补充信息”从自由对话改成半结构化表单必须指定缺失字段在编排层增加循环检测器如果同一对 Agent 的消息模式在过去 N 轮内重复出现就中断链路并告警。这次事故让我意识到多智能体系统的循环问题比单线程代码里的死循环更难发现因为它不是同一个 Agent 重复执行同一段逻辑而是两个 Agent 在互相放大彼此的臆测。4.2 上下文污染像雪崩如何用命名空间和快照止血第二个折磨我们的问题是上下文污染。现象很诡异评审 Agent 的评审意见里居然出现了只有需求分析 Agent 才应该知道的信息。起初我以为是模型串了后来查了状态存储才发现两个 Agent 共用了同一个 key 来缓存临时信息后写入的用户偏好数据被评审 Agent 当成了项目级事实。这就是典型的“多人共用一本草稿纸”问题。每个人都在上面演算可你永远不知道哪行是演算草稿哪行是正式公式。我们当时的止血措施是先给所有状态 key 加上命名空间和版本号规则是project_id:agent_id:purpose:version任何 Agent 只能读自己的命名空间以及通过事件总线发布的、带 schema 的共享消息。接着我们引入任务级快照机制。每个任务开始时系统会从记忆层加载最近一次校验通过的项目快照任务跑完后只有经过校验的产出物才被写回共享存储。这样即使某个 Agent 在工作过程中把临时状态写乱了也不会影响其他 Agent。还有一个细节大模型读上下文是有极限的不是给得越多越好。我们后来给“读历史”这个操作设定了一个裁剪策略只保留和当前任务直接相关的摘要。这个策略见效很快上下文污染问题基本绝迹而且模型输出的质量反而提升了。4.3 工具权限风暴最小授权原则的工程化如果只能给出一条安全底线我会选工具权限。我们曾经出过一次非常低级的事故测试 Agent 在执行回归测试时误调用了生产环境的部署工具把一个灰度环境标记成了新版本。原因说起来很丢人最初为了图省事所有 Agent 共享一个全局工具注册表谁都能调用所有工具。事故发生之后我们把工具权限彻底重构成了配置的一部分。每个 Agent 的配置里必须显式声明自己可以用哪些工具运行时还有一个统一权限拦截层对每次工具调用检查 scope。以下是我们当时总结的权限分级权限级别工具示例触发条件L1 只读读取仓库、检索文档任何相关 Agent 可直接调用L2 工作区写入修改代码、运行测试仅限研发、测试 Agent且必须在任务工作区内L3 半危险生成发布单、修改配置必须附带完整变更说明并记录审计日志L4 高危部署生产、变更配置任何人不能直接调用必须由外部人工审批事件触发L4 的处理方式很关键Agent 可以“请求”交付但不能“执行”交付。交付 Agent 在确认验证通过后会生成一份审批单推给人工由人工在独立的审批界面点击确认系统才会真正调用部署工具。这个设计牺牲了一点自动化率但换来了安全底线。5. 实测数据与团队角色重构开发者的日常发生了什么变化5.1 我们从指标上看到的提升在系统稳定运行三个月后我们做了一次内部复盘。口径不同团队没法直接对比但有几个趋势是明显的常规需求从接单到第一个可评审版本的前置时间缩短了大约四成需要人工介入的次数从原来的一次需求七八次降到了两三次测试反馈的问题里单纯的遗漏性错误明显减少因为测试 Agent 每次都会严格按验收标准逐条执行。但也有表现不好的场景。凡是需要跨团队线下协调、或者需求本身高度依赖行业经验的活儿系统不但没提速反而因为反复补充信息而变慢。这提醒我们多智能体系统不是通用的效率放大器它只适合那些“协作规则已经被理解得很透彻”的工作。数据从另一个角度也告诉我们自动化率不是唯一目标。我们关注的是端到端交付时间和返工率而不是“让多少个 Agent 在跑”。如果 Agent 跑得很热闹但没有产出可交付物那就是浪费。5.2 开发者的工作从“写代码”变成“定规则和验收”重构开发团队这件事最终被人感受最深的不是系统本身而是团队成员的日常工作变了。以前开发者的主要精力在实现功能上上线后还要反复排查环境问题。现在大家的精力被重新分配到三类事情上定义路由规则、编写验收校验器、处理人工接管队列。写代码依然重要但代码更多是给校验器用的把“用户输入无空指针”写成可执行的测试把“协议字段必须具备版本号”写成 schema 校验。Agent 写实现人来写验收这个分工听起来有点颠覆实际跑起来却比想象中顺畅因为验收规则永远掌握在人手里。测试工程师的角色变化更明显。他们不再只是跑测试而是变成“验收规则评审者”去检查测试 Agent 制定的测试计划是否覆盖了关键路径是否漏掉了边界条件。这个转变要求测试人员更懂业务而不是更懂某个测试工具。5.3 留给我们自己的三条底线这套系统跑了一年多我们总结了三条底线任何项目只要触碰其中一条我们就会停下来重新讨论。第一条任何任务必须具有可判定的完成条件否则不进系统。如果连人都说不清“怎样算完成”就不要指望 Agent 能自己定义。第二条任何面向外部用户的交付动作必须有人工确认环节。Agent 可以做到 99% 的准备但最后 1% 的确认和担责必须留给人类。第三条所有 Agent 行为必须可回溯。我们要求每次工具调用、每条事件、每次模型输出都记录 trace_id。宁可牺牲一部分执行速度也不能牺牲可观测性。我后来回想这三条里面最容易被忽略的是第一条。很多团队把大量精力花在调模型、选框架上却不愿意花时间把需求写成结构化的验收标准。但在我们的经验里结构化验收标准带来的收益比换一个更贵的模型大得多。如果你也想做类似的多智能体系统我给的建议是从一个极小的闭环开始选择一个流程成熟、失败后果可控的内部场景设计两个 Agent一个负责产出一个负责审查中间用严格的事件和状态协议串起来。先把链路跑透再考虑加角色、扩场景。最后说一个我自己的体会。Agency Agents 真正改变我们团队的不是让我们彻底不用写代码了而是逼着我们把“开发团队如何协作”这件事讲清楚了。很多模糊的流程在写角色配置、写路由规则、写验收函数的过程中变得前所未有地明确。哪怕哪一天这套系统被完全拆掉留下的这套协作协议依然会让团队跑得更快。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑