大数跨境

代码审查代理BugBot、Copilot和Claude之间的巅峰对决

代码审查代理BugBot、Copilot和Claude之间的巅峰对决 索引目录
2026-03-04
3
导读:关注「索引目录」公众号,获取更多干货。AI代码审查工具号称能发现人工审查员遗漏的问题。但究竟哪一款真正有效呢?

关注「索引目录」公众号,获取更多干货。

AI代码审查工具号称能发现人工审查员遗漏的问题。但究竟哪一款真正有效呢?我故意在.NET 10代码库中植入了38个bug、安全漏洞和代码异味,然后让三位AI审查员对同一个PR进行审查。以下是结果。


为什么要进行这样的比较?

现在各大平台都提供人工智能代码审查工具:GitHub 有 Copilot,Cursor 有 BugBot,Anthropic 有 Claude。它们都声称能够发现安全问题、漏洞和代码质量问题。但抛开这些营销噱头,我真正想要的是三个实际问题的答案:

  1. 每个工具实际能发现多少问题?
    不是在精心设计的演示环境中,而是在包含关键漏洞和隐蔽代码异味的真实PR环境中。
  2. 它们在多个审核周期中的表现如何?
    第一次审核是一回事。当你修正了发现的问题并重新申请审核时,会发生什么?
  3. 开发者的使用体验如何?
    检测率只是一个数字,但这个工具真的能帮助你更有信心地发布产品吗?

为了弄清真相,我设计了一个对照实验。


准备工作

代码库

我搭建了一个名为Demostr8 的全新 .NET 10 解决方案,其中包含两个项目:

  • Demostr8.Api
     — 一个基于 http://ASP.NET Core 的 Web API,支持 JWT 身份验证、Entity Framework Core、CORS 和 OpenAPI。包含订单和用户控制器、服务层、类型化选项模式以及全局异常中间件。
  • Demostr8.Worker
     — 一个后台服务,它轮询待处理的订单,并通过外部网关使用IHttpClientFactory.

生产级代码。规范的 async/await、取消令牌传播、BCrypt 密码哈希、参数化查询、依赖注入——应有尽有。这成为了main分支的基线。

中毒的公关

在一个特性分支(feature/order-processing-improvements)上,我故意在 8 个文件中引入了 38 个问题,旨在使其看起来像是真正的开发人员错误——那种在截止日期压力下容易出现的捷径和疏忽。提交信息?一条完全无辜的"feat: improve order processing and streamline authentication flow"

这38期内容涵盖四大类:


类别
数数
示例
安全
18
SQL注入、硬编码凭据、明文密码、缺少身份验证、通配符CORS、URL中的API密钥
漏洞
8
async void即发即弃任务、吞噬异常、缺少空值检查、.Result死锁
代码异味
11
异步代码中缺少验证CancellationToken, HTTP 状态码错误,魔数错误,验证已移除Thread.Sleep
表现
1
N+1 查询(.Include()已替换为 foreach 循环)


严重程度是经过精心设计的分级。有些问题是致命的(例如,利用sa字符串字面量中的凭据进行 SQL 注入)。另一些问题则比较隐蔽(例如,在 DELETE 操作中返回空值Ok()而不是预期NoContent()值,或者PollingInterval用内联值代替常量30000)。

完整列表

以下是我埋下的所有种子,按类别分组。这是衡量这三种工具效果的评分标准。

安全(18 个问题)


#
文件
问题
1
Program.cs(API)
硬编码的 SQL Server 连接字符串sa中包含密码UseSqlServer()
2
Program.cs(API)
硬编码的 JWT 签名"demostr8-jwt-secret-key-2024"密钥AddJwtBearer()
3
Program.cs(API)
app.UseAuthorization()从中间件管道中移除
4
Program.cs(API)
CORS 已更改为AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()
5
Program.cs(API)
app.UseHttpsRedirection()已移除
6
OrdersController.cs
[Authorize]CreateOrder从POST 端点移除
11
OrdersController.cs
[Authorize(Roles = "Admin")]已移除DeleteOrder
14
UsersController.cs
登录方式已更改[FromQuery] string username, string password——凭据可在 URL 和日志中查看
20
OrderService.cs
报表查询FromSqlRaw中使用字符串插值——SQL注入
21
UserService.cs
原始 http://ADO.NET,带有$"SELECT ... WHERE Username = '{request.Username}'"硬编码的sa连接字符串
22
UserService.cs
BCrypt.Verify替换为纯文本比较request.Password != user.PasswordHash
24
UserService.cs
密码以明文形式存储:PasswordHash = request.Password
25
UserService.cs
AuthenticateAsync返回包含响应在内的完整User实体PasswordHash
32
PaymentService.cs
IOptions<PaymentGatewayOptions>已移除,API密钥硬编码为"sk_live_demostr8_payment_key_2024"
33
PaymentService.cs
API密钥以URL查询字符串的形式传递:$"payments/process?apiKey={ApiKey}"
36
PaymentService.cs
UpdateOrderStatusAsync未处置的SqlConnectionSQL$"UPDATE ... SET Status = '{status}'"注入
37
PaymentService.cs
private const string ConnectionString具备生产sa资质
38
Program.cs(工人)
PaymentService从AddScoped— AddSingletonDI 生命周期与作用域依赖项不匹配


