AI Coding 落地存量大项目:规范先于工具

前几天看到一篇文章,讲某团队用 AI 对 31 万行代码做重构的实践。里面有一句话让我想起了自己团队踩的坑:「没有统一规范的约束,不同人用 AI 写出的代码风格各异,系统反而会加速腐化。」这个说法我们亲身验证过,记录一下。

AI 进来之前,问题就已经存在了

我们有一个 Java 项目,五年历史,十几万行代码。架构本来是分层的(Controller → Service → Repository),但随着人员流动,各层的边界越来越模糊:有 Controller 直接调 DAO 的,有 Service 里写了大量业务逻辑又有 Service 把业务逻辑推到 DTO 里的,DTO 后缀有人写 Dto、有人写 DTO。同一件事有三种做法,没有一种是错的,但放在一起就是一团浆糊。

这个问题在 AI 之前就存在,但可以接受——新人来了,看看旁边的代码照着写,慢慢理解隐性规范,大约三个月能融入。有问题有人 review,偏差不会太大。

AI 进来之后,问题变成了五倍速。

工具链收拢到 Cursor + Claude CLI 之后,大家产出代码的速度快了,但因为每次 AI 对话都是独立的,AI 不知道这个项目的隐性规范,每次都靠「推断」——看见 Mapper 就直接注入,没看过项目规定必须走 Repository 接口;看见字段是 userId 就用 Long,没看见项目规定金额类字段必须用 BigDecimal。每个人的 AI 推断出来的默认值不同,合代码的时候就是一锅粥。review 成本比以前高了,因为不是偶尔有一两个风格问题,而是每个 PR 都有一批。

工具统一没用,规范落地才有用

第一个反应是统一工具——大家用同一套 IDE、同一套 prompt 模板。换了之后,情况确实稍微好一点,但没有本质改变。因为问题不是工具不同,是 AI 缺少项目的上下文。

真正解决问题的是做了两件事:

第一步:人人对齐。 开了一次两小时的架构规范讨论,把那些「大家心里知道但没写下来」的规则显式化:字段注入还是构造器注入?哪些工具类用?分层的边界在哪里?异常怎么包装?金额字段用什么类型?这些讨论并不轻松,因为不同历史时期加入的人有不同的理解,要对齐本身就是一次利益博弈——有人用了三年 @Autowired,不愿意改。但不对齐就没办法往下走,必须这一步先完成。

第二步:人机对齐。 把对齐后的规范写进 CLAUDE.md 和 Cursor Rules,让 AI 在生成代码前就能加载这些约束。不是写成「尽量使用构造器注入」,而是写成「必须使用构造器注入,不允许 @Autowired 字段注入,违反此规则的代码 review 时直接打回」。模糊的规则对 AI 和对人都没用。

这两步的顺序很重要。如果人没有对齐就直接去写 AI 规范,写出来的规范反映的是写规范那个人的习惯,不是团队共识。AI 照着执行,其他人依然不认,规范成了摆设。「人人对齐」必须先于「人机对齐」。

CLAUDE.md 写什么、不写什么

花了一些时间摸索规范文件的粒度,记几个经验。

不写太泛的原则,只写可验证的规则。 「代码要清晰易读」这种话对 AI 没意义,它不知道怎么评估。「所有 public 方法必须有 Javadoc,Javadoc 里必须包含参数说明和返回值说明」这种规则是可执行的。遇到模糊规则先不写,等出了具体的坏案例,反过来把规则提炼清楚再写进去。

写决策表,不写判断过程。 「优先用 X,但如果 Y 情况下用 Z,不过如果还有 W 情况……」这种条件链条对 AI 来说很混乱。改成「场景:分页查询 → 用 X;场景:全量加载 → 用 Z」的决策表形式,执行准确率高很多。

真实代码片段比描述有效。 在规范里直接贴从项目里截取的三到五行代码,比用文字描述「应该像这样做」效果好得多。注意是从生产代码里截,不是现写示意代码——AI 对「真实风格」和「演示风格」的识别比想象中敏感,示意代码有时候会被 AI 当成另一种新的风格来模仿。

总行数控制在 100~150 行以内。 超过这个长度,AI 在「中间」的注意力会下降,埋在文件中段的规则遵守率显著变差。如果规范很多,分到各子模块的 CLAUDE.md 里,主文件只写最高频、最关键的那些。

一个月后的数据

做完这两步大约一个月,有几个可以量化的变化。

review 打回次数降了约 60%。以前每个 PR 平均有 4~6 条风格类评论,现在降到 1~2 条,而且多数是「这个 edge case 考虑了吗」这类实质性问题,不是风格问题。

新功能的 AI 代码采纳率从大约 40% 涨到 75%。「采纳率」是我自己定义的指标:AI 生成的代码未经大幅修改就进入最终 PR 的比例。这个数字高不代表 AI 在偷懒,代表 AI 生成的代码方向对了,减少了二次修改。

不好量化但能感受到的:大家对「AI 写出来的代码是不是我们的代码」的接受度提高了。以前合了 AI 生成的代码,总有一种「这不是我们的风格,只是凑合能跑」的感觉;现在因为规范一致,AI 的产出和人工写的代码混在一起,review 的时候不明显区分了。

还没解决的

有两件事还没有好的解法。

一是规范的维护成本。CLAUDE.md 是个静态文件,项目的规范会演进,有新人加入带来新的约定,有旧的约定被废弃,文件容易腐烂。目前的做法是每季度做一次规范 review,但坦白说这件事很难坚持,往往是出了问题才回头更新。

二是架构层面的约束还是穿不进去。字段类型、命名规范这类表面的约束写进 CLAUDE.md 很有效;但「Service 不能直接访问 DAO」这种架构边界,AI 知道规则但不理解违反规则的系统性后果,在模糊情况下(比如一个临时的 one-off 查询)还是会绕过边界。这类约束真正有效的手段还是代码层面的封装——让违规在编译时就报错,而不只是写在文档里等 review 时发现。

总结一下教训:AI Coding 在存量大项目里落地,工具和模型选型只是入场券,规范工程才是核心工作量。而规范工程最容易踩的坑,是跳过「人人对齐」直接去写 AI 规范——写出来的规范没有权威性,工具执行得再准也没有意义。