1. 为什么研发协作需要多 Agent 而不是一个大模型
1.1 单模型处理研发流程的三个硬伤
很多团队一开始的想法很朴素:既然大模型能写代码、能读日志,那我直接拿一个通用模型,把 Issue 内容、PR diff、CI 日志全塞进上下文,让它一次性给出结论不就行了?我最早也是这么干的,实测下来有三个绕不过去的硬伤。
第一个是上下文污染。Issue 里往往夹杂着用户情绪化的描述、无关的截图说明、历史遗留的讨论串;PR diff 里是几百行结构化代码;CI 日志动辄几千行且大部分是噪音。这三类信息的"语言风格"和"关注重点"完全不同,塞进同一个上下文后,模型很容易被无关信息带偏。比如你让它审查 PR,它却开始复述 Issue 里用户抱怨的某个功能,因为它分不清当前任务边界。
第二个是职责冲突。分析 Issue 需要的是"归纳诉求、判断优先级、识别复现步骤";审查 PR 需要的是"代码规范、逻辑漏洞、边界条件、测试覆盖";CI 排障需要的是"日志模式匹配、错误链路定位、环境差异推断"。这三套能力对模型的提示词、输出格式、甚至温度参数要求都不一样。用一个模型一套提示词硬扛,结果就是每样都做得"差不多但不够好"。
第三个是可观测性差。单模型一把梭,出了问题你根本不知道是哪一步错了——是 Issue 理解偏了?还是 PR 审查漏了关键文件?还是 CI 日志解析时把关键行截断了?整个链路是个黑盒,调试成本极高。
1.2 多 Agent 分工的核心逻辑:让每个 Agent 只做一件事
多 Agent 架构的本质,是把上面那团乱麻拆成几条清晰的流水线。每个 Agent 有自己的系统提示词、自己的工具集、自己的输出契约,彼此通过结构化的消息传递协作。这样做的好处非常直接:
- 每个 Agent 的上下文是干净的。Issue 分析 Agent 只看到 Issue 相关内容,PR 审查 Agent 只看到 diff 和仓库规范,CI 排障 Agent 只看到日志和构建配置。
- 每个 Agent 可以独立调优。你觉得 PR 审查太宽松,就单独调它的提示词和阈值,不影响其他环节。
- 每个 Agent 可以独立观测和替换。某个 Agent 效果不好,直接换掉或升级,其他部分不动。
打个比方,这就像把一个"全科医生"换成"分诊台 + 专科医生"的组合。分诊台负责判断你该去哪个科,专科医生只处理自己领域的问题,效率和准确率都高得多。
1.3 DevFlow AI 的整体架构长什么样
我设计的 DevFlow AI 由四个核心 Agent 加一个协调器组成,整体数据流是这样的:
| 组件 | 职责 | 输入 | 输出 |
|---|---|---|---|
| 协调器 Orchestrator | 任务分发、状态管理、结果汇总 | 事件触发(新 Issue / 新 PR / CI 失败) | 调度指令 |
| Issue 分析 Agent | 归纳诉求、分类、优先级、复现步骤提取 | Issue 标题、正文、评论 | 结构化 Issue 报告 |
| PR 审查 Agent | 代码规范、逻辑风险、测试覆盖检查 | PR diff、仓库规范文件 | 审查意见列表 |
| CI 排障 Agent | 日志解析、错误定位、修复建议 | CI 日志、构建配置 | 排障报告 |
| 汇总 Agent | 把各 Agent 结果整合成人类可读的评论 | 各 Agent 的结构化输出 | 最终评论/通知 |
协调器不直接做推理,它只负责"什么时候叫谁干活"。这种设计让整个系统像一个流水线工厂,而不是一个什么都干的杂货铺。
提示:协调器的状态管理建议用简单的状态机而不是复杂的编排框架。我一开始用了某编排框架,结果发现调试成本比收益还高,后来退回用几十行状态机代码,反而更稳。
2. Issue 分析 Agent:从一堆抱怨里提炼出可执行的需求
2.1 Issue 文本的脏乱差是常态
真实的 Issue 从来不是规规矩矩的"需求描述"。我统计过我们仓库近半年的 Issue,大概分布是这样的:约 30% 是纯 bug 报告但描述模糊("点了没反应"),约 25% 是功能请求但夹杂大量个人偏好,约 20% 是重复或已解决的问题,剩下的是文档问题、环境问题、以及完全跑题的讨论。
如果直接把原始文本丢给模型让它"分析一下",输出往往是一段正确的废话。所以 Issue 分析 Agent 的第一步不是理解,而是清洗和结构化。
2.2 分步提示词设计:先抽取,再判断,最后归纳
我的做法是把 Issue 分析拆成三个串行的子步骤,每个子步骤用独立的提示词调用,而不是一个提示词搞定所有事。
第一步:信息抽取。让模型只做一件事——从文本里抽出这些字段:问题现象、复现步骤、期望行为、实际行为、环境信息、附件链接。这一步不要求模型做任何判断,只做"找出来"。提示词里明确要求:找不到的字段填"未提供",不要脑补。
第二步:分类与去重判断。拿到结构化字段后,再让模型判断这是 bug / 功能请求 / 文档问题 / 环境问题 / 其他,并给出置信度。同时把标题和摘要与历史 Issue 库做向量相似度比对,相似度超过阈值的标记为"疑似重复"。
第三步:优先级与可执行性评估。最后一步才做价值判断:影响范围多大?有没有 workaround?是否阻塞核心流程?综合给出 P0-P3 的优先级建议,并明确标注"信息不足,需要补充哪些内容"。
这样拆的好处是,每一步的输出都可以单独验证。如果最终结果不对,你能快速定位是抽取错了、分类错了、还是优先级判断错了。
2.3 结构化输出的字段设计
Issue 分析 Agent 最终输出一个 JSON,字段设计如下:
{ "issue_id": "ISSUE-1234", "category": "bug", "category_confidence": 0.92, "priority": "P1", "priority_reason": "影响核心登录流程,无 workaround", "symptom": "用户点击登录按钮后页面无响应", "reproduce_steps": ["打开登录页", "输入正确账号密码", "点击登录"], "expected": "跳转到首页", "actual": "按钮无响应,控制台报错", "environment": "Chrome 120, Windows 11", "missing_info": ["是否有网络请求发出", "控制台完整报错"], "duplicate_candidates": ["ISSUE-1180"], "suggested_labels": ["bug", "auth", "P1"] }这个 JSON 就是 Issue 分析 Agent 的"产品"。下游的汇总 Agent 直接读这个结构,不需要再去理解自然语言。
2.4 实测中容易翻车的两个点
第一个坑:模型过度脑补复现步骤。用户只写了"登录不了",模型却编出了五步复现步骤。解决办法是在提示词里加硬约束:"复现步骤必须能在原文中找到对应描述,否则返回空数组并在 missing_info 中标注。"加了这条之后,脑补现象基本消失。
第二个坑:优先级判断受情绪词影响。用户写"紧急!崩溃了!",模型就给 P0。但实际上那个"崩溃"只是某个边缘页面的样式错位。我的处理是让优先级判断只看客观字段(影响范围、是否阻塞、有无 workaround),把情绪化的原文单独隔离,不参与优先级推理。
注意:Issue 分析 Agent 的输出建议先以"草稿评论"形式发到 Issue 里,让人确认后再打标签。全自动打标签在早期很容易误伤,人工确认一轮能积累大量修正样本,反过来优化提示词。
3. PR 审查 Agent:不是让 AI 挑刺,而是让它守住底线
3.1 PR 审查的目标要收敛,别指望 AI 做架构评审
很多人对 PR 审查 Agent 的期待是"帮我找出所有问题",这个期待本身就是错的。AI 做不了架构评审,也判断不了业务逻辑是否符合产品意图。它能做且应该做的,是守住那些明确、可规则化、容易遗漏的底线。
我把 PR 审查 Agent 的职责收敛为四类:
- 规范类:命名规范、文件组织、提交信息格式、是否更新了文档。
- 风险类:明显的空指针、未处理的异常、硬编码密钥、危险的 SQL 拼接。
- 测试类:新增逻辑是否有对应测试、测试是否覆盖了边界条件。
- 一致性类:改动是否与仓库既有的模式一致(比如别人都用某个工具函数,你却又写了一个)。
超出这四类的,一律不报。宁可漏报,不可误报——误报多了,开发者就会直接忽略所有 AI 评论,这个 Agent 就废了。
3.2 diff 的预处理:先切块,再逐块审查
直接把整个 diff 丢给模型效果很差,因为一个 PR 可能改了 20 个文件。我的做法是先把 diff 按文件切块,再按"改动类型"分组:
- 纯新增文件
- 纯删除文件
- 修改文件(再细分为:只改逻辑、只改样式、改配置、改测试)
然后对每一块单独调用审查提示词,最后合并结果。这样做的好处是,模型每次只需要关注一小段代码,注意力集中,判断更准。
对于超大 PR(超过 500 行改动),我会先让模型做一个"改动摘要",识别出这个 PR 主要动了哪些模块,然后只对核心模块做深度审查,边缘改动只做规范检查。这是基于实践的取舍——超大 PR 本来就该拆分,AI 没必要为它兜底。
3.3 审查意见的措辞直接影响采纳率
这一点是我踩了很多坑才悟出来的。同样一个问题,措辞不同,开发者的反应天差地别。
| 差的措辞 | 好的措辞 |
|---|---|
| 这里有空指针风险 | 第 42 行user.profile.name在 user 为 null 时会抛异常,建议加可选链或前置判空 |
| 缺少测试 | 新增的calculateDiscount函数有 3 个分支,当前测试只覆盖了 1 个,建议补充边界用例 |
| 命名不规范 | 变量d建议改为discountRate,与仓库其他文件的命名风格保持一致 |
核心原则:指出具体位置、说明具体后果、给出具体建议。模糊的批评只会引发防御心理,具体的建议才会被采纳。
3.4 如何避免"狼来了"效应
PR 审查 Agent 最大的敌人不是漏报,而是误报导致的信任崩塌。我做了三件事来控制误报:
第一,建立白名单机制。某些文件(如自动生成的代码、第三方库的封装)直接跳过审查。某些规则(如行长度)如果团队本来就不在意,直接关掉。
第二,分级输出。把意见分为"必须修改"和"建议考虑"两档。必须修改的才阻塞合并,建议考虑的只是评论。这样开发者不会因为一堆鸡毛蒜皮的建议而烦躁。
第三,定期复盘误报。我每周会看一遍 AI 评论被开发者标记为"无效"的记录,把高频误报模式加到提示词的负面示例里。这个反馈闭环是让 Agent 越用越准的关键。
提示:PR 审查 Agent 的提示词里一定要放几段"仓库自己的代码范例",让模型学习本仓库的风格。通用规范模型都知道,但"本仓库的习惯"只有喂了范例它才懂。
4. CI 排障 Agent:把几千行日志变成一句话结论
4.1 CI 日志的噪音比例高得离谱
一个典型的 CI 失败日志,真正有用的信息可能只占 5%。剩下的 95% 是:依赖下载进度、测试用例的通过输出、编译器的正常警告、以及各种时间戳和路径。如果直接把原始日志丢给模型,token 消耗巨大且效果差。
所以 CI 排障 Agent 的第一道工序是日志压缩。我的压缩策略分三层:
- 第一层:按行过滤。用正则先剔除明显无用的行(下载进度、纯时间戳、已知的正常警告)。
- 第二层:按块聚合。把连续的测试通过输出聚合成一行"XX 个测试通过"。
- 第三层:错误上下文提取。定位到第一个 ERROR 或 FAILED 关键字后,向前后各取 50 行作为"错误上下文",这是最关键的输入。
经过这三层压缩,几千行日志通常能压到 100-200 行,信息密度大幅提升。
4.2 错误分类:先判断"是不是代码问题"
CI 失败的原因五花八门,但大致可以分成几类,处理策略完全不同:
| 失败类型 | 典型特征 | 处理策略 |
|---|---|---|
| 代码错误 | 编译失败、测试断言失败 | 定位到具体文件和行,给出修复方向 |
| 环境问题 | 依赖下载失败、端口占用 | 建议重试,标注为"疑似环境抖动" |
| 配置问题 | 变量未定义、路径不存在 | 指出缺失的配置项 |
| 资源问题 | 超时、内存不足 | 建议调整资源或拆分任务 |
| 偶发失败 | 无明确错误,重跑即过 | 标记为 flaky,建议重试 |
这个分类非常重要,因为不是所有 CI 失败都需要开发者改代码。如果 Agent 把环境抖动也报成"代码有 bug",开发者会疯掉。我的做法是让 Agent 先做这个分类判断,只有"代码错误"和"配置问题"才 @ 相关开发者,"环境问题"和"偶发失败"只建议重试。
4.3 从错误日志到修复建议的推理链
CI 排障 Agent 最有价值的部分,是把错误日志翻译成"人话 + 修复方向"。我要求它的输出必须包含这条推理链:
- 失败发生在哪个阶段(安装依赖 / 编译 / 测试 / 打包 / 部署)
- 直接错误信息是什么(原文引用关键行)
- 根因推断是什么(基于错误信息的合理推断)
- 建议的修复动作是什么(具体到改哪个文件、加什么配置)
举个例子,日志里出现ModuleNotFoundError: No module named 'xxx',Agent 的输出应该是:
- 阶段:测试阶段
- 直接错误:导入 xxx 模块失败
- 根因推断:依赖未安装,或 requirements 文件未更新
- 修复建议:检查 requirements.txt 是否包含 xxx,若缺失则添加并重新提交
这种结构化的输出,比一句"CI 挂了,请检查"有用一百倍。
4.4 重试决策:什么时候该自动重试,什么时候该叫人
这是 CI 排障 Agent 里最需要谨慎的部分。我的策略是:
- 明确的环境抖动(如依赖源超时、网络错误):自动触发重试,最多 2 次,重试成功则不打扰任何人。
- 疑似偶发失败(无明确错误但失败):标记为 flaky,自动重试 1 次,若仍失败则通知。
- 明确的代码/配置错误:不重试,直接通知相关开发者,附上排障报告。
这个策略的核心是减少无效通知。开发者最烦的就是"CI 挂了"的通知,点进去发现重跑一下就好了。自动重试能过滤掉大部分这类噪音。
注意:自动重试一定要有次数上限和冷却时间,否则遇到持续性的环境问题会陷入无限重试。我设的是最多 2 次、间隔 5 分钟,超过就转人工。
5. 多 Agent 之间的协作与状态管理
5.1 事件驱动还是轮询:我为什么选事件驱动
协调器怎么知道该干活了?两种方式:轮询(每隔几分钟检查有没有新 Issue/PR/CI 失败)和事件驱动(平台 webhook 触发)。
我选的是事件驱动,理由是延迟低且不浪费资源。轮询在仓库活跃度低的时候纯属空转,活跃度高的时候又可能漏掉事件。事件驱动则是"有事才干活",响应快,成本低。
但事件驱动有个坑:事件可能重复投递或乱序。所以协调器必须做幂等处理——每个事件带唯一 ID,处理过的 ID 记录下来,重复的直接丢弃。这个幂等层是必须的,否则同一个 PR 可能被审查两次,发出两条重复评论。
5.2 Agent 之间的消息契约
多 Agent 协作最容易出问题的地方,是 Agent 之间的"接口"不清晰。我的做法是给每个 Agent 定义严格的输入输出契约,用 JSON Schema 约束。
比如 PR 审查 Agent 的输入契约要求必须包含:pr_id、diff_chunks(已切块的 diff 数组)、repo_conventions(仓库规范文本)。输出契约要求必须包含:pr_id、findings(意见数组,每条含文件、行号、级别、描述、建议)。
有了这个契约,任何一个 Agent 都可以被替换或升级,只要它遵守契约,其他部分完全不用改。这就是多 Agent 架构的可维护性优势。
5.3 失败处理:某个 Agent 挂了怎么办
真实系统里,Agent 调用失败是常态(超时、限流、返回格式错误)。我的处理原则是降级而非中断。
- Issue 分析 Agent 失败:发一条"自动分析暂不可用,请人工处理"的评论,不阻塞 Issue 流程。
- PR 审查 Agent 失败:跳过 AI 审查,正常走人工 review,不阻塞合并。
- CI 排障 Agent 失败:只发原始日志链接,不做分析。
核心思想是:AI 是辅助,不是关卡。任何 AI 环节挂掉,都不能阻塞研发主流程。这个原则在系统设计初期就要定下来,否则后期会变成"AI 一挂全组停工"的尴尬局面。
5.4 成本控制:不是每个 PR 都值得全量分析
多 Agent 系统跑起来之后,token 成本是个现实问题。我做了几层控制:
- 小改动跳过深度审查。改动少于 10 行的 PR,只做规范检查,不做深度逻辑审查。
- 草稿 PR 不触发审查。标记为 draft 的 PR 不消耗资源。
- 同一 PR 的重复推送做增量分析。只分析新增的 commit,不重复分析已审过的部分。
- 设置每日预算上限。超过上限后降级为只做基础检查。
这些策略让成本可控,同时不影响核心体验。
6. 落地过程中的真实踩坑记录
6.1 提示词里的"示例"比"规则"更管用
我一开始写提示词,喜欢列一堆规则:"你必须检查 A、B、C、D……"结果模型经常顾此失彼。后来我改成给示例:放 3-5 个"好的审查意见"和"差的审查意见"的对比,让模型模仿。效果立竿见影。
原因是,规则是抽象的,模型需要自己翻译成具体行为;而示例是具体的,模型直接模仿就行。对于输出格式要求高的任务,示例的效果远好于规则描述。
6.2 别让 Agent 输出自由文本,强制 JSON
早期我让 Agent 输出自然语言,然后自己写正则去解析。结果模型今天用"建议:"明天用"推荐:"后天用"可以考虑:",正则改到崩溃。后来全部改成强制 JSON 输出,配合 JSON Schema 校验,解析问题彻底消失。
如果模型偶尔输出非法 JSON,加一个"修复重试"环节:把非法输出和错误信息一起发回给模型,让它修正。通常一次就能修好。
6.3 人工反馈闭环是系统进化的唯一途径
多 Agent 系统上线只是开始,真正的价值在于持续优化。我在每个 Agent 的输出旁边都加了"有用/无用"的反馈按钮,收集到的反馈每周复盘一次。
复盘时重点看两类:误报(AI 报了但实际没问题)和漏报(人工发现了但 AI 没报)。误报加到负面示例里,漏报加到正面示例里。这个闭环跑上几周,Agent 的准确率会有肉眼可见的提升。
6.4 不要追求全自动,人机协作才是正解
最后说一个心态上的坑。我一开始总想着"全自动",让 AI 直接打标签、直接阻塞合并、直接关闭 Issue。结果出了几次误判,团队对系统的信任度骤降。
后来我调整了定位:AI 做初筛和建议,人做最终决策。AI 把 80% 的重复劳动干掉,人只需要处理那 20% 需要判断的部分。这个定位下,团队接受度高得多,系统也真正融入了工作流。
| 环节 | 全自动做法 | 人机协作做法(推荐) |
|---|---|---|
| Issue 打标签 | AI 直接打 | AI 建议,人确认 |
| PR 审查 | AI 阻塞合并 | AI 评论,人决定是否阻塞 |
| CI 排障 | AI 自动重试并通知 | AI 自动重试,失败才通知人 |
| 优先级 | AI 直接定 | AI 建议,人调整 |
这套人机协作的边界,是我踩了无数坑之后总结出来的。核心就一句话:AI 负责"快",人负责"准"。两者结合,才是研发协作效率提升的正解。
7. 从零搭建这套系统的实操路线
7.1 先跑通单 Agent,再谈多 Agent
如果你也想搭一套类似的系统,我的建议是千万别一上来就搞多 Agent。先选一个最痛的场景(通常是 PR 审查或 CI 排障),用单 Agent 跑通,验证价值,积累提示词经验。等单 Agent 稳定了,再考虑拆分和协作。
多 Agent 的复杂度主要来自协作,而不是单个 Agent。如果单 Agent 都没跑明白,多 Agent 只会让你更混乱。
7.2 技术选型的几个务实建议
- 模型选择:不要迷信最大的模型。Issue 分类、日志解析这类任务,中等模型加好的提示词就够了,成本低很多。只有 PR 审查这种需要深度推理的,才值得上大模型。
- 向量库:Issue 去重需要向量检索,用轻量级的本地向量库即可,不必上重型方案。
- 编排:如前所述,简单的状态机代码往往比编排框架更实用。
- 部署:先跑在单机上,用定时任务或 webhook 触发。等稳定了再考虑容器化和高可用。
7.3 衡量效果的三个指标
系统上线后,怎么判断它有没有用?我盯三个指标:
- 采纳率:AI 提出的意见中,被开发者实际采纳的比例。低于 30% 说明误报太多,需要优化。
- 响应时间:从事件触发到 AI 给出结果的时间。超过 5 分钟体验就差了。
- 人工节省:粗略估算 AI 帮团队省下了多少重复劳动时间。这个指标用来向团队证明价值。
这三个指标每周看一次,持续优化。系统不是搭完就完事,而是要像养一个团队成员一样持续调教。
7.4 一个最小可行版本的搭建顺序
如果你现在就想动手,我建议按这个顺序来:
- 先接一个平台的 webhook,能收到事件。
- 写一个最简单的 PR 审查 Agent,只做规范检查(命名、提交信息)。
- 把结果以评论形式发回 PR。
- 收集反馈,逐步增加审查维度。
- 稳定后,再加 Issue 分析 Agent。
- 最后加 CI 排障 Agent 和协调器。
每一步都验证价值后再往下走,不要贪多。我见过太多团队一上来就设计一个宏大的多 Agent 架构,结果卡在第一个 Agent 的提示词调优上,最后不了了之。
这套系统我前后迭代了大半年,从最初的一个脚本,长到现在四个 Agent 协作。回头看,最大的收获不是技术本身,而是理解了AI 在研发流程里的正确位置——它不是替代人,而是把人从重复劳动里解放出来,去做真正需要判断力的事。这个认知,比任何架构设计都重要。