2026/9/15 18:58:14

AI编程代码规范:从事故到ROBOT.md的工程实践指南

AI编程代码规范:从事故到ROBOT.md的工程实践指南 1. 为什么AI写代码也必须有一份“员工手册”1.1 当AI开始“自由发挥”我遇到的三个真实事故先说结论给AI制定代码规范这件事不是“管理洁癖”而是被逼出来的。过去半年我把团队的日常开发流程切到了AI辅助编程的节奏上需求拆解、代码生成、单测补齐、重构建议全都让AI参与。前两周确实很爽commit速度明显变快一个会话干完以前半天的活。但等我把AI生成的代码合并进主干、开始跑回归的时候问题开始集中爆发。第一个事故发生在一次支付模块的改动。我让AI修一个超时重试的bug它的确修了但同时顺手把项目中另一个工具类的列表拼接逻辑从for循环改成了stream。任务完成得很干净单元测试也过了结果联调时发现序列化顺序变了消息队列里的字段顺序不一致下游系统解析直接报错。整个排查花了我一个下午最后看diff才意识到——AI在“顺手优化”它觉得不够优雅的代码。第二个事故更隐蔽。AI生成的代码里有一段对用户输入的增加逻辑。它默认对字符串做了trim和空值兜底看起来很稳妥但这块逻辑在业务上恰恰要求保留原始输入包括首尾空格。AI按自己“通用的好习惯”改了我的业务行为没有报错、没有警告只是默默地把线上表现改变了。第三个事故是日志格式。AI在某次代码补全时把logger.info的参数顺序调整了导致日志收集系统解析错位告警规则全部失效。这玩意儿当时没被发现直到一个后台任务异常了整整一小时告警没触发我们靠人工巡检才发现。三个事故有一个共同点AI不是不遵守规则而是它根本不知道你们项目的规则是什么。它只知道“通用意义上代码应该怎么写”不知道“在这个仓库里哪些是约定俗成的红线”。1.2 把AI看作“高产出、零常识”的新同事我后来跟团队打了一个比方AI就像一个刚入职的新人名校毕业基础功扎实干活麻利但完全不了解公司制度。你不告诉他“报销单怎么填”他就按网上的模板填你不告诉他“发布窗口是每周四下午”他就敢在生产环境空档期乱发东西。这个比喻的关键点在于你没法指望一个新人通过“多观察、多学习”来自动领悟制度你只能把制度写下来放在他开工前必经的路上。AI也一样它对项目的理解来自训练数据当前上下文。训练数据是全世界公开代码的平均值当前上下文是你在对话窗口里贴进去的代码和提示词。项目里的特殊性——比如某段代码为什么不能动、某个命名约定为什么存在、某些目录为什么不能随便新建——对这些它一无所知。所以从管理逻辑上给AI制定代码规范本质上和编写新人入职手册没有区别。它不是“限制AI的能力”而是“补全AI缺失的上下文”。1.3 这份规范到底值不值有人会问写一份给AI看的代码规范要花多久值当吗按照我的实际经验第一次起草完整版大概需要两个小时左右后续每月维护大概半小时。两个小时的投入换来的是什么是我把上面那种“AI顺手优化导致线上事故”的排查时间省下来了。一次事故排查的人力成本至少是半天到一天如果涉及线上回滚、客诉跟进成本还得翻几倍。而且这份规范文档不只在当前项目有效。它沉淀下来的是一套“项目常识”换人也好、换AI工具也好、新需求启动也好都可以直接复用。我把规范的模板抽取到了一个专门的目录新项目clone下来之后改改技术栈章节就能用。这是一笔越用越划算的投资而不是单纯的管理成本。2. 规范文档的载体从Prompt到仓库根目录2.1 为什么漂浮在聊天窗口里的Prompt不靠谱最开始我尝试把规范写在Prompt模板里每次开新会话都粘贴一遍。效果很糟糕原因有三个提示词过长会稀释AI的注意力。当你的用户消息里有300行项目背景、200行规范、500行代码的时候AI对规范章节的遵从度会显著下降。它更倾向于把注意力集中在最近的、与代码直接相关的内容上。规范无法持续更新。写进会话里的规范是“一次性”的今天改了一版约定忘了发到群里大家还在用旧版——说白了它没有一个“唯一权威版本”的存储位置。团队成员各自维护Prompt模板内容悄悄分化。有人加了“不要用stream”有人加了“禁止修改公共工具类”还有人觉得“AI需要更大自由度”删了一堆限制。因此规范不应该是一个“漂浮的文本块”它应该是一份固化的、版本可控的、有唯一来源的工程文档。2.2 文件放哪里、叫什么名字最合适经过实践我选择把规范放在仓库根目录命名为ROBOT.md。选择这个名字有讲究很多AI编程工具包括GitHub Copilot、Cursor、通义灵码等会默认读取仓库根目录下特定文件名作为项目级说明。ROBOT.md是我用的主工具约定但为了兼容性我同时做了几个软链或副本AGENTS.md、CLAUDE.md内容一致指向同一份规范。这样做的好处是无论团队里同事用的是哪款AI工具都能自动读到规范。文件位置的优先级也验证过位置读取概率说明仓库根目录的ROBOT.md / AGENTS.md最高多数AI工具默认自动加载.cursor/rules目录下的规则文件偏高Cursor系工具按文件名自动识别docs目录下一份超链接中依赖工具的“文档检索”能力团队成员各自的对话窗口极低每次都要手动粘贴容易遗漏放置原则总结为一句让AI在“不开任何额外窗口、不做任何额外操作”的情况下就能读到规范。一旦需要人为记忆去“记得喂给AI”这个方案基本就会失败。2.3 “喂”给AI的两种打开方式规范文件放好了接下来是“让AI读到它”。目前主流的AI辅助编程工具对项目级规范文件的读取方式有两种第一种是IDE插件自动加载。比如Cursor会自动扫描.cursor/rules和根目录的ROBOT.md作为系统级指令注入上下文。你什么都不用做打开项目、打开AI对话框规则就已经在AI的“意识”里了。这种方案最省心也最可靠。第二种是手动引入。如果你的工具不支持自动加载可以做一个“快速启动指令”比如在规范文件顶部写一段引导语要求使用者复制粘贴给AI请先阅读项目中根目录下的ROBOT.md文件并严格遵守其中的所有规则。如果规范与你的通用建议冲突以规范为准。这段引导语本身属于“元规则”——它做的事情是让AI主动去找规则而不是等规则被塞进上下文。在长对话场景里有个实际好处即使中间切换了会话只要第一步做了“阅读规范”的动作后面所有生成内容都更守规矩。3. 我把代码规范拆成了六大模块规范最终要能落地就不能只是“不要乱改”“注意质量”这种空话。我把实际用下来的ROBOT.md按模块拆解每一块都有明确的“给AI看的规则”和“给人类同事看的理由”。下面按实际文档顺序讲解。3.1 模块一角色定义与工作边界文档开头需要定义AI的角色。我给AI设定的角色是“项目初级开发工程师”权限边界如下你可以生成、修改业务代码但核心目录下的文件需要额外授权。你可以补充单元测试但不要为了“覆盖率”写无意义的测试。你可以提出重构建议但在没有明确指令前不要擅自重构与当前任务无关的代码。你不可以修改依赖版本、CI/CD配置、数据库迁移脚本除非任务明确要求。这段内容的必要性在于约束AI的“主动性”。AI天然倾向于表现得“很有用”它会主动把“能优化的都优化一遍”。不划边界的话每个任务都可能附带一堆无关diff。3.2 模块二公共代码保护清单公共代码是项目里最脆弱的部分。一个工具函数可能被上百处调用AI一旦改动它的边界行为影响面是全局性的。规范里我单列了一张“红线清单”用最简单直白的语言标注common/、utils/、shared/、core/、hooks/目录下代码为公共代码禁止在非明确授权的情况下修改。对公共代码的修改必须通过代码评审并且提交信息中必须注明“BREAKING CHANGE”或“MODIFIED_SHARED_CODE”。如果AI认为某处公共代码存在bug它应做的是“报告”而不是“直接修改”。给AI划“应做说明而非直接修改”的规则针对的是模型在无所事事时倾向于“直接把问题修了”的行为模式。把“报告问题”作为第一优先级可以让人类同事及时知悉变化避免隐蔽改动上线。3.3 模块三禁止事项清单我把“禁止事项”写成独立章节用否定句每条都是一句话不给AI留下过度解释的空间。节选如下禁止擅自修改包管理文件package.json、requirements.txt、pom.xml等中的依赖版本。禁止对DB操作、网络请求、文件读写等I/O边界做静默容错处理除非业务需求明确要求失败时静默。禁止在日志中打印敏感字段token、password、身份证号、手机号。禁止把项目内私有逻辑上传到公共AI对话中简化为不要在对话里粘贴完整密钥。禁止修改编译器警告之外的“你没被要求动”的代码。否定句的写法很关键。正面的建议如“注意I/O异常处理”容易让AI“自由发挥”而否定句“不要静默吞掉I/O异常”能掐断AI默认的容错倾向——它通常会加个空catch块让单测通过但这在生产环境的后果就是问题毫无征兆。3.4 模块四代码风格领域化代码风格章节需要结合具体技术栈写不能太泛。通用规范缩进、分号、命名AI早就学会了不需要你教。真正要紧的是“领域内的风格约束”前端React组件统一使用函数组件禁止默认导出除非是在页面路由层级。前端状态管理优先使用项目内封装的useRequest禁止在各页面直接写裸fetch。后端Controller层只做参数校验与结果包装业务逻辑必须下沉到Service层。后端所有数据库查询必须走DAO层禁止在业务代码里直接拼接SQL。Python对时间字段统一使用timezone-aware类型禁止使用naive datetime。这些规则为什么AI容易犯因为它只有“世界级代码的平均风格”不知道你们项目内部的架构规范。比如它可能觉得“直接写在Controller里也没什么”但你们项目的分层约定要求必须下沉到ServiceAI不会凭空知道这个约束。3.5 模块五测试与安全性门禁测试规范的要点不是“测试覆盖率要高”而是“测试必须真的验证行为”。常见AI生成的测试问题是“假绿”——断言太弱什么都能通过等于没测。我给AI定的规则是新业务代码必须附带至少一条关键路径测试。单测断言必须包含“行为验证”如“调用某接口后返回特定结构”而不是只断言“函数执行不抛异常”。禁止为了覆盖率跳过核心分支。遇到很难测试的分支应在注释中说明原因。涉及文件上传、登录鉴权、第三方回调等安全相关代码禁止在测试中打印敏感信息。安全性门禁单独列了一个小节专门写“如果AI对这块代码没有把握必须在注释中标注AI_GENERATED_UNREVIEWED等待人工复核”。这个标记的作用不只是“安全提示”还方便后续代码扫描工具识别AI生成区域也算是一条数据链路。3.6 模块六提交流程与解释要求最后一个模块要求AI在提交代码时遵循标准信息流如果你修改了公共代码或跨模块逻辑commit message必须以[IMPORTANT]开头。如果你生成的代码包含了需要后续人工复查的部分请在代码注释和对话摘要中同时标注。在完成一次较大改动后必须用不超过5条bullet列出“你改了什么、为什么改、可能影响哪些模块”。这部分的本质是让AI生成行为“可追溯”。毕竟AI不会像人类同事那样记得自己上周干了什么它每次会话都是从头开始。把“解释”固定在提交信息里相当于给每一次AI改动都留了审计记录一旦出问题可以快速定位是“哪次对话、哪条指令、哪个方案”导致的。4. 最容易踩坑的六类AI违规写法与应对条款4.1 风险一隐形重构——AI“顺手”动了无关代码前面提到的支付模块事故就是典型。AI在执行任务时为了提高“代码质量”评分会顺手把遇到的不符合它审美的代码一并改掉。应对条款在规范中加入“最小改动原则”原话是“只修改与当前任务直接相关的代码行。不改变无关代码的格式、变量名、函数签名、执行逻辑。”但这条依然被违反过。所以我后来又加了一条“diff展示规则”要求AI在每次修改后主动输出“我修改了哪些文件、哪些函数”这对人类评审者来说能快速发现“多出来的改动”。4.2 风险二华而不实的优化——AI为了“优雅”牺牲可读性AI特别喜欢链式调用、函数式编程、装饰器这些“看起来高级”的写法。问题在于很多项目的代码基础是普通命令式风格混入高级特性后可读性急剧下降。更严重的是AI在“优化”中可能悄悄改变原有的null判断或前置校验。应对条款在风格章节写明“优先使用项目内已有的代码风格当多种实现方式达到相同目的时选择最简单、最少嵌套的一种”。同时加了一句“禁止以‘风格优化’为由修改与当前任务无关的代码。”4.3 风险三自创约定——命名、依赖版本、目录结构的个人偏好AI生成代码时经常自作主张给类名加前缀、把常量定义位置改掉、或者引入一个新的小工具库来实现本可简单实现的功能。应对条款规范中明确所有新引入的第三方依赖必须说明理由并提交给人工评审。项目内已有工具函数时禁止重复实现“轮子”。命名风格遵循现有代码风格不确定时先问人类同事而不是自己决定。这个问题的深层原因在于AI对“项目内已有工具”的检索能力有限尤其在不完全了解整个仓库结构的情况下它倾向于直接“写一个自己知道的工具”而不是去搜索仓库里是否已经存在类似实现。4.4 风险四单元测试“假绿”最典型的AI测试问题是断言“函数没有抛异常”就算通过。例如AI生成一个测试test(should call saveData, async () { await saveData({name: test}); expect(true).toBe(true); });这种测试唯一的作用是填充覆盖率报告。应对条款是硬性的“单测中禁止出现expect(true).toBe(true)这类空断言必须针对返回值/副作用行为做断言。”另外增加一条人工检查项“覆盖率数据的可信度由评审者判断不要盲目追求百分比。”4.5 风险五破坏日志与可观测性日志格式引用的字段名、日志级别如果被AI随意改掉直接破坏告警链路。最惨的是AI还会把中文日志改成英文理由是“国际化”但下游日志系统按中文keyword做告警匹配直接失效。应对条款在规范中声明“日志结构必须保持向后兼容”并补充“禁止修改已有日志的关键字段名称、级别和message模板。如需修改必须在commit message中显式标注LOG_CHANGE。”4.6 风险六依赖引入失控AI有时候因为当前环境缺少某个能力会“顺手”在包里加一个新依赖这会让依赖体积膨胀也可能引入安全漏洞。场景很常见AI想用lodash/get但是项目里没有引入lodash于是自动安装。应对条款明确“禁止在未获得明确许可的情况下修改package.json、requirements.txt、go.mod等依赖清单。一旦修改必须单独生成一个commit并附带添加该依赖的理由说明。”这等于把“修改依赖”从“普通代码改动”里拎出来单独走一个更重的审批路径。5. 规范落地的五条实战经验让AI“真听进去”规范文档写得再漂亮AI不遵守等于零。针对“如何让模型真正遵循规范”我自己折腾出几个非常有效的技巧。5.1 技巧一在规范开头放置“最高指令”规范文档开头我固定放三段话原文如下你是一名严格遵守项目规范的高级开发工程师。以下规范文档定义了本项目的硬性约束。所有规范优先级高于通用的编程建议。当规范内容与你的一般性知识冲突时以规范为准。违反规范将导致代码变更被拒绝合并并增加人工审查成本。因此在做出任何结构性修改前请先阅读规范内容并逐条对照。这段文字不能省。“以规范为准”这句话作用极大因为AI如果只把它当成一个普通参考文档就会把规范建议和自身训练数据里的通用行为当作平行选项。而把它定义为“硬性约束冲突裁决规则”AI的合规率会明显提高。5.2 技巧二规范保持“短而可扫读”不要写成一本书规范切忌冗长。我见过有人写了30页的AI开发规范几乎把团队所有规章制度都塞进去了。AI的上下文窗口有限规范越长注意力越分散最后反而什么都记不住。我团队现在的ROBOT.md大概在200行左右每条规则尽量压到一两句话能被AI“一眼扫完”。核心原则是规范只记录“项目内不同于通用做法的约束”通用编程规范命名、缩进之类不要重复AI的预训练知识已经够用。只有那些“违反会导致真实事故”的规则才值得写进去。5.3 技巧三正反例对照展示规则条文之外搭配1-2组正反例效果高一个数量级。例如规范里写“不要无意义地把代码改为函数式风格”AI可能还是不太明白但配上代码就容易理解// 禁止为迎合风格而引入的过度链式调用 const result users.filter(u u.active) .map(u u.name) .join(,); // 允许当数据量较小且代码可读性不受影响时可用普通循环 let names []; for (const u of users) { if (!u.active) continue; names.push(u.name); } const result names.join(,);正反例为什么有效因为AI学习到的模式是“示例驱动”模型对示例语义的推断能力强于对抽象规则的理解。一对好的正反例抵过十条冗长的规则说明。5.4 技巧四把规范纳入代码评审流程规范最终要嵌进工程流而不是靠自觉。我在代码评审模板中增加了一项“AI合规性检查”评审人需要确认本次提交是否由AI生成AI是否遵守了ROBOT.md中的所有约束如果不确定请在文档中标记AI_GENERATED_UNREVIEWED。建议把ROBOT.md的修改历史也纳入git这样每次规范调整都有迹可循也方便后续复盘什么时候改的、为什么改。评审环节里可以定期回顾“最近一个月AI违反最多的规范是哪几条”然后针对性优化措辞。5.5 技巧五定期让规范“进化”规范文档和代码一样需要持续迭代。我每个月会过一遍本月的AI辅助开发记录重点看三类问题哪些规则AI频繁违反说明规则表述不清需要优化。哪些AI“坏行为”出现多次但规范里没有说明需要补规则。哪些规则已经不再有效说明该删了过时的规则会稀释重要规则的权重。比如第一期规范里我写了“禁止使用任何AI自动生成的TODO注释”后来发现团队里根本没人遵守反而把规则集搞得很膨胀。第二期就把它删掉了。AI工具和模型能力迭代得很快一套规范用一年的情况基本不可能。保证它跟着项目一起进化才是长期有效的唯一方式。最后再分享一个在团队推广时很重要的技巧不要把规范文档命名为“限制AI”之类的负面名称命名为“AI协作指南”或“AI编码伙伴使用手册”大家更容易接受。毕竟这份文档的意义不是“防止AI搞事”而是“让AI成为真正的队友”。