
项目标题里那三个字——生成即规范只要写过一段时间AI辅助代码的人大概都能品出分量有多重。AI写得快这已经是共识了但快带来的另一个副作用是垃圾代码也在被加速生产。一个团队如果只是把AI当成更快的打字员前三个月会觉得效率翻倍到第七八个月就会发现自己被高速堆积的技术债围住了——大量局部可用、全局混乱的代码只有一次性的上下文理解没有任何结构性的约束。这一弹我想专门聊聊怎么从提示词设计、模板约束、工具链兜底这三个层面把CleanCode这条标准真正嵌进AI生成代码的过程里而不是等生成完再靠人工Review去救。内容偏实操适合已经在用AI写代码、但觉得生成一时爽维护火葬场的团队参考。1. 为什么AI编程会让技术债变得比人写的还难收拾1.1 高智商、低纪律AI写代码的本质局限先说一个我越来越笃定的判断AI写代码最大的问题不是写得错而是写得毫无纪律。一个经验丰富的工程师写代码时脑子里通常带着长期形成的约束——这个函数不能超过多少行、这里不能直接塞魔法数字、这个模块的依赖方向不能反、全局状态能不用就不用。这些约束往往不需要刻意提醒是肌肉记忆的一部分。AI完全不一样。它没有肌肉记忆只有概率预测。给它一段上文它预测下一个最合理的token应该是什么。这个最合理源自训练数据里的统计规律而训练数据里既有优秀代码也有大量平庸甚至糟糕的代码。所以你会发现一个很有意思的现象AI写一个单独的函数常常是对的甚至很漂亮但让它在一个中等规模项目里连续生成十几个文件后整体就开始走样了。有人会跨层调用不该调用的模块有人会在每个文件里重新声明一遍相似的常量有人会造出只在测试里出现一次的Mock对象。打个比方这就像一个高智商的临时工你交代一件事他能干得又快又漂亮但不会主动考虑这个活和三个月后的另一次维护之间有什么关系。他不会替你维护结构的完整性不会替你保持风格的统一更不会主动去重构那些先跑通再说的部分。这就是技术债的加速器。人类写代码积累技术债靠的是偷懒或者赶进度AI积累技术债靠的是没有长程记忆和全局责任感。更麻烦的是它的产出速度一个下午就能生成人类写一周的代码量等于你把技术债的复利周期从季度压缩到了天。1.2 CleanCode在AI时代的定义变化规范要前置传统意义上的 CleanCode是事后约束——代码写完了通过Code Review、重构、静态检查来逐步净化。这套逻辑在线下开发里问题不大因为人的产出速度有限Review 跟得上。但AI的到来改变了这个等式。我见过不少团队把AI生成的代码合并后根本不Review——或者说Review不过来。一个1000行的PR人很难从头到尾精细地看完每一行如果你的工具只有事后检查这一道防线那防线一定会被击穿。你挡不住所有问题只有把规范这个动作前置到生成这个动作里去才能从源头把垃圾量降下来。生成即规范说的就是这个不是生成完了再改而是在生成的同时就已经符合规范了。这个理念落到实操上有三个抓手把规范写进上下文通过提示词、规则文件、项目约定让AI在生成之前就知道该怎么写。把规范锁进模板用脚手架、代码骨架、目录结构把可变性约束住让AI只能在你划定的空间内发挥。把规范焊进工具链用Lint、静态检查、格式工具在合并前自动拦截而不是全指望人眼。这三件事做好了AI生成代码的技术债总量就能显著下降。下面我按这三条线逐步拆开讲。2. 把规范写进上下文提示词不只是帮我写个XX2.1 四个信封提示词设计法给AI立规矩很多人的AI编程提示词是这么写的帮我写一个用户注册接口包含邮箱验证。然后AI哗啦哗啦生成一堆代码。你一看逻辑大方向没问题但细节乱糟糟常量到处散着、错误处理风格不统一、也没有注释。这里面缺的不是能力是约束。想让AI产出规范代码提示词必须有结构、有边界、有正例和反例。我自己摸索了一套方法叫四个信封——不管项目任务多复杂提示词里至少放四类内容角色与目标告诉AI你希望它扮演什么角色比如资深后端工程师以及这段代码最终要达成什么目标。规范白名单明确列出必须遵守的编码规则比如禁止魔法数字每个公共函数必须有docstring所有外部输入必须经过校验。反例黑名单给出你不想看到的写法实例或者明确列出禁止事项比如不允许在业务代码里直接拼SQL不允许使用全局可变状态。给反例比只给正例有效得多——AI见过太多坏代码你给它列举坏样子它反而更清楚边界在哪里。输出契约约定代码之外的交付物比如除了代码还需给出测试用例清单和变更影响说明。这套提示词用起来后最大的变化不是生成代码的正确率提升了而是风格稳定性明显上升了。同一个模型加了规范约束和没加约束产出的代码质量差距能达到看起来像两个人写的。2.2 提示词里的CleanCode规则应该列到什么颗粒度有人会问规范这么多全写进提示词里不现实吧确实一条条全列提示词能写两千字然后模型上下文被占满了真正干活的余地反而小了。所以要注意编排优先级。我的经验是提示词里的CleanCode规则要分级。高优先级的是那些直接影响可维护性、难以事后修复的规则比如模块依赖方向哪一层可以调用哪一层函数长度与单一职责拒绝上帝函数错误处理策略何时抛异常、何时返回结果对象禁止全局状态与隐藏副作用命名规则类名、方法名、变量名的风格中低优先级的是那些可以由工具自动检查的比如缩进、引号风格、空行规则这些交给格式化工具就好写进提示词反而是浪费token。建议把所有规则拆分到一个.ai-rules或者CONVENTIONS.md文件里然后在提示词中引用请阅读项目根目录下的 CONVENTIONS.md严格按其编码规范生成代码不允许违反其中的任何规则如果发现规则与需求冲突请在代码注释中标注出来。这比在提示词里列十条规则要高效得多——规则文件可以常驻上下文也可以按模块分片注入不会挤占对话空间。2.3 一个可直接抄走的提示词模板这里我贴一个能用在实际项目里的精简模板覆盖常见场景。你可以按自己的技术栈调整。你是这个项目的资深工程师。下面的规则来自项目根目录CONVENTIONS.md是你必须遵守的编码契约 [在此粘贴规则摘要例如] - 所有业务逻辑只能放在service层controller只做参数解析与响应封装 - 禁止魔法数字所有常量集中到constants模块 - 函数一般不超过30行超过则必须拆分 - 所有外部输入用统一的XxxValidator校验 - 禁止使用any或Python里的裸except特殊情况须注释说明 任务实现用户注册功能包含邮箱格式校验、密码加密存储、重复注册检测。 要求 1. 按上述契约生成全部代码文件保持现有目录结构 2. 每个文件生成后附上一段说明你做了哪些决策、有哪些潜在重构点 3. 同时生成一组针对核心业务逻辑的单元测试用例测试中不要使用真实数据库 4. 生成完毕后自查一遍是否违反上述任何一条规则违反的请先自行修正为什么加第4条因为实测下来让AI生成完自查这个动作能把规则违反率再压低一截。模型在生成时注意力可能分散但你明确要求它回头检查时它会重新聚焦到规则上自动修正不少低级问题。3. 把规范锁进模板生成器的核心是约束自由3.1 约束即自由脚手架比提示词更管用提示词能解决怎么写的问题但解决不了写在哪、写成什么样的问题。AI生成代码时如果没有一个结构骨架它是不会有意识地遵守你的架构设计的。你说我们项目用三层架构它可能真的给你在三层里各放些文件但很可能这一处依赖反了、那一处又跨层访问了全都取决于它在哪个上下文片段里做预测。所以这一弹要重点讲的第二个思路是把规范锁进模板。用好脚手架和代码骨架让AI只能在预设的框架里填写内容很多架构层面的技术债就直接被消灭了。用装修来类比就特别清楚你请一个工人来刷墙与其告诉他按照装修规范刷不如直接把涂料、滚筒、分色纸都给他配齐再把施工范围划定清楚。他发挥的自由少了但出错的概率也小了。AI生成代码也一样给它一个接口模板、一组工具函数、一套目录骨架它就只能在这个空间里做填空而不是在空白画布上随意创作。3.2 目录结构即架构约束实操上我建议先把项目目录结构表达清楚再把目录结构当作提示词的一部分。比如你想要严格的分层架构在提示词或规则文件里明确src/ controller/ # 只允许放HTTP层代码不得包含业务逻辑 service/ # 业务逻辑只允许出现在这里 repository/ # 数据访问唯一入口 domain/ # 领域模型与领域服务 constants/ # 所有常量集中管理 validators/ # 统一校验逻辑然后又明确告诉AI生成的代码只能落在上述目录中。controller不允许引入repository的依赖service是业务逻辑的唯一宿主repository只做持久化不允许包含业务判断。这种目录结构加上依赖规则本质上是一种物理约束——AI即使想乱写也会在文件路径和引用关系的维度上被强烈抑制。实测下来把目录结构定义清楚之后生成的代码在架构层面的乱象会少掉一大半。原因很简单AI在生成import语句时如果看到目录规则里写明了依赖方向它大概率会遵守而如果没有这个约束它就会自由联想——今天看到张三在service里调了repository明天就会生成类似代码。3.3 接口骨架与填空式生成更深一层的模板约束是给AI预置接口骨架让它填空而不是创作。比如你写了一个 OrderService 的接口定义了createOrder、cancelOrder、queryOrderById三个方法签名然后在任务里给它请实现OrderService接口已定义不要新增公共方法。方法内部逻辑按领域规则处理。这时候AI要做的事情就非常具体了它不是设计一个订单模块而是实现三个已知的方法。它自由发挥的空间变小了但代码的确定性、可维护性大幅提升了。尤其是团队多人协作时接口先定AI生成的实现再填进去最后合出来的代码风格和结构高度一致后期维护的人不需要面对一堆五花八门的自定义结构。模板约束这块我自己在实际项目里用的一套是每个模块生成前先手工写好一个module_template.md里面包含接口定义、数据模型定义、边界说明、依赖说明。然后让AI严格照这个模板产出实现和测试。这样生成器实际上变成了填空器质量稳定得多。4. 让规范贯穿到可测性与可维护性易调测不是口号4.1 生成代码能跑与可调测的巨大差距易调测这三个字在标题里排得靠后但真做起来是区分团队成熟度的关键。很多AI生成的代码功能上是通的但你真要去调它、测它、改它会骂人。举个最常见的场景AI生成的后端接口你调用时候返回了一个错误的JSON结构可日志里只有一行汇总信息你根本不知道是哪个分支产生的错误。再或者某个服务方法内部抛了个异常你去看堆栈发现异常被吞掉了只记了句操作失败。这种代码测试起来极为痛苦——你写了个失败的测试用例想找原因可代码里没有足够的定位信息。易调测要解决的就是这个问题。我的方案是把可观测性、异常可追踪性、测试友好性作为生成代码的硬性规范而不是事后补充。4.2 把可观测性写进生成规则在提示词和规则文件里我强制要求几条所有外部接口的入口和出口必须打印结构化日志包含请求ID、参数摘要、响应状态、耗时。所有自定义异常的message里必须包含定位信息比如类名、方法名、关键参数值方便拿堆栈就能定位。禁止无脑捕获异常后只记录error捕获时必须记录完整异常堆栈。外部依赖调用DB、缓存、第三方API必须设置超时和断路器且关键路径上要有指标打点。这些规则摆出来后生成出来的代码就和能跑而已彻底拉开差距了。你在本地调试阶段打开日志就能看到一次请求的完整生命周期哪一步慢了、哪一步返回了什么一眼就能扫出来——省掉大量抱着Debugger一步步跟的时间。4.3 测试骨架让AI为自己写的代码先测一遍易测的另一个关键是让AI生成代码的同时把测试骨架一起生成了。我见过太多AI生成了一堆代码但一个测试都没有的项目。功能确实跑起来了但三个月后没人敢动那块代码因为不知道改动会不会踩碎什么。合理的做法是在生成任务里强制绑上测试要求每个核心业务方法必须附带单元测试用例。测试要覆盖主要分支而不仅仅是happy path。外部依赖数据库、消息队列、HTTP客户端一律用接口替身Mock/Stub/内存实现不允许真的连外部服务。实际跑下来AI生成的测试当然不算完美覆盖率也不会特别高。但有了骨架团队后续补测试的成本低得多——比从一张白纸开始写测试至少省一半时间。而且这些测试本身就是一种文档它们表达了AI对所生成代码的行为预期。后续改代码的人一跑测试就知道自己改坏了哪个行为定位效率会高很多。我还喜欢在生成任务上追加一句请先写测试再写实现。对AI来说这个顺序会让它更早思考这段代码应该有哪些外部行为产出的实现通常会更贴合接口契约测试也更扎实。这个顺序很多人忽略但实测下来对质量提升非常明显。5. 用工具链兜底把人盯着变成自动拦着5.1 规范要变成门禁不能只靠自觉前两招都是把规范前置到生成过程但AI永远不可能百分百遵守规则——何况模型还有随机性同一个提示词跑两次结果都可能有差异。所以必须加一道保险工具链在合并代码之前自动拦截不合规的东西。这一环节里最值得投入精力的是三件事静态检查Lint把命名、格式、复杂性规则装进CI任何违反规则的代码直接阻止合并。复杂度与坏味道检测用工具扫描圈复杂度、认知复杂度、重复代码、过长函数等指标超标的直接挂红。单测覆盖率门禁核心模块设定覆盖率下限低于阈值不允许合并。很多团队可能会说我们也有Lint啊但实际执行时经常打折——本地跑不过就--force提交或者CI只是个摆设没人真的卡。我的建议是把质量门禁做成硬门禁合并时必须全绿。AI生成时代代码量会指数级膨胀人工Review已经靠不住了只有机器门禁能稳定守住基本面。5.2 可量化的技术债体检指标别靠感觉技术债最怕的就是模糊。你说这代码有技术债我说还行吵半天没结果。要治理它必须把技术债翻译成可量化的数字。我在多个项目里沉淀了一套技术债体检指标放在CI里定期跑指标健康阈值超标的典型信号修复建议圈复杂度单函数 ≤ 10函数里的圈复杂度高于15说明分支太多逻辑难测试拆函数引入状态策略或表驱动重复代码率≤ 3%超过5%说明大量复制粘贴一改漏几处提取公共函数或模板注释密度关键公共接口 100% 注释公共方法无docstring说明为什么没留存补注释只写为什么不写是什么覆盖率核心模块 ≥ 80%低于60%改代码等于盲飞先补核心链路的测试依赖层级违规0有跨层import说明架构在腐烂按依赖规则修复全局可变状态0有global/static可变对象并发隐患改成不可变或显式上下文传递有了这些数字技术债就不再是感觉问题而是报表上的具体数字。每次迭代跑一次体检你就能看见这周我们又引入了多少债、还了多少债。这个反馈闭环非常重要——它让规范落地有了数据支撑也让管理层能看清楚代码质量不是玄学。5.3 门禁过严会逼出绕过机制治理要留出口这里有一个必须提醒的坑门禁太严格、又没有申诉出口团队就会开始绕。常见的是改Lint配置、把检查命令从CI里删掉、或者找绕过检查的提交姿势。这事我踩过教训很深。所以我在设定门禁时留了三道口子紧急热修复可以带warning合并但必须12小时内补修复单。对规则的自定义要透明任何人想改规则必须提出书面理由比如这条规则对这个场景不适用经评审后改而不是顺手就关。门禁拦截的问题要可追溯每次被拦下要有清晰的提示说为什么被拦、应该怎么改。如果门禁只报错不给解法团队的挫败感会很高。工具链的本质是自动提醒不是自动惩罚。它应该帮人减少决策负担而不是增加心理抗拒。把门禁设计得友好大家才愿意配合。6. 常见坑:AI生成CleanCode时我踩过的那些雷6.1 AI的过度抽象陷阱一开始用约束规则时我把提示词里写了遵循DRY原则不要重复自己结果AI把三处用途完全不同的代码硬抽成了一个魔改函数参数加了六个默认值套默认值调用处各种传参绕圈子。表面上没有重复实际上比重复还难读。后来我把规矩改细了允许小范围重复禁止过早抽象。规则描述改为如果同一结构的代码出现三次以上才考虑提取两次或少于两次宁可复制也不要强行抽象。提取时公共函数必须有清晰的单一职责和完整测试。这个微调之后生成代码的可读性提升非常明显。这个坑其实很有代表性CleanCode的很多原则字面上看是对的但如果AI不理解上下文语境会机械地执行一条规则而破坏另一条更重要的规则。规范规则要表述得带条件而不是绝对命令。6.2 偏好一次性代码为特殊场景生成的代码污染全局另一个常见现象AI为一个特定需求生成的代码里面带的特殊处理逻辑会蔓延到好几个文件里去。今天你让它实现订单过期自动取消它会在OrderService、OrderScheduler、OrderRepository三个类里各放几行关于过期的判断既不集中也不分层。后期你要改过期时间从24小时改成48小时得全局搜索还是容易漏。对付这个问题我在规则里加了一条所有时间窗口、状态机转换、支付结算等涉及业务规则的逻辑必须集中到domain层或configuration里业务层只允许调用不允许四处散落规则判定。有了这个约束后生成代码里的规则就集中得多了改一处就生效维护成本大幅下降。6.3 测试替身滥用Mock到没意义AI很爱生成Mock因为Mock能立刻让测试跑通。但一个测试如果Mock掉了几乎所有依赖那它其实什么都没测到——它只是在验证AI自己构造的剧本。有一阵子我发现团队里一堆单测跑得飞快、全绿但根本抓不住回归问题。后来我专门查了一下发现大量测试都是All friends mocked, no assertion on real behavior。我在规范里加了一条测试必须对真实行为做断言外部依赖用轻量级替身如内存版Repository不鼓励对内部私有方法做Mock。禁止对纯函数Mock。这条加上后测试质量有明显回升。AI生成的测试更偏向行为验证而不是自导自演。6.4 注释成为噪声还有一个很反直觉的坑AI生成的注释往往是噪声。它特别喜欢写这是一个创建订单的方法这种毫无信息量的注释——你说的是是什么我看代码就知道了。我要的是为什么为什么要校验库存、为什么要用分布式锁、为什么这个分支在并发时会走向这里。所以我在规则里明确注释只写为什么不写是什么。公共方法和复杂分支必须有注释说明设计意图代码本身要表达是什么。有了这条约束AI生成的注释明显收敛也更有价值。它可以写这里先更新库存再创建订单是为了避免并发下超卖而不是更新库存。6.5 生成的异常处理太重或太轻异常处理是AI代码里最两极分化的地方要么是全部try-catch吞掉导致错误完全不可见要么是到处throw笼统的RuntimeException调用方根本不知道该怎么处理。两种情况都会给调试和生产带来很大麻烦。我的规则是业务层只抛出明确的业务异常技术层异常向上传递时保留堆栈跨系统调用时必须捕获并包装为带错误码的领域异常。另外异常信息里必须包含足够的上下文比如用户ID、订单号这对排查线上问题简直是救命级别的。7. 这一弹的收尾说说我实测下来的体会第36弹了想聊点没有什么排版的体会。CleanCode和AI编程结合这件事一开始我以为是个技术问题做久了发现更多是工程纪律问题。AI这个协作对象能力强、脾气好、努力不抱怨但它没有方向感也不会主动维护你的架构秩序。你要么花力气把它训练成懂规矩的团队成员要么就只能天天给它擦屁股。我个人实测下来最有效的时间投入其实就是最开始那两三天把项目规范整理成机器可读的规则文件、把模板补齐、把CI门禁建好。这笔投入会在后面每一个生成任务里不断复用省下来的Review和返工时间远远超过最初的投入。另外想强调一句别指望一个万能生成器能解决所有项目的代码质量问题。每个团队的技术栈、架构风格、领域约束都不一样规范必须定制才能落地。通用的CleanCode规则是骨架你自己的项目和团队文化才是血肉。要是你也在做类似的事建议从一个小模块开始试先写规则文件再做模板约束最后挂门禁。跑两个迭代看看数据再决定要不要推广。这套方法不挑语言、不挑框架核心思想是一致的——AI负责快规范负责稳人来定义什么是对。最后分享一个让我觉得值回票价的小配置把规则文件放进AI的上下文里再在每次生成任务末尾加一句请先自查是否违反规则并列出你违反的地方以及如何修正。就这么一句话AI生成代码的规范违反率能降两到三成强烈建议试试。