打造更强大的 Bugbot
随着代码 Agent 能力不断增强,我们反而在代码审查上花了越来越多时间。为了解决这个问题,我们构建了 Bugbot,一个代码审查 Agent,会在变更进入生产环境之前,分析 Pull Request 中的逻辑错误、性能问题和安全漏洞。到了去年夏天,它的效果已经足够好,我们决定将它正式发布给用户。
构建 Bugbot 的过程起初依赖定性评估,随后逐步演变为更加系统化的方法,并使用自定义的 AI 驱动指标在质量维度上持续爬坡优化。
自发布以来,我们进行了 40 次重大实验,将 Bugbot 的解决率从 52% 提升到 70% 以上,同时把每个 Pull Request 平均标记出的缺陷数量从 0.4 提升到 0.7。这意味着每个 PR 中被成功解决的 bug 数量从大约 0.2 增加到约 0.5,翻了一倍多。

谦逊的起点
在我们最初尝试构建代码审查智能体时,模型的能力还不够强,生成的审查结果帮助不大。随着基础模型能力提升,我们意识到可以通过多种方式来提升缺陷报告的质量。
我们尝试了不同的模型组合、流水线、过滤器以及一些更巧妙的上下文管理策略,并在过程中不断向内部工程师征求反馈。如果某种配置看起来误报更少,我们就采用它。
我们在早期发现的最有效质量改进之一,是并行运行多次缺陷检测,并用多数投票来合并结果。每一轮检测都会接收一个不同顺序的 diff,这会引导模型采用不同的推理路径。当多轮检测独立标记出同一个问题时,我们就把它视为该缺陷真实存在的更强信号。
经过数周的内部定性迭代,我们最终打磨出一个版本的 Bugbot,它在效果上优于市面上的其他代码审查工具,也让我们对将其推出有了足够信心。它的流程是:
- 使用随机化 diff 顺序并行执行 8 轮检测
- 将相似的缺陷合并到同一个分组中
- 用多数投票过滤掉只在单轮检测中出现的缺陷
- 将每个分组合并为一条清晰的描述
- 过滤掉不需要的类别(例如编译器警告或文档错误)
- 将结果交给验证模型以识别误报
- 与之前运行中已报告的缺陷去重
从原型到生产环境
为了让 Bugbot 在实际场景中真正可用,我们必须在核心审查逻辑之外投入建设一套基础系统。这包括用 Rust 重写我们的 Git 集成并尽量减少获取的数据量,使仓库访问变得快速且可靠,同时加入速率限制监控、请求批处理以及基于代理的基础设施,以便在 GitHub 的各项约束下运行。
随着使用范围不断扩大,各团队也需要一种方式来编码代码库特有的不变量,例如不安全的迁移或对内部 API 的错误使用。对此,我们增加了 Bugbot rules,以支持这些检查,而无需将它们硬编码到系统中。
这些要素结合在一起,使 Bugbot 在真实代码库上既实用又易于适配。但它们无法告诉我们质量是否真的在提升。如果没有用来衡量进展的指标,我们就无法定量评估 Bugbot 在实际环境中的表现,而这也会限制我们能够将其能力提升到什么水平。
衡量真正重要的事情
为了解决这个问题,我们设计了一个名为「解决率」的指标。它在 PR 合并时使用 AI 来判断,在最终代码中作者实际解决了哪些 Bug。在开发这个指标时,我们会与 PR 作者一起在内部对每个示例进行抽样核查,结果发现 LLM 准确地将几乎所有示例分类为「已解决」或「未解决」。
团队经常会问我们如何评估 Bugbot 为他们带来的影响,因此我们在仪表盘中突出展示了这个指标。对于评估效果的团队来说,相比于零散的口头反馈或对评论的反应,这个指标提供的信号要清晰得多。解决率可以直接回答 Bugbot 是否在发现工程师实际会修复的真实问题。

爬山式优化
对“解决率”的定义改变了我们构建 Bugbot 的方式。我们第一次能够基于真实信号而不是主观感觉来做爬山式优化。我们开始在线上用实际解决率、线下用 BugBench 进行评估;BugBench 是一个精心整理的基准集,包含真实代码 diff 以及人工标注的缺陷。
我们围绕模型、提示词、迭代次数、验证器、上下文管理、类别过滤和 Agent 设计等方面运行了数十个实验。出人意料的是,许多改动都让我们的指标下降了。事实证明,我们在早期定性分析中做出的很多初步判断其实是正确的。
Agentic 架构
我们在今年秋天把 Bugbot 切换到完全 Agentic 的设计时,取得了最大幅度的能力提升。Agent 能够围绕 diff 进行推理、调用工具,并自主决定在哪里深入探索,而不是按照固定的多轮检查顺序执行。
Agentic loop 让我们不得不重新思考提示词的设计。在早期版本的 Bugbot 中,我们需要约束模型,以尽量减少误报。但在采用 Agentic 方法后,我们遇到了相反的问题:它变得过于谨慎。于是我们改用更激进的提示词,鼓励 Agent 调查每一种可疑模式,并在标记潜在问题时宁可多报、不错报。
此外,Agentic 架构也为实验打开了更广阔的空间。我们能够把更多信息从静态上下文中抽离出来,放入动态上下文中,控制模型在一开始能获取到的上下文量,并观察它的适应情况。模型会在运行时稳定地自行获取它所需要的额外上下文,而不必事先把一切都喂给它。
同样的设置也让我们可以直接迭代工具集本身。由于模型行为由它可调用的工具所塑造,即便是工具设计或可用性上的微小变化,也会对结果产生巨大的影响。经过多轮迭代,我们不断调整和完善这一接口,直到模型的行为能够持续稳定地与我们的预期对齐。
接下来
目前,Bugbot 每月为 Rippling、Discord、Samsara、Airtable 和 Sierra AI 等客户审查超过两百万个 PR。我们也在 Cursor 的所有内部代码上运行 Bugbot。
展望未来,我们预计会定期推出具有不同优劣势的新模型,既来自其他服务提供商,也来自我们自身的训练工作。要持续取得进步,就需要找到模型组合、执行框架和审查结构之间的最佳搭配。与刚发布时相比,如今的 Bugbot 已经提升了数倍。再过几个月,我们预计它还会有显著提升。
我们已经在为这样的未来做准备。我们刚刚以 Beta 形式发布了 Bugbot Autofix,它会自动启动一个 Cloud Agent 来修复在 PR 审查过程中发现的缺陷。下一阶段的重要能力包括:让 Bugbot 运行代码来验证自己的缺陷报告,以及在遇到复杂问题时进行深入分析和研究。我们也在尝试一种始终在线的版本,让它持续扫描你的代码库,而不是等到收到 pull request 才开始工作。
到目前为止,我们已经取得了长足进展,这离不开一些关键团队成员的贡献,包括 Lee Danilek、Vincent Marti、Rohan Varma、Yuri Volkov、Jack Pertschuk、Michiel De Jong、Federico Cassano、Ravi Rahman 和 Josh Ma。我们共同的目标,始终是帮助你的团队在 AI 开发工作流不断扩展的过程中,持续保持代码质量。
阅读文档 或 立即试用 Bugbot。