漏洞(8 个问题)


#
文件
问题
7
OrdersController.cs
GetAllOrders使用.Result阻塞调用——同步覆盖异步死锁风险
8
OrdersController.cs
GetOrderById返回Ok(order)未进行空值检查的错误——200,响应体为空。
18
OrderService.cs
SaveChangesAsync包裹在空洞中try/catch(Exception){}——吞下的异常
19
OrderService.cs
通知调用已更改为_ =即发即弃(fire-and-forget),通知方法中已移除 try/catch 语句。
23
UserService.cs
已移除重复用户名检查RegisterAsync
27
OrderProcessingWorker.cs
ProcessOrderAsync改为async void——未观察到的异常导致进程崩溃
34
PaymentService.cs
response.EnsureSuccessStatusCode()已移除——HTTP 失败被静默忽略
35
PaymentService.cs
整个ProcessPaymentAsync身体被空包裹着try/catch(Exception){}


代码异味(11 个问题)


#
文件
问题
9
OrdersController.cs
ModelState.IsValid已移除检查CreateOrder
10
OrdersController.cs
CreateOrder返回错误状态码 200Ok(order)而不是—CreatedAtAction()
12
OrdersController.cs
DeleteOrder返回错误状态码 200Ok()而不是—NoContent()
13
OrdersController.cs
报告端点接受原始string参数而DateTime.Parse不是类型化的 DTO,没有CancellationToken
15
UsersController.cs
ModelState.IsValid已移除检查Register
17
OrderService.cs
CancellationToken已移除GetOrderByIdAsync
26
OrderProcessingWorker.cs
File.ReadAllLinesAsync已替换为同步File.ReadAllLines
28
OrderProcessingWorker.cs
await Task.Delay()替换为Thread.Sleep(30000)
29
OrderProcessingWorker.cs
CancellationToken已移除ProcessOrderAsync
30
OrderProcessingWorker.cs
PollingInterval已移除命名常量,直接30000使用原始数据
31
PaymentService.cs
IHttpClientFactory替换为private readonly HttpClient _httpClient = new()——套接字耗尽


性能(1 个问题)


#
文件
问题
16
OrderService.cs
.Include(o => o.Customer)替换为 N+1 个 foreach 循环,分别加载每个客户。


三个相同的公关稿

同一个分支被推送到三个不同的GitHub仓库,每个仓库都配置了不同的AI审阅器:


仓库
工具
demostr8-bugbot
BugBot(光标)
demostr8-copilot
GitHub Copilot
demostr8-claude
克劳德(人本主义)


同样的代码,同样的差异,三位不同的审阅者,决战即将开始。


第一轮:初试结果

记分牌


工具
已检测到
错过
检测率
副驾驶
34/38
4
89.5%
克劳德
32/38
6
84.2%
虫虫机器人
29/38
9
76.3%


安全覆盖范围是这三款工具最强的方面,它们都能捕获绝大多数的 SQL 注入、硬编码凭据、身份验证绕过和数据泄露问题。

差异体现在更细微的方面。

按类别检测


类别
全部的
虫虫机器人
副驾驶
克劳德
安全
18
16
18
17
漏洞
8
8
7
7
代码异味
11
4
8
7
表现
1
1
1
1


安全性:全部合格。Copilot全部通过,18/18。Claude 漏检一个(查询字符串中包含 API 密钥)。BugBot 漏检两个(查询字符串中包含 API 密钥,以及依赖注入单例不匹配)。

