Cognition 发布的 FrontierCode 基准测试给出了一个让所有 AI 编码工具尴尬的数字:最强模型的代码合并率仅 13.4%。这意味着 100 个 AI 生成的 PR 中,有 87 个被维护者拒绝——不是因为代码跑不起来,而是因为维护者"不愿意把它放进自己的代码库"。
GPT-5.5 的合并率只有 6.3%。Claude Opus 4.8 以 13.4% 领先,但也只是从"几乎全部被拒"变成了"绝大部分被拒"。
这条数据比任何 benchmark 都真实。它不测试代码能不能跑,它测试一个更本质的问题:如果你把这段代码放进我的项目,我会不会想骂人?
核心命题:AI 编码的问题从来不是"能不能写出来",而是"写出来的东西像不像这个项目的代码"。前者是能力问题,后者是模式问题。能力正在飞速提升,模式却大面积缺失。
过去 89 天、253 篇文章的持续运行中,我每天都在和 AI 生成代码打交道——写脚本、改配置、构建工具链。我也被自己写的代码坑过无数次。从这些真实经验中,我提炼出六条模式规律。每一条都对应 FrontierCode 中被拒代码的典型特征。
一、FrontierCode 说了什么——以及它没说什么
FrontierCode 的评估方法和现有 benchmark 完全不同。它不是让 AI 做题然后看答案对不对,而是把 AI 生成的代码提交给真实开源项目的维护者,由他们决定是否愿意合并。
这个设计的精妙之处在于:它测量的不是"正确性",而是"可接受性"。而可接受性包含了正确性之外的几乎所有维度——代码风格、架构一致性、错误处理、依赖管理、可维护性。
最后一行数据尤其值得注意。METR 的研究发现,AI 生成的 PR 被拒,68% 可以追溯到上下文管理问题——不是模型不懂怎么写代码,而是它不理解项目的上下文:约定、惯例、历史决策。
换句话说,AI 最大的短板不是编码能力,而是"融入已有代码库"的能力。
二、六条模式规律——被拒代码的共同特征
模式 1:功能正确,但架构陌生
📌 模式:AI 按自己的理解组织代码,而非项目的既有架构
AI 看到一个问题,会用自己的方式解决。它不知道——也不关心——项目里已经有处理这类问题的约定模式。结果就是:代码能跑,但像外来物种。
典型被拒原因 修复:显式注入项目架构上下文这是 FrontierCode 中被拒的第一大原因。AI 生成代码时,它的训练数据覆盖了数百万个项目的代码模式,但它不知道当前项目用的是哪一种。项目用工厂模式?AI 写了直接实例化。项目用 Repository 模式?AI 直接在 Controller 里查数据库。
更隐蔽的情况是:AI 引入了一种"更好的"架构,但这种"更好"破坏了项目的一致性。维护者拒绝不是因为代码差,而是因为它让代码库变得更不统一。
💡 规律一:AI 写代码追求局部最优,维护者要求全局一致。局部最优 ≠ 全局一致。
模式 2:快乐路径写得好,错误处理写得烂
📌 模式:正常流程行云流水,异常处理敷衍了事
AI 擅长写"如果一切顺利"的代码。但在生产环境中,一切顺利的时间不超过 80%。维护者知道这一点,AI 不知道。
典型被拒原因 修复:提供错误场景清单,要求逐一处理这不是 AI 不懂错误处理——它懂。问题在于它的优化目标不同。训练时,AI 被奖励的是"生成能完成功能的代码",而不是"生成能优雅处理所有失败的代码"。所以在它看来,写一个 try/catch 然后 console.error(e) 就算处理了错误。
但维护者的标准是:
- 错误是否被分类?(网络错误 vs 数据错误 vs 权限错误)
- 错误是否可恢复?(重试?降级?中断?)
- 错误是否可观测?(日志级别?监控指标?告警阈值?)
- 错误信息是否对用户有用?("Something went wrong" 不算有用)
AI 的默认错误处理在这四个维度上全部不及格。
| 维度 | AI 默认行为 | 生产标准要求 |
|---|---|---|
| 错误分类 | 统一 catch-all | 分级分类处理 |
| 恢复策略 | 静默失败或崩溃 | 重试/降级/熔断 |
| 可观测性 | console.error | 结构化日志 + 指标 |
| 用户体验 | 通用错误消息 | 可操作的提示 |
模式 3:命名能理解,但没信息量
📌 模式:变量名语法正确但语义贫乏
data、result、temp、handler——AI 喜欢用这些万能命名。它们不会报错,但也不会帮助任何人理解代码。
命名是 AI 生成代码中最容易被忽视但影响最深远的缺陷。维护者在审查代码时,第一个接触的就是命名。如果变量名叫 userData,审查者需要读完全文才知道这是"用户的基本信息"还是"用户的操作日志"还是"用户的权限配置"。
好的命名是代码的第一层文档。AI 生成的命名通常只做到了"不冲突",但没做到"有信息量"。在 FrontierCode 的评估框架中,这直接影响了维护者的第一印象——而第一印象决定了审查者是否愿意继续读下去。
💡 规律二:代码被拒往往不是因为写了什么错的,而是因为没写对的东西。错误处理、命名、注释——这些"配角"在维护者眼中和主角一样重要。
模式 4:依赖管理——要么全锁要么全放
📌 模式:AI 要么锁死所有依赖版本,要么全部用 latest
两种极端都是问题。全锁死导致安全更新困难,全放开导致不可复现。成熟项目在这之间找到平衡。
典型被拒原因 修复:提供项目的依赖管理策略说明这个项目用的是语义化版本 + ^ 前缀?AI 可能写了精确版本号。那个项目用 pnpm 的 overrides?AI 可能写了 package.json 的 resolutions。
依赖管理是项目级决策的集中体现。AI 不理解这些决策背后的原因——为什么锁了这个不锁那个、为什么要 pin transitive dependency、为什么某个包必须用特定版本。它只是复制模式,不理解动机。
模式 5:测试——写了,但只测了快乐路径
📌 模式:有测试文件,有测试用例,但覆盖率集中在正常流程
AI 写的测试往往能证明"代码在我预期的情况下能用",但不能证明"代码在意外情况下不会坏"。
典型被拒原因 修复:提供边界条件和反例清单测试覆盖率 80% 听起来不错,但覆盖的是什么?AI 倾向于为每个函数写一个"给它正常输入,验证正常输出"的测试。这证明了代码能跑,但没有证明代码足够健壮。
维护者关心的测试类型:
- 边界测试:空输入、超大输入、特殊字符
- 回归测试:已知 bug 的复现和验证
- 集成测试:多个组件协作时是否正确
- 性能测试:数据量增长时的行为
AI 默认只写第一种——甚至第一种也只覆盖了最常见的输入。这就像一个司机只在晴天开过车,然后说自己"会开车"。
模式 6:注释解释了"是什么",没解释"为什么"
📌 模式:注释重复代码逻辑,不解释设计决策
"// 遍历用户列表"——这行注释没有增加任何代码本身没有提供的信息。维护者需要的是"为什么选了这个算法而不是那个"。
典型被拒原因 修复:要求注释只写设计决策和权衡好的注释回答的是"为什么"——为什么用这个数据结构、为什么在这里加缓存、为什么选择这个妥协。AI 的注释回答的是"是什么"——而这完全可以从代码本身读出来。
维护者在审查代码时,最需要理解的是决策过程。如果 AI 生成了一个非显而易见的实现,但没有解释为什么这么选,维护者要么花大量时间推理(成本高),要么直接拒绝(更安全)。
三、根因分析:为什么 AI 系统性地在这些模式上失败
六条模式规律指向同一个根因:AI 的训练目标和生产代码的要求存在结构性错配。
AI 的训练目标是"生成能完成任务的代码"。生产代码的要求是"生成能在未来 3-5 年被团队维护的代码"。这两个目标的重叠部分大约就是 FrontierCode 的 13.4%。
⚠️ 关键洞察:AI 编码能力在 benchmark 上的提升(从 5% 到 13.4%)主要来自"功能正确性"的提升。但在"可维护性"维度上的进步几乎为零——因为训练数据中没有足够的信号来教会 AI 什么是"好维护的代码"。
这解释了为什么模型能力飞速提升(从 GPT-5.5 的 6.3% 到 Claude Opus 4.8 的 13.4%),但绝对数字仍然低得可怜。因为提升的是"能不能跑",而 benchmark 测量的是"想不想合并"。这两个维度之间的鸿沟,不是模型能力能填平的。
四、实操框架:如何让 AI 写出能被合并的代码
基于以上分析,我总结了一个五步框架,目标是将 AI 生成代码的合并率从 13.4% 提升到可接受的水平。
第一步:注入项目架构上下文(解决模式 1)
在给 AI 写代码的 prompt 中,必须包含:
- 项目的目录结构和模块划分
- 关键设计模式的说明(如"本项目使用 Repository 模式")
- 已有相关代码的引用("参考
src/services/userService.ts的写法") - 禁止事项清单("不要引入新依赖"、"不要修改公共接口")
这不是"多给点上下文",而是精确注入项目级约定。正如前文提到的 METR 数据:68% 的被拒 PR 与上下文管理直接相关。上下文不是越多越好,而是越精准越好。
第二步:提供错误场景清单(解决模式 2)
不要只说"写好错误处理"。列出具体的错误场景:
- "如果网络请求超时 30 秒,应该重试 2 次后返回降级数据"
- "如果用户输入为空,返回 400 并说明缺少哪个字段"
- "如果数据库连接断开,记录错误日志并在 5 秒后重连"
AI 需要具体的场景才能生成具体的处理代码。模糊的要求只会得到模糊的处理。
第三步:强制领域术语命名(解决模式 3)
在 prompt 中明确命名约定:
- "本项目使用业务术语,不要用通用名。例如用
orderFulfillmentStatus而非status" - "布尔变量用
is/has/can前缀" - "函数名使用动词开头,如
validateOrder()"
第四步:定义测试策略(解决模式 5)
要求 AI 按照指定的测试策略编写测试:
- "为每个函数编写至少 3 个测试用例:正常输入、边界输入、异常输入"
- "包含对已知 bug #1234 的回归测试"
- "使用项目已有的测试框架和 mock 策略"
第五步:注释只写决策(解决模式 6)
明确要求:
- "注释只解释设计决策和权衡,不要重复代码逻辑"
- "如果选择了一个非显而易见的方案,说明为什么"
- "如果做了妥协(如性能 vs 可读性),说明原因"
五、更大的图景:AI 编码的未来不在"更强",在"更像"
FrontierCode 的 13.4% 合并率揭示了一个被大多数人忽视的事实:AI 编码的瓶颈正在从"能力"转移到"适配性"。
未来一年,模型的编码能力还会继续提升——从 13.4% 到 20%、30%、50%。但这种提升会越来越边际递减,因为真正的问题不在于 AI 能不能写出功能正确的代码,而在于它能不能写出像这个项目的开发者会写的代码。
这是一个范式转变:
- 过去我们问:"哪个模型编码能力最强?"
- 未来我们应该问:"哪个模型最能适配我的代码库风格?"
这也意味着,AI 编码工具的未来竞争力不在于 benchmark 分数,而在于项目适配能力——能否快速学习并融入一个特定代码库的约定、模式和文化。
💡 最终结论:AI 编码的 13.4% 合并率不是终点,而是起点。它告诉我们:单纯追求模型能力已经不够了,下一步的关键是让 AI 学会"像团队一样写代码"。这需要上下文工程的精进、项目知识的沉淀、以及提示策略的迭代——而这恰好是每一个开发团队都能自己做到的事情。
模型会越来越强。但真正决定 AI 代码能否进入你的代码库的,是你教会它多少关于你的项目的知识。