给AI立规矩,代码才不会越写越乱
最近大半年,团队里用AI写代码的频率越来越高,从最开始让我帮忙补单元测试,到后来直接让AI改复杂业务逻辑,甚至有个同事把一个小模块的完整需求丢给AI,它还真给写出来了。但问题也随之而来:代码风格开始漂移,有人提交的代码用单引号,有人用双引号;模块边界经常被突破,改一个工具函数居然顺手改了接口定义;更头疼的是,让AI修一个bug,它可能顺带“优化”了旁边三处代码,review的时候完全不知道它到底动了什么。
最开始我以为是模型不够聪明,后来换了几个新模型,问题依旧。我意识到,问题根本不在模型有多强,而在我们从来没告诉过AI:这个项目里什么是“对”的代码。
于是上个月,我在项目里新增了一份专门给AI制定的代码规范。不是给人看的那种偏“意识形态”的规范文档,而是真正写给大模型的、可执行、可检查、能塞进上下文里的规则。这篇就聊聊我是怎么设计的、踩了哪些坑,以及这套规范目前给团队带来了什么变化。
这篇文章适合所有深度使用AI辅助开发的人,不管是个人项目还是团队协作,只要你在让AI写代码,这套思路就能直接抄。
1. 为什么人写的规范,AI根本看不懂
1.1 AI不是不守规矩,是根本不知道规矩在哪
我们项目原来有一份非常详细的代码规范,大概30多页,从命名规范到设计模式再到性能红线,写得清清楚楚。但那是对人写的。
人的阅读习惯是可以翻目录、找重点、记忆关键条款的。但是AI不一样,它每次只看到一个有限的上下文窗口。我们在对话里给AI说“按照项目规范来写”,AI根本不知道项目规范在哪,也不知道该去哪里找,更不可能自己主动去翻那30页文档。
实测下来,如果只是口头提示“请遵守项目代码规范”,AI大概率会按训练数据里最常见的风格来写,而不是按你项目里的风格来写。训练数据里有的是各种开源项目的混合体,AI会默认给你生成一套“通用最佳实践”,但这些实践往往和你项目已有的风格完全对不上。
1.2 上下文被冲垮:AI是金鱼记忆,不是大象记忆
我们试过把规范文档直接贴到对话里,一开始效果还行,但对话稍微长一点就完蛋。让AI改了几轮代码之后,它就把规范忘得差不多了,又开始按自己的偏好来。
这不是AI“不听话”,而是注意力机制的特性。规范的文本埋在长长的对话历史里,越往后权重越低。尤其是当代码片段越来越长、讨论越来越多时,早期的那几条规范早就被挤到注意力边缘了。
我在实际操作中还发现一个现象:规范如果放在对话的早期,效果最差;放在对话中后期、紧跟着任务要求出现,效果会好不少。但如果每次都要手动粘贴,也坚持不了几天。所以规范文件必须独立存在,并且要有一套机制保证它每次都出现在合适的位置。
1.3 致命伤:AI不知道“不该改什么”
人写代码的时候,天然知道边界在哪里。我不会在修登录bug的时候顺手把支付模块的命名改一遍,因为我知道那样会让review的人发疯。但AI没有这个“常识”。
有一次我让AI优化一个列表查询接口的性能,结果它把整个Repository层的实现方式都改了。从MyBatis Plus改成了JdbcTemplate,性能确实提升了,但是整个团队的代码风格被它一人带偏,其他人后续维护直接崩溃。
这就是我下定决心做这套AI代码规范的核心原因:不是管AI该做什么,而是让它知道不该做什么。AI的创造力在代码生成上是优点,在项目协作里就是风险。
2. 给AI写规范,和给人写规范完全是两码事
2.1 写法逻辑不同:人看条款,AI看指令
刚开始我尝试直接把人类规范精简版丢给AI,效果很差。后来我琢磨出一个道理:AI不擅长从抽象条款推导具体行为,但擅长执行结构化的指令。
人类规范常写“代码应当具备良好的可读性”,这句话本身没有操作定义。AI看到这句话,不知道具体要干嘛。但如果你写“所有函数必须有Javadoc注释,注释第一行说明该函数的功能”,AI就知道该怎么做了。
所以给AI的规范,本质上是在写一套“提示词工程”性质的规则集,每条规则里要有明确的动作、边界和判定标准,而不是价值观描述。
2.2 详略取舍不同:AI版要短而准
人的规范可以写得非常全面,因为人可以按需查阅。但AI的规范如果太长,也会被上下文窗口限制。我们项目的规范文件最开始写了一万多字,后来发现AI根本读不完,尤其是配合代码内容一起塞进上下文的时候,经常只截取前半段。
我在反复测试后总结出的经验是:给AI的规范尽量控制在300行以内,每条规则尽量一行描述,实在需要解释的用一到两句补充。超过这个长度,要么精简,要么拆分。
与其写一个又长又全的规范,不如按模块拆分,配合不同的任务场景分别注入。我后面章节会详细讲这部分。
2.3 验证方式不同:人靠理解,AI靠重复
人读完规范,理解了,就会长期遵守。AI没有“长期记忆”,每次会话都是一次全新的开始。所以你写的规范不能有“前文已述”这类依赖上下文的写法,必须保证每条规范可以独立理解、独立执行。
另外一个关键点是:规范文件要具备可重复性。这意味着AI在每次会话开始时都能被有效注入,而不是靠人临时想起“哦我是不是得粘贴一下规范”。必须在工程流程上固化这个动作。
3. 我给AI制定的代码规范,具体包含哪些内容
3.1 全局总则:先定底线
这份规范文件的开头我写了一组“不可绕过”的规则,称之为底线条款。包括:
- 不得修改与本次任务无关的代码文件
- 不得在代码中硬编码生产环境配置
- 不得移除或改变已有的异常处理逻辑
- 不得绕过代码审查流程直接提交
- 不添加无用的依赖
为什么先搞这么多“不”?因为AI一旦自由发挥,破坏力远大于创造力。AI的特性是如果你不给它边界,它会把一切它觉得不“完美”的地方都改一遍。这些底线条款,实际上是在限制AI的“过度热心”。
3.2 查询模块:怎么读代码
如果AI要回答“这个bug为什么会出现”这类问题,需要先理解现有代码。我给AI规定了查询代码的步骤:
- 先搜索项目结构,识别相关模块
- 只读和问题相关的文件,不要全局搜索所有文件
- 如果涉及方法调用链路,从入口方法开始追踪
- 禁止在没有完整理解链路的情况下,直接猜测问题原因
这个查询规范的效果非常明显。之前AI经常只看了一个报错信息就猜原因,结果给出的修改建议经常不靠谱。加了这条之后,AI会主动去翻相关文件了。
3.3 修改模块:怎么改代码
这部分是核心中的核心。我规定了几条硬性准则:
- 遵循“最小改动”原则:只修改解决问题所必需的最小范围
- 保持代码风格与所处文件一致:如果文件里用单引号,就继续用单引号
- 不能因为个人偏好重构已有代码,哪怕那代码确实写得烂
- 如果一个改动涉及3个以上文件,先把修改计划列出来让开发确认
- 新增的公共方法必须带注释,说明设计原因和适用场景
最小改动这条最管用,AI遵守这条之后,代码review的压力直接小了一半。
3.4 测试模块:改完必须给检验方案
以前让AI改代码,改完就完事,有没有测试全靠自觉。规范里加了一条硬性要求:所有涉及逻辑变更的修改,必须同步提供测试方案,要么是单元测试代码,要么是调用示例和验证步骤。
这条规则不是为了追求覆盖率,而是让AI在修改前就下意识地考虑“我怎么证明这次改动是正确的”。实测下来,这个习惯本身就能降低AI瞎改代码的概率。
3.5 日志与错误处理:给AI强调“异常状态不是可有可无的”
项目里的日志规范和人用的规范差别不大,主要规定了:
- 禁止吞掉异常,所有catch块必须至少输出一条日志或者抛出包装异常
- 日志必须使用模板形式,禁止字符串拼接日志
- 错误提示中必须包含相关参数值,方便定位问题
AI特别喜欢“优化”异常处理,经常把别人精心写的catch逻辑给简化掉。加了这条之后,好歹能在规范层面阻止大部分盲目改动。
3.6 禁止事项:明确列出不能做的事
最后一部分是黑名单。每个项目可能不一样,我这里列了团队踩过的几个经典坑:
- 不要用System.out.println替代日志框架
- 不要在Entity中写业务逻辑
- 不要把业务规则写在Controller层
- 不要改写数据库表结构相关的定义文件
- 不要在修复bug的同时“顺手”升级依赖版本
黑名单的每一行都来自血泪教训,基本都是AI在实际开发过程中真实干过的操作。
4. 落地实操:怎么让AI真正“读到”并遵守这些规范
4.1 文件怎么放、怎么写
我把这份规范放在项目根目录下的CODE_OF_CONDUCT_FOR_AI.md,而不是藏在docs里。这个位置的用意是:任何AI工具扫描项目结构时,大概率都会先看到根目录的文件列表。
规范文件本身的格式,我用了纯文本Markdown,不用复杂表格,避免某些AI工具解析表格能力弱导致规则丢失。每条规则尽量独立成行,不依赖上下文。另外,文件头部放了一段“这是给AI开发助手的强制约束,必须在完成任何任务前读取并遵守”的说明,事实证明这种前置强调语气对AI有引导作用。
4.2 项目级提示词:绑定“先读规矩再干活”习惯
根目录我还会放一个AGENTS.md或者CLAUDE.md,取决于你用哪个工具。这个文件用来定义AI助手的“工作流程”,在文件里明确写了一条:处理任何代码相关任务之前,必须阅读CODE_OF_CONDUCT_FOR_AI.md并逐条对照。
这一步很关键。如果只是把规范文件丢在项目里,AI不会主动去看。但如果你在Agent配置里指定它必须先读这个文件,再开始干活,效果就完全不同了。实测下来,执行率从之前的不到10%提升到了接近100%。
4.3 配合PR描述模板:让AI自己汇报是否“合规”
我还给团队定义了一个PR描述模板,要求AI在完成代码改动后,在PR描述中逐一列出:
- 本次修改涉及哪些文件
- 每个文件改了几行代码
- 是否引入了新增依赖
- 是否符合最小改动原则
- 是否同步提供了测试方案
这个模板表面上看是给PR用的,实际上是逼AI在完成任务时主动检查自己的行为是不是合规。我试过让AI按这个模板输出,它能明显“意识到”自己有没有动不该动的文件。
4.4 在不同代码场景中如何拆分布置
配合不同的代码场景,我给AI的规范也会分场景注入。我以前的项目采用的是“总规范+场景片段”的组合方式:
- 总规范:所有任务都适用,内容是底线条款、通用编码风格、禁止事项
- 场景片段A:新增功能的开发规范,重点约束功能设计、接口命名、参数校验
- 场景片段B:Bug修复规范,重点约束问题排查流程、改动范围、回归测试
- 场景片段C:代码重构规范,重点约束行为保持、风险控制、兼容性验证
当AI的任务类型比较明确时,我会在提示词中直接指定“本次任务适用场景片段B”,同时附带总规范全文。这样总规范控制长度,场景片段控制精确度,两边都不累赘。
这个“总规范+场景片段”的组合思路,是我调试了很久之后确定的。从一开始只挂一份完整文档,到后来拆分场景,最大的变化就是AI不再“过度执行”规则。比如之前用一份全量规范约束所有任务时,AI写一个接口也在想重构规则、写一个工具函数也在想性能规范,导致很多低级错误。现在按场景拆开,只让它关注当前任务相关的规则,反而更靠谱。
5. 常见问题与排查技巧实录
5.1 问题一:AI读了规范,但就是不遵守
这是最让人上火的情况。规范给了,文件路径也明确说明了,AI也回复“好的,我了解了”,但实际产出还是我行我素。
排查思路:先检查任务描述是否和规范冲突。比如规范说“保持最小改动”,但任务描述是“优化这个模块的整体设计”,AI就会优先执行任务指令而忽略规则。另外一个原因可能是规范内容在不合适的上下文位置,如果规范被代码内容淹没,注意力权重就低。
我的处理办法是:在任务描述的最后面再重复一次关键规则。比如“记住:本次任务只修改XXX文件,不要碰YYY文件”。这种重复对AI有很强的指令强化作用。
5.2 问题二:规范太长,AI根本读不完
如果规范文件超过几百行,AI在有限的上下文里可能读不完,或者只读到前半段。尤其是遇到大型代码库,AI还要花大量上下文去理解代码,留给规范的“带宽”就更少了。
解决技巧:遵循“总规范+场景片段”的组合方式,这是效果最好的一种方案。日常场景中模型只加载必要的那一段,既控制上下文消耗,又不影响规则覆盖。如果项目里不同模块的风格差异较大,还可以在具体模块目录下放一个针对该模块的简版规范,块级定制会让AI更容易学。
5.3 问题三:AI“假装”遵守规范,实际上没有
比如规范要求“新增公共方法必须带注释”,AI可能真的加了一个注释,但注释写的是“This method adds a new method”,等于废话。
这种问题的本质是:AI把“遵守规范”当成一个形式任务来完成,而不是真正理解规范的目的。我的经验是,规范条目要尽量写得有“判定性”。比如“注释必须包含:方法功能、入参说明、返回值说明”就比“必须带注释”好执行得多。AI可以把这三者当作强制字段来生成内容。
5.4 问题四:规范和实际需求冲突
有时候规范说“禁止修改与任务无关的文件”,但任务本身就需要跨多个模块改动。AI会陷入两难,然后通常会偏向先做任务,再做规范检查。
我在规范里加了一条例外条款:“如果任务确实需要跨模块修改,请在动手前先说明理由,列清楚计划改动文件清单,等待确认后再继续。”这条规则给了AI一个合理的“出口”,当它觉得规范冲突时,有一个沟通路径可以走,而不是闷头违反规则或者卡死不干活。
5.5 问题五:多Agent干活时,规范互相打架
团队里有人用不同的AI编程工具,不同工具读取项目规则的方式不一样。有的认CLAUDE.md,有的认AGENTS.md,还有的认自定义指令文件。如果不统一,每套工具都按自己的习惯来,等于没有规范。
我的解法是:保留一份主规范,在CLAUDE.md和AGENTS.md里都放指向主规范的链接,并写清楚“所有AI协作工具必须统一遵守CODE_OF_CONDUCT_FOR_AI.md”。这样不管哪个工具进项目,都能找到同一份规则。
6. 几个想到的延伸玩法
做完了这份规范之后,我发现这个思路不仅能用于“给AI定规矩”,还能降低新人接手项目的成本。新同事进组不用翻一堆文档,直接看这份AI规范,基本就知道这个项目里哪些坑是不能踩的,相当于一份“踩坑导航图”。
我还在考虑把规范关联到CI流程里。比如写一条脚本,在PR提交前自动检测是否包含System.out.println、是否修改了锁文件等硬性红线,如果命中就直接拦截。这样相当于把规范从“写给人/AI的文字”变成了“机器可执行的约束”,执行力会再上一个台阶。
也有人建议我把这套规范做成通用的“Skill”或插件配置,发到社区里让大家直接导入到AI编程工具里用。我自己试过把规范包装成一个可复用的提示词包,在几个项目里同样能跑通,但不同项目的技术栈差异很大,真要做好还是得按各自项目来定制。
如果非要说一句总结的话,我的体会是:AI编程的关键不是让模型更聪明,而是让它在你的项目里有边界地聪明。给AI制定代码规范,本质上是把一个团队长期沉淀的经验转译成AI能理解的语言。这个转译过程会逼着你想清楚自己的项目里到底什么最重要,这本身就是一件很有价值的事。
始终要记得:代码规范不是给AI上的枷锁,是让AI的代码少返工的护航配置。