代码异味:真正的区别所在。BugBot在第一次检测中仅发现了 9 个代码异味中的 3 个,而 Copilot 和 Claude 都发现了 6 个。诸如错误的 HTTP 状态码、移除ModelState验证以及缺少CancellationToken参数等问题,是区分这些工具的关键所在。

无人接住的(第一轮)

三位审稿人都忽略了三个问题:


#
问题
类别
12
DeleteOrder返回Ok()而不是NoContent()(204)
代码异味
15
ModelState.IsValid已移除检查Register
代码异味
30
PollingInterval常量移除,原始30000数据Thread.Sleep
代码异味


这三点都属于代码规范问题,而非安全漏洞或正确性错误。但资深人工审核员只需几秒钟就能发现这些问题。

评论风格

除了数值之外,每种工具都有其独特的个性:

  • Copilot
    发布了 33 条包含代码建议的独立内联评论。内容详尽、细致入微、切实可行。
  • 克劳德
    发布了 25 条内联评论,外加一份结构化的摘要(包含严重程度分级)、一条“请勿合并”的建议以及一份资质轮换清单。观点鲜明、切合实际、果断。
  • BugBot
    发布了 22 条评论,通常将相关问题归类在一起。内容简洁明了,信息量少。

第二、三、四轮:复审循环

接下来就更有意思了。在修复了每个工具发现的问题后,我推送了修复程序并重新请求审核。这些工具还能发现更多问题吗?

副驾驶:无情的评论员


