尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

多智能体架构如何让AI代码审查从提示词走向产线

多智能体架构如何让AI代码审查从提示词走向产线 做 AI 代码审查这件事几乎每个团队都走过同一条路先拿大模型写个提示词把 MR 的 diff 贴进去让模型“看看有什么问题”demo 效果惊艳得不行觉得上线只是时间问题可真把它挂到 CI 上每天面对几百上千个变更请求问题就全冒出来了——上下文不够用、误报率高到没人看、意见没法解释、token 成本还压不住。LinkedIn 团队把这条路真正走通的方式是把“单条万能提示词”升级成一套多智能体系统规划器拆解任务多路专职 agent 并行审查聚合器合并结果再用 RAG 从代码库里精准捞上下文。这篇文章就顺着“从提示词到产线”这条主线把 LinkedIn 这套多智能体代码审查的设计思路、关键实现和落地经验拆开讲清楚也聊聊一个普通团队能从中直接借鉴哪些东西。1. 为什么单条提示词搞不定代码审查1.1 代码审查不是“找错”是多维判断的组合很多人对代码审查的理解是“找 bug”但真正做过 review 的人都明白一次合格的审查至少包含六个维度功能正确性、并发安全、安全漏洞、性能风险、可维护性、测试覆盖甚至还有 API 兼容性和风格一致性。这里面每一个维度需要的知识都不一样侧重的代码上下文也不一样。安全审查要盯着输入校验、鉴权逻辑、加密存储并发审查要关注共享状态、锁的粒度、线程安全问题性能审查要看循环复杂度、数据库查询次数、是否在热路径上做了重活。你把所有这些塞进一句“请 review 这个 diff”模型大概率只会给出一些泛泛的、显而易见的意见——比如“这里缺少空指针检查”“建议使用常量代替魔法数字”真正的深层问题一个都抓不到。这里有个很直观的类比单提示词方案就像是让一个全科医生只看化验单不给他病历、不给既往史、不给用药记录他最多只能说“指标偏高建议复查”根本做不了精准诊断。代码审查天然需要的是会诊而不是一位医生拍脑袋下结论。1.2 diff 只是表象上下文才是关键第二个被低估的问题是diff 本身的信息量非常有限。一次真实的代码变更改的可能只有 50 行但这 50 行调用了一个 2000 行的模块改了某个被 30 处引用的公共函数还涉及一张数据库表的字段变更。如果只看 diff模型根本不知道这个函数被谁调用、修改是否会破坏下游行为。我在实际调试这类系统时发现模型给出的“正确性意见”里至少有三成是因为缺少跨文件上下文才产生的误报或漏报。比如模型说“这个函数没有处理空值”实际上调用方在上游已经做了非空断言模型说“这里可能死锁”实际上锁的获取顺序在别处已经统一。没有上下文再聪明的模型也是在信息不全的情况下强行推理。LinkedIn 的代码库是典型的 monorepo 加微服务混合形态一个变更牵涉的上下文经常散落在十几个文件里全局符号依赖复杂。单条提示词方案在这里根本撑不住这也是他们转向多智能体架构的直接动因。1.3 产线上还有三座大山可解释、延迟、成本就算单条提示词在离线 demo 上效果不错真正上线还要面对三个现实约束。第一是可解释性。开发者看到一条 AI 审查意见第一反应不是“它对不对”而是“它为什么这么说”。没有依据的意见在 demo 里可以忽略但在产线上会消耗大量人工时间。第二是延迟。每个 MR 都要在合理时间内返回结果如果一次审查要 5 分钟开发者根本不会等。第三是成本。每天几百个 MR每个 MR 塞一个超长 prompt 调用大模型账单会非常难看。这三座大山决定了一个事情AI 代码审查在产线上不能是“一个模型一把梭”必须是一个可编排、可解释、可控制成本的系统。多智能体架构正是冲着这个方向去的。2. 多智能体架构的核心设计2.1 一个审查任务如何拆成多个角色LinkedIn 公开分享的做法里最有价值的不是某个具体的提示词而是角色拆分这件事。他们把一次代码审查拆成了三类角色规划器Planner先读 diff理解这次变更想干什么判断需要哪些审查维度决定检索哪些代码上下文然后把任务分发给下游。专职审查 agent比如正确性审查、安全审查、性能审查、可维护性审查。每一路 agent 只负责一个维度各看各的上下文各出各的结论。聚合器Aggregator收集所有 agent 的输出去重、排序、合并最后生成一条结构化的 review 评论。为什么这么拆核心逻辑是职责隔离。每个 agent 的提示词可以做得非常聚焦上下文需求也更明确模型就不用再“既要又要”。你让一个安全 agent 只盯输入校验和鉴权逻辑它就不会被代码风格问题带偏你让一个并发 agent 只盯锁和共享状态它就不会浪费上下文在读业务逻辑上。这跟外科手术是一个道理不是一位医生从头做到尾而是主刀、麻醉、器械护士各管一摊。职责越清晰出错的概率越低出了问题也越容易定位是哪一环的锅。2.2 规划器的工作机制规划器是整个系统的路由中枢它要解决的第一个问题是这次变更到底需要哪些审查维度实际操作中这个决策是规则和模型混合完成的。规则部分很简单根据 diff 的元信息做初步路由比如文件路径包含payment、auth、security之类的关键词就强制拉起安全审查 agent变更涉及pom.xml、package.json这类依赖文件就加上依赖兼容性检查纯前端样式改动就没必要跑性能 agent。规则之外规划器还可以让模型对 diff 做一次轻量级的意图理解输出一个结构化结果变更类型、影响模块、风险等级、建议审查维度列表。这一步用的模型可以很小、很快因为它不需要深入推理只需要做粗粒度的分类。规划器要解决的第二个问题是检索计划。它需要根据 diff 里出现的符号引用——函数名、类名、全局变量、数据库表名——决定哪些文件要完整拉取哪些文件只需要摘要哪些调用关系需要追踪。这一步直接决定了后面每个 agent 拿到的上下文质量是整个系统里最吃工程功夫的部分。2.3 RAG 上下文构建每个 agent 拿自己那份“病历”多智能体架构下RAG检索增强生成的意义和单模型场景完全不同。单模型场景里RAG 的目标是“尽量把有用的东西都塞进上下文”多智能体场景里RAG 的目标是“每个 agent 只拿到自己需要的、最相关的上下文”。LinkedIn 的做法大致可以理解为三个检索来源代码库检索根据 diff 中的符号引用找到相关定义、调用点和被影响的模块。比如某个公共函数被改了签名就要把它的全部调用点检索出来让正确性 agent 判断调用方是否被破坏。历史检索检索类似 bug 的历史修复记录、相关 MR 的讨论、代码 blame 信息。这能帮助 agent 理解“这个改动为什么会存在”“之前踩过什么坑”。知识库检索团队内部的架构规范、安全基线、最佳实践文档也可以作为上下文注入让 agent 的审查标准跟团队约定对齐。检索完成之后还要做一步非常重要的事构建上下文包。每个 agent 有独立的 token 预算检索结果要按相关度排序超出预算的部分要么截断、要么用摘要替换。这里有一个我踩过很深的大坑上下文不是越多越好。你把一堆弱相关的文件塞进去模型反而会被噪声干扰给出更多误报。上下文构建的本质是“在信息完整度和噪声控制之间取平衡”。3. 提示词在智能体里的真实角色3.1 提示词的定位变了从“万能咒语”到“职责说明书”很多团队做多智能体系统时有个误区觉得提示词还是那个“灵魂”于是每个 agent 的提示词都写得又长又华丽。实际运行下来你会发现提示词在多智能体系统里的角色已经从“驱动模型发挥创造力”变成了“约束模型不要越界”。每个专职 agent 的系统提示词应该包含四块内容身份说明、职责边界、输入输出格式、禁止事项。举个例子安全审查 agent 的提示词里会明确写“你只关注安全相关问题不评论代码风格、不评论性能、不评论业务逻辑”这样能最大程度减少各 agent 之间的输出重叠降低聚合器的处理压力。禁止事项这部分特别容易被忽略但它的价值不亚于正向引导。我在实践中会明确写“不要建议重构整个模块”“不要基于未提供的上下文做假设”“不要重复 diff 中已经很明显的简单问题”。这些约束能显著降低低质量输出的比例。3.2 结构化输出是聚合器能工作的前提如果说提示词是约束那么输出格式就是契约。多智能体系统里聚合器要处理多个 agent 的返回结果如果每个 agent 都返回一大段自然语言聚合器做起来会非常痛苦又要解析、又要去重、又要判断优先级最后还是乱的。正确的做法是给每个 agent 强制结构化输出。比如用 JSON schema 定义审查意见的格式{ severity: warning, category: concurrency, file: order_service.py, line_start: 142, line_end: 148, title: 共享计数器存在竞态条件风险, explanation: counter 的递增操作没有加锁多个工作线程同时执行时可能丢更新。, suggestion: 使用 AtomicInteger 或加锁保护该操作。, confidence: high, evidence: [ order_service.py:138 处定义了共享变量, order_service.py:142 处在多线程路径中被调用 ] }结构化输出的价值非常直接聚合器可以做精确去重按文件加行号加类别、按 severity 排序、映射到具体的代码行甚至可以自动把 JSON 转成 GitHub 或 GitLab 的 review comment。如果让 agent 返回散文聚合器还得再用一次模型去“理解”成本和错误率都上去了。3.3 遏制幻觉的几条硬规则AI 代码审查最怕的不是漏报而是幻觉——模型言之凿凿地指出一个根本不存在的问题或者引用一个不存在的 API。防幻觉不能靠提示词里写一句“请不要胡说”要靠机制设计。我在系统里强制了三条规则。第一每条审查意见必须引用具体的证据比如具体的文件路径、行号、调用的函数名没有证据的意见直接标记为low_confidence。第二当模型检索不到的相关上下文时必须明确写“未在提供的上下文中找到相关定义”而不是猜测。第三置信度低于阈值的意见默认只在人工展开时显示不直接作为正式 review 评论发出去。这三条规则单独看都不复杂组合起来效果非常明显产线上展示给开发者的意见几乎都有据可查开发者不再需要追着问“你到底在哪看到的问题”。4. 从原型到产线的落地细节4.1 先建回归集别急着上线多智能体系统比单提示词方案复杂得多可调的东西也多每个 agent 的提示词、检索策略、上下文预算、置信度阈值、聚合规则。这么多旋钮如果没有评估基准你根本不知道动哪个旋钮会产生什么影响。LinkedIn 这类团队的做法是先从真实 review 历史里抽一批 MR 出来人工标注构建离线回归集。数量不用特别多两三百个代表性样本起步就够用但覆盖度要足够不能全是简单 bug得有大文件变更、跨模块调用、历史遗留问题。回归集建好之后定义三个核心指标精确率AI 提出的意见里有多少是真实的、召回率真实存在的问题里 AI 抓到了多少、噪声率开发者需要花时间处理的无效意见占比。之后每次改提示词、改检索策略、改阈值先在回归集上跑一遍对比指标变化再决定要不要上产线。这个过程看起来笨但它是多智能体系统能持续迭代的基石。4.2 灰度上线建议模式先行就算离线指标很好看直接全量上线也是危险的。我发现最稳妥的路径是分三阶段灰度。第一阶段是纯建议模式。AI 跑完审查后只在 MR 页面发评论明确标注“AI 生成的建议请人工确认”不做任何阻塞。这个阶段的核心目标是收集开发者反馈——每条评论下放一个“有用/没用”的按钮或者让开发者评论“误报”。第二阶段把收集到的反馈数据回流到回归集负反馈多的意见类别单独分析针对性收敛提示词或阈值。第三阶段当精确率达到团队接受的标准之后再把它接入 CI作为可选的检查项但仍然不阻塞合入。我见过不少团队在第一阶段就急着开阻塞结果开发者在评论区炸锅、直接关闭 AI 功能。产线稳定比自动化程度重要得多这个顺序不能省。4.3 成本与延迟控制多智能体的命门多智能体系统的最大软肋就是成本一路审查变四路审查token 消耗翻倍是保守估计。如果不做控制上线第一天账单就会让你怀疑人生。这里总结一些我实测有效的控制手段手段具体做法收益分级模型简单 diff 用小模型复杂 diff 才上最强模型显著降低成本token 预算每个 agent 限定上下文上限超出部分截断或摘要控成本、降延迟结果缓存diff 哈希 检索结果的 embedding 缓存减少重复计算并行执行多路 agent 并行跑聚合器最后合并压降 p95 延迟按需路由规划器判定不需要的维度直接跳过省整条链路开销延迟方面多智能体架构有一个天然优势各路 agent 之间没有依赖可以完全并行整体耗时不再是链路累加而是最慢那一路 agent 的耗时。实际跑下来p95 延迟比单模型超长 prompt 方案反而更低。4.4 可信度设计与人工兜底AI 代码审查上线之后最容易出现的问题不是“AI 错了”而是“开发者和 AI 吵起来了”。这里有一个原则我建议所有团队都坚持AI 永远只是辅助意见不自动合入不自动阻塞不与人工 reviewer 平权。具体怎么做每条 AI 评论头部加一句“AI generated suggestion, please review carefully”。当 AI 意见与人工 reviewer 意见冲突时以人工为准但要把这个冲突记录下来作为评估数据回流。人工 reviewer 对 AI 的纠正是系统迭代最宝贵的燃料一定要让它进到 eval 集里下次才能避免同类错误。5. 常见问题与排查技巧实录5.1 误报率高先查职责边界别急着骂模型误报是 AI 代码审查最常被抱怨的问题但我在实际排查中发现误报很多时候不是模型不够聪明而是职责边界没划清。比如安全 agent 在评论里顺便提了代码风格问题或者正确性 agent 在没有完整上下文的情况下强行下结论。排查路径建议三步走。第一步按 agent 维度拆误报率看是哪一路 agent 拖后腿。第二步点开那路 agent 的完整输入看它到底基于什么做出了错误判断——是上下文缺失还是提示词里的约束不够明确。第三步针对具体原因做收敛而不是笼统地“改一版提示词碰运气”。还有个细节技巧给每类问题设置独立的置信度阈值。安全相关的意见可以放宽阈值多展示风格相关的意见收紧阈值宁可少说也不能天天刷屏。5.2 检索不到上下文先查证据日志再查索引症状很典型agent 说“未找到函数定义”但你手动一搜函数明明就在隔壁文件躺着。这种情况八成是检索链路出了问题。我建议从三个方向排查。第一代码库索引是否过期——文件刚被重命名或移动过索引没跟上。第二符号解析是否失败——diff 里引用的函数是动态导入的或者通过依赖包间接引入静态解析找不到。第三上下文包构建是否截断——检索结果确实选上了但在组装时因为 token 预算超限被截掉了。这里有一个我踩坑之后养成的习惯每一步检索都写证据日志把“检索了哪些符号、命中哪些文件、最终组装进上下文包的有哪些”全部记录下来。出问题时直接回放日志五分钟就能定位是哪个环节丢的上下文。没有这个日志排查这类问题全靠猜效率极低。5.3 聚合器把好建议弄丢了多路 agent 并行之后聚合器这个环节看起来最简单实际最容易出幺蛾子。典型问题是去重逻辑太粗暴两个 agent 从不同角度提到同一个文件同一行的两个不同问题被聚合器当成重复意见合并成一条丢掉了一半信息。我的经验是聚合器不要做“重新理解”只做“合并与排序”。去重用确定性规则——文件加行号加类别三个字段完全一致才算重复排序用 severity 加 confidence冲突意见同一个位置两条互相矛盾的建议保留两条不自动裁决。聚合器一旦尝试“理解”内容它就会成为新的误报源。5.4 加了 agent 反而更差警惕职责重叠最后一个常见问题很有意思团队把 agent 从三个加到六个结果整体效果不升反降。原因几乎都是职责重叠。正确性 agent 和性能 agent 都在看循环代码安全 agent 和正确性 agent 都在看空值校验同一类问题被重复提出开发者看到的就是一堆自相矛盾的噪声。多智能体架构的铁律是每个 agent 必须有一个独占的审查维度。加 agent 之前先问一句这个新维度现有 agent 覆盖不了吗如果答案是想覆盖但覆盖得不好优先优化现有 agent而不是再加一路。5.5 问题速查表现象可能原因排查手段对策误报集中在某类问题职责边界不清或阈值过宽按 agent 和类别拆误报率独立阈值 提示词收敛agent 说找不到定义索引过期或检索截断回放检索证据日志更新索引、扩大检索范围聚合结果信息丢失去重逻辑误判核对聚合前后输出用确定性字段去重加了 agent 效果变差职责重叠对比各路输出类目保持维度独占开发者反馈“没用”意见太泛、无证据检查意见是否带行号和依据强制证据引用6. 普通团队能直接抄的部分6.1 最小可用版本两路 agent 起步看到多智能体架构很容易觉得这是个昂贵的大工程但普通团队完全可以做一个简化版先跑起来。我的建议是最小可用配置正确性审查加安全审查两路 agent加一个规则去重的聚合器再用 RAG 把 diff 涉及的符号引用检索出来作为上下文。编排层不一定要上复杂的框架用 LangGraph 或者自己写一个几十行的调度脚本都可以。关键是把规划、执行、聚合三件事分清楚而不是把所有逻辑糊在一个循环里。最小版本跑通之后再根据实际反馈逐步增加审查维度每一次增加都要有明确的目标和评估依据。6.2 三个可以直接复用的经验第一个经验提示词和 eval 集要绑定迭代。改一条提示词就是改一次评估规则不要“凭感觉优化 prompt”。每次提示词改动都对应一个回归集上的指标变化这样系统的每一次进步都是可追溯的。第二个经验多智能体的价值来自职责拆分不是 agent 数量。两路边界清晰的 agent 效果远好于六路互相重叠的 agent。判断架构好坏的第一标准是“每一路的职责是否独占”而不是“看起来多智能”。第三个经验产线效果取决于反馈闭环不是一次性 demo 指标。开发者每次点“没用”、每次人工修正 AI 意见都是系统迭代的燃料。把这个闭环建起来系统会越跑越准没有闭环再好的初始效果也会在一堆噪声中被开发者主动屏蔽。6.3 不适合上多智能体的场景也不是所有团队都适合一上来就搞多智能体。团队很小、代码审查频率很低一套单 agent 加 RAG 的方案可能就够了对延迟极其敏感的场景多路并行带来的架构复杂度可能超过收益连基础的静态检查都没跑起来的团队先别急着上 AI 审查把 lint 和编译告警清干净收益反而更大。多智能体架构是手段不是目的。判断标准只有一个它是否帮你把代码审查这件事做得更准、更快、更省人力。最后说点我自己的体会。我照着这条思路做过内部的简化版本踩得最深的坑不是模型不给力而是上下文构建检索做不好agent 数量越多越混乱。后来我给每一步都加上证据日志哪个 agent 基于哪些文件、哪些检索结果得出什么结论全部可回放系统才真正从“看起来厉害”变成“可维护”。多智能体不是银弹但它确实是 AI 代码审查从提示词玩具推向产线的合理路径——前提是你愿意把工程精力花在 eval、检索和反馈闭环上而不是沉迷于调花哨的 prompt。
返回列表