欢迎光临
我们一直在努力

便宜模型能不能做代码评审:Luna 与 Astra 在 50 个 PR 上的实测对比

便宜模型能不能做代码评审:Luna 与 Astra 在 50 个 PR 上的实测对比

原文:Entelligence Blog – 《GPT-5.6 Luna vs GPT-6 Astra: Is a $1.20 Model Good Enough for Code Review?》(https://entelligence.ai/blogs/gpt-5.6-luna-vs-gpt-6-astra-is-a-1.20-model-good-enough-for-code-review)

引子:一个迟早要算的账

接入 AI 代码评审之后,团队很快会撞到同一个选择题:让每一次 PR 都过最贵的模型,还是给日常变更换一个便宜很多的模型。前者账单难看,后者你担心漏掉真 bug。

Entelligence 在 2026 年 9 月做了一组对照实测,直接回答这个问题:在同一批 PR、同一个提示词下,用 GPT-5.6 Luna 这个便宜档模型和 GPT-6 Astra 这个贵档模型各跑一遍,看差在哪里、差多少、差在什么类型的代码上。他们之前还做过 Astra 与 GPT-5.6 Sol 的对比,这次沿用同一套设置,所以数字可以直接对齐。

先说价格,后面的结论都建立在这个倍数上。GPT-5.6 Luna 是每百万输入 token 0.20 美元、每百万输出 token 1.20 美元;GPT-6 Astra 是 10 美元和 50 美元。落到单次评审,同一批 PR 上 Luna 一次 0.0041 美元,Astra 一次 0.113 美元,差 28 倍。

一、实验怎么搭的,能不能复现

这批实验的设计值得单独看一遍,因为它的可复现性做得比较扎实,也是判断结论可信度的前提。

PR 来源是 AI-Code-Review-Evals 组织公开的 50 个基准 PR,来自 Cal.com、Sentry、Discourse、Keycloak 和 Grafana 五个仓库,每个仓库 10 个。这些 PR 都是在干净基线上刻意引入了缺陷的版本,不是自然产生的历史 PR。

两个模型拿到的是完全相同的提示词和相同的 diff。提示词明确要求找出正确性、安全性、并发、资源以及错误处理这几类 bug,并且排除了风格、命名、文档和测试建议。

验证环节是这套方法里最关键的。对每个 PR,来自 Astra、Sol、Luna 以及 Entelligence 公开评审器的意见会被放进一个匿名列表,然后由 GPT-6 Astra 和 GPT-5.6 Sol 各自独立判断列表里每一条是不是真 bug,并合并重复项。只有两个裁判都认定是真的,才算一个 verified bug。两个裁判在 91% 的意见上判断一致,最终有 143 个不同的 bug 通过了双裁判。

有一点必须点出来:因为加入 Luna 的意见改变了裁判看到的池子,所有东西都被重新判定了一遍,所以 Astra 的 verified 数量从上篇的 91 变成了这篇的 92,Sol 从 107 变成 108。另外 Astra 本身就是两个裁判之一,理论上对它自己有一点偏向,作者在局限一节里也承认了这一点。

二、结果对比

指标GPT-5.6 LunaGPT-6 Astra
验证通过的 bug 数 69 92
提出的问题数 93 96
精确率 74% 96%
50 个 PR 总成本 0.20 美元 5.66 美元
每个验证 bug 的成本 0.0030 美元 0.061 美元
单次评审平均耗时 23 秒 36 秒
单次评审平均输出 token 2104 688

几个结论可以直接从表里读出来。

Luna 找到的验证 bug 数量是 Astra 的 75%,花的钱是 Astra 的 3.6%。换成单 bug 成本,Astra 每个验证 bug 比 Luna 贵 20 倍。

有意思的是 token 这一栏。Luna 每次评审的输出 token 是 Astra 的 3.1 倍,但总成本还是低得多,因为它的输出单价低了 42 倍。它同时还更快,23 秒对 36 秒。

但精确率的差距是团队最先感受到的。Luna 每 4 条评论里大约有 1 条站不住脚,而 Astra 是 96 条里错 4 条。作者的原话说得很实在:本来就习惯快速略过 AI 评审意见的开发者,在四分之一的评论都是噪音时,会略过得更快。

三、差距落在哪里:按仓库和按缺陷类型拆开

只看总分很容易被平均掉一个模型在某类仓库上表现很好、在另一类上表现很差的事实。这篇文章按读者要求做了两个维度的拆分,这部分是全文最有价值的地方。

按仓库看:在 Sentry、Discourse 和 Grafana 上,Luna 与 Astra 的验证 bug 数量差距在 2 个以内。Cal.com 差距拉大,21 比 30。差距最大的是 Keycloak,Luna 只找到 6 个,Astra 找到 14 个,而且 Luna 在 Keycloak 上的意见只有 50% 站得住,Astra 是 93%。

按缺陷类型看,方向是一致的。用 GPT-5.6 Sol 给全部 143 个 bug 做了根因标注(标签和基准数据一起公开,可以自行核对),结果是这样:数据与逻辑类是最大的一组,Luna 39 个对 Astra 47 个;并发类 10 个对 13 个;安全性问题 Luna 找到 24 个中的 9 个,Astra 找到 19 个。

Keycloak 是一个身份与访问管理服务,它的基准 PR 大多改的是认证和权限逻辑,所以两个维度的结论在这里合流了。作者举了两个 Astra 抓到、Luna 漏掉的例子:联合恢复码在用过之后没有被标记为已使用,导致同一个恢复码可以重复使用;另一个是全局视图权限覆盖了在单个 client 上设置的拒绝规则。

这两个 bug 的价值在于它们说明了一类判定的性质:单看任何一行都看不出问题,必须把权限模型在改动之后允许什么推演出来才看得见。这正好落在便宜模型的短板上。

四、两边各自漏了什么

除了 Astra 独有的优势,作者也对称地统计了另一侧。

143 个验证 bug 里,44 个是两边都找到的,48 个只有 Astra 找到,25 个只有 Luna 找到。Luna 独有的 25 个里,16 个是数据与逻辑类,4 个是并发类。文中给了两个具体例子:Discourse 里重复调用退订请求会让用户的通知等级持续下降;Sentry 里一个并发 bug 在替换不健康的工作线程时没有停掉旧线程。

还有一个更实用的数字。如果把两个模型都跑一遍,50 个 PR 一共能覆盖 143 个验证 bug 中的 117 个,也就是 82%,总成本 5.86 美元——相当于在 Astra 的 5.66 美元上多花 0.20 美元,多换 25 个验证 bug。是否值得,取决于你的团队怎么处理评审意见的噪音。

五、作者自己承认的局限

这部分值得认真看,因为它同时列出了这组数字能被推到哪里、不能被推到哪里。

第一个是记忆风险。有读者指出这些仓库是公开的,bug 的修复可能就在它们的提交历史里,晚于修复时间训练的模型可能是在回忆它见过的补丁。作者查了每个 PR 背后的提交日期,跨度是 2013 年到 2025 年 7 月 25 日,其中 20 个来自 2025 年,没有任何一个晚于两个模型的训练截止点,所以「训练截止点之后」这一组是空的,没法做这个切分。作者也给了缓解理由:基准里的缺陷是人为加进这些 PR 的,所以每个 diff 里的那个具体 bug 不可能是模型训练过的提交;但周边代码确实又老又公开,知道正确版本的模型仍然占便宜。

第二个是重复性问题。作者选了每个仓库两个 PR,让每个模型又各跑了两次。在这 10 个 PR 上,Astra 首轮有 15 个验证 bug,两次重跑中 10 个都复现,至少出现一次的是 14 个;Luna 也是 15 个,两次都复现的是 7 个,至少出现一次的是 12 个。样本很小,只能当粗略参考,但结论很清楚:单次运行的数字本身就有波动,而 Luna 的波动比 Astra 大。

第三个是漏报,也就是所有模型都没发现的真 bug。要度量这个需要一份完整 bug 清单,而基准没有公开。作者只给了个下界:有 26 个验证 bug 被 Luna 和 Astra 同时漏掉,只被 Sol 或 Entelligence 评审器抓到。真实漏报数一定更高,因为没有任何评审器提过的 bug 根本进不了这个池子。

除此之外,作者还列了四条:除了那 10 个重复 PR,每个模型对每个 PR 只评审了一次;Astra 既是参赛者又是裁判;所有 PR 都早于两个模型的训练截止点;两个模型只看到了 diff,没有仓库历史、调用图或生产数据;以及 verified 数量只是 bug 数量的下界。

六、怎么在自己仓库上做一遍这套对比

原文末尾给了六步做法,可以直接照搬。

第一步是从自己仓库里收集 30 到 50 个已经合并、但后来又需要修复的 PR。

第二步是用完全相同的提示词,各跑一遍便宜模型和贵模型。

第三步是用不在这两个模型之列的裁判来验证意见,或者至少让一个裁判加人工抽查一部分。

第四步是按仓库和按缺陷类型拆分结果,平均值会隐藏弱点。

第五步是挑几个 PR 重跑,看结果波动有多大。

第六步是比每个验证 bug 的成本,并且把「漏掉代价高的那几类」单独看一遍。

这套流程的骨架大致是这样,按仓库和缺陷类型分桶的逻辑就落在返回结构里。

# 自拟示意代码,非官方 API,仅用于说明对比实验的骨架
REVIEW_PROMPT = """只找 bug:正确性、安全、并发、资源、错误处理。
不要提风格、命名、文档、测试建议。逐条给出你的判断依据。"""

def run_comparison(prs, cheap, expensive, judge, buckets):
rows = []
for pr in prs:
diff = pr.diff()
# 同一个 diff、同一段提示词,这是可对比的前提
cheap_findings = cheap.review(diff, prompt=REVIEW_PROMPT)
exp_findings = expensive.review(diff, prompt=REVIEW_PROMPT)

# 裁判必须不在这两个模型之列,否则等于自己判自己
verified = judge.verify(cheap_findings + exp_findings, diff=diff)
# 双裁判都认定才算真 bug
cheap_ok = [f for f in verified if f.source == "cheap"]
exp_ok = [f for f in verified if f.source == "expensive"]

rows.append({
"repo": pr.repo,
# 按缺陷类型分桶:漏掉不同类别的代价差别很大
"bucket": buckets.label(pr, cheap_ok),
"cheap_verified": len(cheap_ok),
"expensive_verified": len(exp_ok),
"cheap_cost": cheap.usage_cost,
"expensive_cost": expensive.usage_cost,
})
return rows

def summarize(rows):
# 单 bug 成本是决策指标,不是总成本
for repo in {r["repo"] for r in rows}:
sub = [r for r in rows if r["repo"] == repo]
for name in ("cheap", "expensive"):
bugs = sum(r[f"{name}_verified"] for r in sub)
cost = sum(r[f"{name}_cost"] for r in sub)
print(repo, name, bugs, "bugs", round(cost / max(bugs, 1), 4), "per bug")

参数上最需要注意的是提示词必须逐字一致,这是两组数字能对比的前提。verify 的返回要带来源标记,否则没法拆开统计哪一侧找到了什么。分桶函数是这个脚本里最有业务价值的部分,它决定了你能看到「便宜模型在权限代码上掉得多厉害」还是只能看到一个被平均掉的总分。summarize 按单 bug 成本聚合而不是总成本,因为总数会被 PR 数量稀释。

七、能带走的判断

便宜模型做代码评审是可行的,但前提是你要知道哪些变更不该交给它。作者自己的结论是:Luna 在那个价位上足够应付日常的正确性类 bug,但他们不会让它单独评审认证或权限相关的代码。

平均分掩盖风险分布。整体上 Luna 找到 Astra 七成半的验证 bug,但在 Keycloak 这类认证权限代码上,它只找到 14 个中的 6 个,精确率掉到 50%。如果只看总分做决策,你会正好在最贵的那类代码上失去保护。

diff 本身不告诉模型它在评审什么。原文有一句说得很准:单看 diff,模型不知道这次改动属于哪一类。它不知道某个文件位于授权路径上、某个函数被登录流程调用、或者类似的改动上季度出过事故,而这些信息恰恰决定了一个变更该被多仔细地审。这也解释了为什么走全仓库上下文和把生产行为反馈进评审的做法,在这类场景下比单纯的 diff 评审更有价值。

双模型并行是一个明确可选项,但要算清楚买到了什么。多花 3.5% 的成本换 25 个验证 bug,同时把噪音也带进来——这个取舍取决于你们团队对评审评论的容忍度,而不是一个通用结论。

最后需要说明的是,文中所有数字都出自 Entelligence 官方博客的自我评测,属于厂商自测口径,且 Astra 同时是参赛者和裁判之一,作者已就此声明;涉及模型价格与评测脚本的时效性,请以各家官方文档为准,选型前建议用自己仓库的数据复测一遍。

赞(0)
未经允许不得转载:171主机测评 » 便宜模型能不能做代码评审:Luna 与 Astra 在 50 个 PR 上的实测对比
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址