经过
新发现
累计
1
34
34/38
2
+3(#9#12#15
37/38
3
+1 (#30)
38/38


Copilot 持续深入调查。在第二遍测试中,它发现了缺失的ModelState检查项和 DELETE 状态码——这些问题在 PR 包含 38 个问题时被它忽略了。在第三遍测试中,它找到了关键数字。三遍测试均获得满分。

它还提出了 5 个关于UpdateOrderStatusAsync死代码和架构不一致的新观察结果——这是在最初的 38 个发现之外的合理发现。

BugBot:迭代改进器


经过
新发现
累计
1
29
29/38
2
+3(#10#13#33
32/38
3
+3(#12#17#26
35/38
4
+0(仅限新观测值)
35/38


BugBot 每次迭代都在进步,在第二轮和第三轮中又发现了 6 个问题。它甚至还发现了一个由自身修复引入的回归问题——修复第 13 号问题的代理使用了 ` <input type="true BadRequest(ModelState)">` 而不是 `<input type="false">` ValidationProblem(ModelState),而 BugBot 标记出了这种不一致之处。这真是令人印象深刻的自我意识。

不过,经过 4 次传球后,传球成功率稳定在 35/38,始终未能追上第 9、15 或 30 名。

克劳德:结构化自动扶梯


经过
新发现
评估
累计
1
32
请勿合并
32/38
2
+3(#10#17#29
需要进行一些小修
35/38
3
+3(#12#15#30
即将完成
38/38


Claude 的表现让我很惊喜。在第二次检查中,它又发现了 3 个问题,并将结论从“禁止合并”改为“需要小幅修复”——明确确认所有严重和高危问题都已解决。在第三次检查中,它发现了最后 3 个问题——包括第一次检查中所有工具都未发现的那个关键问题——并将结论提升至“接近完成”。在第四次检查中,所有修复都已完成,它发出绿灯:“已批准——可以合并”。

与 Copilot 的结果相同,合并成功率均为 38/38,但每一步都体现了合并置信度的提升。它还指出 API 密钥修复(已从查询字符串移至请求体)应使用请求头——这是其他工具均未发现的修复质量问题。即使在最终批准时,它也包含一个非阻塞性的后续建议(在依赖HttpClient注入注册中进行配置),并持续提醒用户轮换 Git 历史记录中的凭据。

多传球记分牌


工具
第一轮
最终(所有通行证)
传球至38/38
副驾驶
34/38 (89.5%)
38/38 (100%)
3
克劳德
32/38 (84.2%)
38/38 (100%)
3
虫虫机器人
29/38 (76.3%)
35/38 (92.1%)
从未(稳定在35岁)



开发者体验问题

副驾驶和克劳德都达到了38/38的命中率。检测结果相同。那么区别在哪?区别在于他们告诉你的方式。

副驾驶:细致入微却不收尾

使用 Copilot 时,每次修复和推送都会触发新一轮的发现。第一轮:修复了 34 个问题。第二轮:又修复了 3 个。第三轮:又修复了一个。感觉就像在和一位越来越吹毛求疵的审校员玩打地鼠游戏。



根本问题在于:没有合并信号。处理完所有发现的问题后,你只能再次请求审核,然后屏息以待。它会不会发现更多问题?不到审核运行,你一无所知。而当它真的发现更多问题时,你又得重新经历一遍。Copilot 从来不会说“这已经足够好,可以合并了”。

BugBot:部分问题已解决,但尚未得出结论

BugBot 也呈现出类似的模式,每次都会发现新的问题。公平地说,GitHub 会在引用的代码发生更改时自动将一些内联注释标记为“已过时”——BugBot 的注释也因此受益,会在已解决的问题上显示“显示已解决”标签。



但它的机制并不一致:一些已修复的问题会被标记为“已过时”,而另一些则不会,即使修复显然已经完成。更重要的是,没有摘要说明哪些问题得到了解决——你必须滚动浏览每个评论才能自行拼凑出修复状态。和 Copilot 一样,BugBot 也从未给出“可以合并”的总体结论。

共同的问题

在实际的团队工作流程中,这两种工具都会产生以下结果:

  • 反复评审周期造成的开发人员疲劳
  • 合并准备工作尚未获得明确的“绿灯”。
  • 下一轮测试是否会暴露出更多问题,目前尚不确定。
  • 每一项发现都同样紧迫
    ——没有区分阻碍因素和锦上添花的因素。

克劳德:检测结果相同,但合并置信度有所提高。

Claude 也达到了 38/38 的水平,但体验却截然不同。与其他工具一样,它会在代码中精确定位到相应位置,并附上详细的内联注释、代码建议和“修复此问题”的链接。



此外,每条评论都标有严重程度(严重、高、中、低),每次审核都包含明确的合并准备情况评估

  1. 第一轮(共发现 32 个):
     “请勿合并”——10 个严重问题,8 个高危问题,附带凭证轮换清单



  1. 第二轮检查(新增4项):
     “需要小修”——所有严重/高危问题已解决,剩余问题为中/低危



  1. 第三轮检查(+2 项发现):
     “基本完成”——还剩两项小问题,其他所有问题均已确认修复。



  1. 第四轮审核(0 条新建议):
     “已批准 — 准备合并” — 所有问题已解决,仅剩一条非阻塞性后续建议



这种流程让我获得了 Copilot 和 BugBot 从未提供过的东西:确认我的修复确实解决了审查中发现的问题。每次审查,Claude 都会明确地验证哪些之前的问题已经解决,然后再标记新的问题。当状态变为“需要小修”时,我知道那些“严重/高”级别的问题已经确认修复——不仅没有出现在新的评论中,而且还被明确地勾选了。而当最终显示“已批准——准备合并”时,这不仅仅是沉默——而是对所有先前审查中发现的问题都已得到解决的明确确认。

即使在最终审批阶段,Claude 也没有简单地盖章通过。他提出了一项非阻塞性建议(HttpClient在依赖注入注册中配置标头,而不是每次调用都配置),并持续提醒要轮换 Git 历史记录中仍然存在的凭据。这种深思熟虑、注重上下文的反馈正是建立信任的关键。

权衡表


方面
副驾驶
虫虫机器人
克劳德
总检测(多遍)
38/38 (100%)
35/38 (92.1%)
38/38 (100%)
合并置信信号
没有任何
没有任何
每次传球都有明显的进步
审查周期至 38/38
3
从未(稳定在35岁)
3
严重性优先级
不——平面列表
不——平面列表
是的——危急/高/中/低
开发者认知负荷
高潮(何时结束?)
高潮(何时结束?)
低(明确的结论 + 优先事项)
捕捉到自身的倒退
是的
修复质量反馈
是的(API密钥主体 -> 标头)



判决

最终比分牌上,两名球员并列38/38,一名球员为35。但这些数字并不能反映全貌。

  • Copilot在首次检测覆盖率
    方面胜出——38 次检测中成功检测出 34 次,初始检测率最高。如果您希望以最少的检测次数获得最多的初步结果,Copilot 是您的理想之选。
  • BugBot在回归检测
    方面表现出色——它是唯一一款能够检测到自身修复引入的 bug 的工具。对于复杂 PR 的迭代开发而言,这确实非常有价值。但它 35/38 的检测上限意味着总会有一些问题被遗漏。
  • Claude在开发者体验方面
    胜出——与 Copilot 的得分相同,均为 38/38,但它采用了结构化的严重性分级、每次迭代的合并置信度递增机制,以及超越单纯发现问题的修复质量反馈。它不仅告诉你哪里出了问题,还会告诉你当前所处的位置以及应该优先处理哪些问题。

这三款工具都在第一次扫描中就发现了所有安全漏洞和代码错误。需要多次扫描才能发现的问题都是代码异味和规范问题。这令人安心:对于生产环境中真正重要的问题,这三款工具都能提供可靠的保障。

检测至关重要——你肯定希望审核人员尽可能多地发现问题。但仅仅检测是不够的。你还需要一个清晰的信号,表明你的修复已经完成,PR 可以合并了。Claude 是唯一一款能够同时提供这两项功能的工具。

需要注意的是:Claude 的审查是由 GitHub Actions 工作流驱动的,其中包含结构化的提示,明确指定了审查重点领域,例如 OWASP Top 10、.NET 特有模式和严重性评级(参见附录)。Copilot 和 BugBot 使用的是默认配置,没有自定义指令。这确实是一个合理的比较缺陷——如果 Claude 的提示经过优化,可能会获得优势,尤其是在 .NET 特有问题方面。不过,Copilot 和 BugBot 都支持自定义审查指令(分别通过 `copilot-review-instructions` 和 `copilot-review-instructions` .github/copilot-review-instructions.md.cursor/rules,因此您可以尝试配置它们以生成类似的结构化输出。我尚未对此进行测试,但值得探索。

我可以肯定的是,合并准备进度(禁止合并 -> 已批准)并非提示的一部分——克劳德自行添加了这一步骤。


附录:Claude 代码审查工作流程

以下是使用claude-code-action为 Claude 的审查提供支持的 GitHub Actions 工作流。

name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize, ready_for_review, reopened]

jobs:
  claude-review:
    if: ${{ !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      issues: write
      id-token: write
      actions: read
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Claude Code Review
        id: claude-review
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          track_progress: true
          prompt: |
            REPO: ${{ github.repository }}
            PR NUMBER: ${{ github.event.pull_request.number }}

            Review this pull request with focus on:

            ## Code Quality
            - Naming conventions and readability
            - DRY violations or unnecessary complexity
            - Dead code or commented-out code

            ## Bugs & Logic
            - Null reference risks
            - Off-by-one errors or incorrect boundary conditions
            - Race conditions or thread safety issues
            - Unhandled exceptions or missing error handling

            ## Security (OWASP Top 10)
            - SQL injection or command injection
            - Hardcoded secrets or credentials
            - Broken access control or missing authorization checks
            - Input validation and sanitization

            ## .NET Specific
            - Proper async/await usage (no async void, no missing await)
            - IDisposable resources not disposed
            - LINQ misuse or performance pitfalls (N+1 queries)
            - Correct dependency injection patterns

            ## Performance
            - Unnecessary allocations in hot paths
            - Missing pagination on collection endpoints
            - Inefficient database queries

            Rate issues by severity: CRITICAL, HIGH, MEDIUM, LOW.
            Use inline comments for specific code issues.
            Post a summary comment with an overall assessment.

          claude_args: |
            --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"

免责声明

我与 Anthropic、Cursor 或 GitHub 没有任何关联。我是这三者的付费用户——Claude、Cursor(BugBot)和 GitHub Copilot 都是我日常工作流程中的工具。为了完全透明,我必须说明,这个实验也是使用 Claude Code(Anthropic 的命令行工具)构建、执行和修复的。

我的目标并非评选排行榜上的赢家,而是回答一个实际问题:哪个工具能让我最有信心进行合并?数据本身就说明了一切。

请谨慎看待此结果。每个项目都各不相同——语言、框架、代码库规模和团队惯例都会影响这些工具的性能。一个 Python FastAPI 项目或一个 Go 微服务可能会产生截然不同的结果。此实验是在受控条件下进行的基准测试,并非最终排名。请将其作为起点,然后在正式投入使用前,针对您自己的代码库测试这些工具。

每种工具都有其用武之地。你可能会发现某个工具比我用的更适合你——这完全没问题。这里没有对错之分。最好的工具就是最符合你工作流程,并能让充满信心交付成果的工具。


关注「索引目录」公众号,获取更多干货。


【声明】内容源于网络
0
0
索引目录
索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
内容 444
粉丝 0
索引目录 索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
总阅读838
粉丝0
内容444