当前位置:首页 > 文章 > 正文内容

我给GPT-5.5喂了10万行代码,它发现了我两年没发现的Bug

廖万里4小时前文章1

我给GPT-5.5喂了10万行代码,它发现了我两年没发现的Bug

我有一个维护了两年的 Python 后端项目,大概 10 万行代码。两年里自认为代码质量还不错,单元测试覆盖率 70% 以上,CI 全绿,生产环境也没出过大问题。但心里一直有个念头:这 10 万行代码里,有没有我从来没发现过的隐藏 Bug?上个月我花了一个周末,把整个项目喂给了 GPT-5.5,让它逐文件审查。结果它找到了 6 个 Bug,其中 2 个是那种一旦触发就会导致数据不一致的严重问题。这篇文章记录整个实验的过程、发现、以及成本。

为什么要做这个实验

起因其实是一个很小的事。上个月我在改一个订单模块的代码时,发现了一个存在了一年多的 Bug——当订单状态为"已取消"且支付方式为"货到付款"时,退款逻辑会错误地把金额算成负数。这个 Bug 从来没被触发过,因为"已取消的货到付款订单"这个组合在我们业务里极其罕见。

修完这个 Bug 之后我突然想:类似的隐藏 Bug 还有多少?靠人工 Code Review 10 万行代码不现实,写测试用例覆盖所有边界条件也不可能。但 GPT-5.5 的上下文窗口有 200 万 Token,理论上一次能读进去一个几万行的项目。不如让它来帮我看一遍。

实验设计

项目的基本情况:

  • 语言:Python 3.11
  • 框架:FastAPI + SQLAlchemy + Celery
  • 代码量:约 10.2 万行(不含测试代码和第三方依赖)
  • 文件数:347 个 .py 文件
  • 主要模块:用户系统、订单系统、支付网关、库存管理、消息推送

因为单个 GPT-5.5 请求放不下整个项目(10 万行代码大概 300-400 万 Token,超出了上下文窗口),我把审查分成了三轮:

  1. 第一轮:按模块审查。把项目拆成 12 个模块,每个模块 3000-8000 行。给 GPT-5.5 的 prompt 是:"审查以下代码,找出潜在的 Bug、逻辑错误、边界条件处理缺失、并发安全问题。对每个问题给出严重程度(严重/中等/轻微)和修复建议。"
  2. 第二轮:跨模块追踪。把第一轮发现的疑似问题做跨文件追踪。比如订单模块里有个状态流转的疑似 Bug,我把相关的 4 个文件一起丢进去让它分析调用链。
  3. 第三轮:人工验证。对 GPT-5.5 报告的所有问题逐一人工复查,排除误报,确认真实 Bug。

它发现了什么

三轮审查下来,GPT-5.5 一共报告了 23 个疑似问题。经过人工复查,确认了 6 个真实 Bug,2 个代码坏味道,其余是误报。

Bug 1:订单状态机的并发竞态(严重)

这个 Bug 在订单模块的 transition_order_status 函数里。函数的大致逻辑是:读取订单当前状态 → 判断能否转换到目标状态 → 更新数据库。

GPT-5.5 指出的问题是:这个函数没有任何并发控制。如果两个请求同时把同一个订单从"待支付"转为"已取消"和"已支付",数据库最终状态取决于谁后写入,而不是谁先通过状态校验。

我回头看了一下代码,这个函数确实是用 SQLAlchemy 的 session.query().filter().update() 写的,但没有加乐观锁(version counter)或悲观锁(SELECT FOR UPDATE)。在生产环境里,虽然目前还没触发过——因为业务上很少有同时操作同一个订单的情况——但理论上确实存在这个风险。

修复方案也很简单:在订单表加一个 version 字段,update 的时候带 version 条件,如果 version 不匹配就说明被并发修改了。

# 修复后的代码
result = session.execute(
    update(Order)
    .where(Order.id == order_id, Order.version == current_version)
    .values(status=new_status, version=current_version + 1)
)
if result.rowcount == 0:
    raise ConcurrentModificationError("订单已被其他请求修改")

Bug 2:退款金额精度丢失(严重)

这是我前面提到的那个 Bug。退款模块里有一个计算退款金额的函数,对于"已取消的货到付款订单",代码逻辑是:

# 原始代码(有问题)
if order.status == "CANCELLED" and order.payment_method == "COD":
    refund_amount = order.total_amount - order.paid_amount
    # paid_amount 对于货到付款的已取消订单始终为 0
    # 但 total_amount 可能因为优惠券分摊等原因不等于原始金额

GPT-5.5 的反馈是:"当 paid_amount 为 0 且 total_amount 因优惠券分摊导致非整数时,refund_amount 可能为负数或精度丢失。建议使用 Decimal 类型并增加合理性校验。"

我验证了一下,确实如此——我们用的是 MySQL 的 DECIMAL(10,2),但在 Python 里曾经有一段代码用了 float 做中间计算,导致某些边界情况下金额差了 1 分钱。虽然金额很小,但财务对账时会报不平。

Bug 3:缓存 key 冲突导致用户数据串号(中等)

用户模块里有一个缓存用户信息的函数,缓存 key 的生成方式是 f"user:{user_id}"。GPT-5.5 发现:当 user_idNone 时,所有匿名请求都会命中同一个 key "user:None",导致缓存污染。

这个问题在实际业务中不太可能触发——因为调用这个函数的地方都保证了 user_id 不为空——但缺少防御性校验确实是个隐患。万一未来有人新增了一个调用但没有做空值检查,后果就是用户信息串号。

Bug 4-6:三个轻度问题

剩下三个问题相对较轻,但也都真实存在:

  • Bug 4:Celery 任务重试时没有幂等性保护。如果一个发短信的任务在"已发送但未更新状态"时被重试,用户会收到两条相同短信。
  • Bug 5:文件上传接口没有限制文件大小,理论上攻击者可以传一个 10GB 的文件把磁盘写满。虽然前面有 nginx 做了限制,但应用层也应该加一道防线。
  • Bug 6:日志里记录了用户的手机号明文,没有脱敏处理。这在 GDPR 和个保法下是有合规风险的。

Token 消耗了多少

这件事大家最关心的可能是:让 GPT-5.5 审查 10 万行代码,到底花多少钱?

我做了一个精确的统计:

阶段请求次数输入 Token输出 Token
第一轮:12个模块审查12 次约 180 万约 18 万
第二轮:跨模块追踪8 次约 140 万约 12 万
第三轮:补充追问6 次约 40 万约 8 万
合计26 次约 360 万约 38 万

总共消耗了约 398 万 Token。

如果全部走 OpenAI 官方 API,按 GPT-5.5 的官方定价(输入 $15/百万Token,输出 $60/百万Token),这次实验的费用是:

360万输入 × $15/1M + 38万输出 × $60/1M = $54 + $22.8 = $76.8 ≈ ¥553

但我走的是 API 聚合平台。我用的 bblabu 是美元额度充值模式——大概 4 到 6 分钱人民币换 1 美元 API 额度,消费按官方标准计费(GPT-5.5 输入 $15/1M,输出 $60/1M,和其他平台完全一样)。所以同样消耗这些 Token,实际花费是:

$76.8 × 0.05 ≈ ¥3.84

花三块八毛钱,找到两个可能导致生产事故的严重 Bug——这个 ROI 我觉得没什么好说的。

这次实验的意外收获

除了找到 Bug,这次实验还给了我几个意料之外的启发。

第一,GPT-5.5 对代码坏味道的敏感度比我想象的高。它指出了一些非常微妙的问题,比如某个函数的圈复杂度太高、某个模块的导入顺序不规范、某个异常处理吞掉了原始异常信息。这些问题不影响功能,但长期积累会让代码越来越难维护。

第二,它对并发问题的理解超过了很多中级开发者。Bug 1 的竞态条件分析,GPT-5.5 不仅指出了问题,还给出了两种修复方案(乐观锁和悲观锁)的优缺点对比。这种分析深度超出了我的预期。

第三,误报率比我预想的低。23 个疑似问题里 6 个是真实 Bug + 2 个代码坏味道,真正有用的占了 35%。剩下的误报大部分是它把一些"虽然能工作但不够优雅"的写法当成了 Bug。这个准确率对于一个自动审查工具来说已经很实用了。

第四,大项目做全量审查的 Token 成本远低于预期。10 万行代码 26 次 API 调用,不到 400 万 Token。如果走聚合平台的渠道,成本几乎可以忽略不计。这意味着以后每次大版本发布前,花几块钱让 AI 全量扫一遍代码,是完全可行的——而这个习惯可能会成为未来开发流程的标准操作。

我准备把它变成常规流程

实验做完之后,我在项目的 CI 流水线里加了一个可选步骤:当 PR 的代码变更超过 500 行时,自动触发 GPT-5.5 做一个针对性的 Code Review,把发现的问题贴在 PR 评论里。

人工 Code Review 依然是最重要的——AI 看不懂业务逻辑,也理解不了为什么某个看起来奇怪的写法其实是故意为之。但让 AI 做第一轮粗筛,帮人类 Reviewer 把明显的 Bug 和代码坏味道先过滤出来,可以大幅提高审查效率。

如果你也想试试,这几个建议可能有帮助:

  • 单次不要塞太多代码。我试过一次性丢 2 万行进去,GPT-5.5 的分析质量明显下降,开始出现遗漏和敷衍的回答。控制在 5000-8000 行以内效果最好
  • Prompt 里明确你的技术栈。告诉它"这是一个 FastAPI + SQLAlchemy 项目,使用 PostgreSQL",它会优先检查这些框架常见的问题
  • 按模块分开审查比全量丢进去效果好。模块化审查能让 AI 聚焦在局部逻辑上,而不是被大量无关代码分散注意力
  • 走聚合平台能省一大笔钱。如果我用官网直充,一次全量审查 500 多块,一年做 10 次就 5000 多了。用 bblabu 这种美元额度兑换模式的平台,一次才几块钱,一年下来省的钱够买一台 MacBook Air

10 万行代码,26 次 API 调用,3 块 8 毛钱,找到 6 个 Bug。这个实验彻底改变了我对"AI 能不能做代码审查"的看法——它不完美,但它已经足够有用了。


相关资源:

文中 Token 消耗数据来自 OpenAI API 返回的 usage 字段,费用基于 2026 年 5 月各平台公开价格计算。

本文链接:https://www.kkkliao.cn/?id=REPLACE_ID 转载需授权!

本文链接:https://www.kkkliao.cn/?id=3998 转载需授权!

分享到:

版权声明:本文由廖万里的博客发布,如需转载请注明出处。


“我给GPT-5.5喂了10万行代码,它发现了我两年没发现的Bug” 的相关文章

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。