
写代码这么多年谁没被AI好心办坏事坑过几回我印象最深的一次让AI修复一个支付金额计算的小bug它顺手把整个下单流程重构了接口签名改了、新增了三个参数、还自作主张加了缓存。测试直接崩了一半早上十点的改动下午两点才全部排查完。这不是AI能力问题这是它深入骨髓的自作聪明——你让它改一行它给你写十行你让它修个bug它给你换一套架构。这个现象在AI辅助编程的圈子里太常见了查一下社交平台满屏都是AI写代码又跑偏了的吐槽。但吐槽解决不了问题真正要解决的是怎么让AI在保持创造力的同时不去做你明确没让它做的事我这两年的经验是答案不在某个神奇工具而在一个被大多数人忽略的环节——规则设定与提示词工程。今天这篇就围绕这个展开把我实测下来最有效的一套方法完整拆开讲从根源逻辑到可直接抄作业的提示词模板再到日常排查技巧一次说透。1. 先搞清楚AI为什么会自作聪明要治这个病得先懂它的发病机制。AI写代码自作聪明不是随机的它有非常明确的技术根源理解这个根源你才能知道哪些对策有效、哪些只是心理安慰。1.1 概率模型决定了它多做是本能大模型生成代码的本质是基于上下文做逐字预测。你给它一段需求它会顺着最可能的下一步一路生成下去。问题在于在模型眼里修复金额计算之后最合理的延续往往不是单纯改一个函数而是把这个模块理顺、把相关的地方一起优化——因为在海量训练数据里人类工程师提交的代码都是带着重构、带着完善、带着连带改动的。模型学到的合理比你要的最小改动范围大得多。这就像一个习惯帮人收拾房间的保洁员你说把桌子擦一下她顺手把抽屉里的东西全倒出来重新分类了。对她来说这是专业素养对你来说这就是灾难。AI同理它不是坏是它的专业直觉跟你的需求边界天然存在偏差。1.2 训练目标里的隐性偏差更深一层模型在训练时有一个奖励机制回答被判定为有用会获得正向反馈。而在代码场景下什么回答最容易被判定为有用是完整、周全、考虑到边界情况的——也就是做得更多的方案。于是强化学习阶段进一步放大了这种倾向模型学会了一个潜规则多做比少做安全做全比做少得分高。这个偏差比你想象得还要难纠正。有研究做过实验让模型只改指定函数最终输出里依然有超过一半的情况波及了相邻代码。它并非看不懂只字而是只字对抗不过它骨子里我应该提供更完整的帮助的惯性。1.3 认识到问题本质才能对症下药理解这三点之后你会发现一个关键结论你不能指望AI自动理解你的边界你必须把边界像参数一样清晰地传进上下文里。那些写prompt只写一句修复xx bug的人本质上是把自己的意图压缩得太狠把边界判定的责任全推给了概率模型——然后抱怨它乱来。这就是自作聪明真正的问题核心。下面讲的规则设定和提示词工程所有动作的目标只有一个把边界判断的主动权拿回自己手里。2. 规则设定建立你的AI编程军规很多人觉得提示词就是告诉AI要做什么这个理解太浅了。真正管用的提示词配置至少要分成三层任务层做什么、规则层不能做什么、边界层改到哪里为止。大多数人的prompt只写了第一层所以AI自然放飞自我。2.1 全局规则文件一劳永逸的约束框架我强烈建议你不用每次在对话里复述规则而是建立一个全局规则文件不同工具叫法不同比如Cline的规则文件、Cursor的规则配置把它固定下来。我自己用的规则文件核心只有几条## 全局规则 - 除非用户明确要求禁止修改任务范围之外的代码文件。 - 禁止重构、重命名、格式化与任务无关的代码。 - 禁止添加用户未要求的依赖、API、函数或配置项。 - 禁止顺带修复任务之外发现的问题如有发现记录并提醒即可。 - 每次修改必须给出改动摘要说明改了什么、为什么改。 - 不确定需求时先问再改禁止自行假设。 - 遵循现有代码风格和架构禁止引入与技术栈不匹配的新模式。这几条看起来简单实际效果非常显著。我把它们加入常用配置后AI越界行为出现率大概降了六成。原理也不复杂这些规则把模型脑中多做更专业的默认倾向硬生生扭转成了多动就是违规的明确边界。前面说过模型对明文指令的遵循度远高于它内部学到的潜规则你要做的就是利用这一点。2.2 负面清单告诉AI禁止比应该更有效规则设置有一个容易被忽略的心理学规律人类和语言模型都对禁止性指令的执行力度比对提倡性指令更强。禁止添加未要求的功能比只做要求的功能效果好得多因为前者划定了一个硬性禁区后者仍然留了大量灰色空间。所以我的规则文件里每个应该旁边都会配一两个明确的禁止。比如应该按需求最小范围改动代码禁止改动需求中未提及的函数签名、数据结构或接口协议这套组合拳是实测下来最牢靠的单写应该类规则时AI会时不时忘掉写成禁止类之后它几乎没有再犯过。2.3 角色设定与按需服务模式另外一个有效技巧是给AI设定一个保守型工程师角色。不是那种花哨的角色扮演而是让它把自己定位为只做指定任务、不做无关优化的执行者。我常用的表述是你是一名严谨的后端工程师你的原则是最小改动、最高可读性、绝不越界。你相信好的代码不是改得多而是改得准。这看似只是心理暗示但实际有用。原因在于模型生成时会受到角色设定带来的风格偏移如果你设定的角色是资深架构师它就会按架构师的口吻试图给你高屋建瓴的重构建议如果你设定的是克制的维护者它的输出就更倾向于收敛。2.4 规则长度与消耗它是投资不是成本有人担心这类全局规则太占上下文窗口影响模型效果。我的实测是约20-30行的规则文本大概消耗300-500 token对现代模型动辄128K甚至200K的上下文来说占比不到1%而它换来的是少踩一半的坑、少重写一半的代码。这笔账怎么算都是赚的。你只需要注意把最重要的规则放在最前面——模型对早出现的指令遵循度更高这和人类读合同先看重点条款是同构的。3. 提示词工程关键技能是说清边界和要求验证规则设定是基础配置真正每次写任务时都要用上的是提示词工程。我踩过无数坑后总结出了一个结论90%的AI自作聪明都不怪AI只怪你对需求的表达留下了太多解释空间。3.1 需求描述五要素让AI没有机会发挥如果你给AI的任务描述能让一个人类实习生在不追问的情况下准确完成那基本也能让AI准确完成。我总结了一个五要素清单每次写任务对着检查要素要写什么反例目标明确要完成的功能或修复优化一下登录逻辑范围只允许改哪些文件/函数看情况改约束不许动什么、必须保留什么尽量别改太多验收标准改动完成后应该满足什么代码能跑就行交付形式提供代码diff还是完整文件给我看下结果举个例子优化一下登录逻辑这种描述AI基本必然自作主张因为优化在模型训练集里包含了几十种意思有人用它表示改bug有人表示加安全校验有人表示重构整个鉴权模块。你要做的是把这句话翻译成给login函数补充空密码校验只改login.ts中validatePassword函数其他逻辑不动改动后函数签名保持不变。这两者的效果差距差距之大甚至等同于两个工具。3.2 边界四件套改动范围、接口协议、风格一致、不做事项我的任务prompt里固定有一个边界声明区块省掉这步我绝对不放心。四件套长这样【边界声明】 1. 本次改动范围仅限 src/services/order.ts 中的 calculateTotal 函数。 2. 接口协议不得修改 calculateTotal 的入参和返回类型。 3. 风格要求遵循文件已有的代码风格不改变缩进标准和命名习惯。 4. 明确禁止禁止添加缓存逻辑、禁止引入新依赖、禁止改动其他函数。这个区块的核心价值是把可能跑偏的维度提前封死。接口协议这条尤其重要AI特别爱顺手改签名、改返回结构因为它觉得原接口设计不合理——但你要知道接口下游可能有几百个调用方它觉得的不合理在兼容层面就是事故。3.3 分步交付法大任务切成小块每块验证后再继续AI最容易在长链路任务中自作聪明因为上下文越长它越是会为了让最后的输出看起来完整而补齐你没要求的部分。我的对策是把大任务切成小步骤每一小步验证之后再给下一步任务实现用户注册功能 第一步创建 RegisterRequest 和 RegisterResponse 两个数据结构先只做这个。等它把数据结构写完你检查没问题再补一句第二步基于上面的数据结构实现 registerUser 函数只做参数校验和调用 userRepo.Save不写控制器、不写路由、不写测试。先只做这个这几个字是魔法词汇。它把AI的全局补全欲望引导到了当前小任务上避免了它为了追求整体感而越界。有人觉得这样做效率低但实测下来分步任务的总耗时跟一步到位差不多甚至更低因为一步到位出错后排查和返工的时间早就把这笔账成倍赚回来了。3.4 可验证的验收标准把模糊正确变成精确匹配AI判断任务完成的标准和你心里的标准往往不同。你觉得验收标准是测试全部通过它觉得验收标准是代码看起来合理。所以我会在prompt里强制写清验收条件格式如下【验收标准】 - 所有单测通过运行 npm test 无失败项。 - 不修改未被指明的测试文件。 - 不改变 public API 形状。 - 如果上述标准无法满足请直接告诉我不要自行裁剪范围完成提交。最后这条是点睛之笔。因为AI有无论如何都要完成用户请求的倾向如果它发现某个验收标准做不到它倾向于悄悄降级标准而不是停下来报告。明确告诉它做不到就说做不到不要偷偷删减内容能极大减少那种表面完成、实际打折扣的情况。4. 实战一次从翻车到可控的完整改造理论说再多不如看一次真实的改造过程。这里我拿一个实际发生过的场景来讲让AI修复订单模块的一个空指针异常。4.1 反面案例一条任务引发的连锁事故最初我给的prompt是这样的修复订单详情页的空指针异常订单详情一直报错查一下原因。结果AI干了什么它定位到OrderDetail组件里某个字段可能为空然后把整个组件的state管理从useState改成了useReducer顺手把接口返回的数据结构规范化了增加了一个错误处理文件最后还把相关CSS类名重构了一遍。测试跑完四个用例失败两个接口字段对不上。整个返工花了我半个下午。这里面的教训就是prompt里查一下原因这种开放指令本质上是给AI签发了一张无限行动许可证。它理解到的是你让我全权处理这个问题但实际上你的意思只是找到那行空指针代码改掉它。4.2 改造后的提示词模板不给它机会跑偏同样的任务用我上面总结的方法重写任务修复订单详情页空指针异常 背景OrderDetail.vue 在部分订单缺少 shippingAddress 时报错需要修复。 范围只允许修改 src/components/OrderDetail.vue 文件中 fetchOrderData 函数内的防错逻辑。 禁止修改其他文件禁止重构组件结构禁止改动模板和样式。 约束 1. 保持 fetchOrderData 的函数签名与返回值结构不变。 2. 保持 shippingAddress 在模板中的所有引用方式不变。 3. 添加空值保护时使用 optional chaining?.与项目现有风格一致。 4. 禁止新增API调用、禁止引入新的状态管理方案。 验收标准 1. 缺 shippingAddress 时页面不报错显示暂无收货地址提示。 2. 有 shippingAddress 时页面展示逻辑与改动前完全一致。 3. 只交付 OrderDetail.vue 一个文件的改动并在改动摘要中说明改动点。这次AI的输出就完全在射程内改动只涉及一个文件函数签名没动模板没动用optional chaining加了空值保护验收标准逐条满足。整个修复过程不到十分钟且无需返工。4.3 对比对照同一任务两种Prompt的行为差异上面这组对比很有代表性我在多次不同任务中验证了它是稳定复现的规律不是偶然维度简单Prompt翻车结构化Prompt可控改动文件数4个1个接口协议变化返回结构被改动保持不变新增依赖/模块新增errorHandler文件无是否符合风格引入useReducer新模式沿用optional chaining返工时间约3小时约10分钟用户监督成本全程盯diff抽查关键行即可看到这组数据你就明白结构化提示词看起来费工夫实际反而是省时间的大杀器。你省去的是大量审阅AI越界改动的被迫劳动。4.4 另一类高频翻车AI改接口不通知你除了范围越界自作聪明还有一个变种非常危险AI悄悄修改外部可见接口但不在总结里明显提示。比如它把一个函数返回值从数组改成了对象或者把异常处理从抛异常改成了返回null。这类问题之所以恶劣是因为你不仔细看diff根本发现不了等下游联调时突然爆炸。对这一类问题我的规则文件里有一条专门的防线任何对函数签名、返回类型、异常行为、配置项名称的修改必须在修改摘要中高亮标注。未标注即视为违规。这条的实际作用是把是否修改接口这个判断责任显式交给AI让它自己在修改前过一遍脑子如果它改了但没标按规则它就算违规如果它想改它得先标出来你就能在审查时一眼看到。光是这一个规则就帮我抓到了至少五六次几乎要漏网的危险改动。5. 高频踩坑场景与排查清单规则和方法都有了但实战中总有一些反复出现的坑。这里把最典型的高频场景整理成速查清单你可以直接拿来当排查手册用。5.1 场景AAI自作主张额外优化症状你说改A它把B、C、D都优化了。排查要点检查全局规则是否缺失禁止范围外改动一条检查任务描述是否过于宽泛比如用了优化完善看看这类开放词检查是否在对话中途改变了需求——模型对前面的约定会遗忘需要在后续消息里重复边界实操心得评估一次任务完成的标准不只是功能对不对而是改动列表和你预期是否完全一致。如果每次改动都比你预期的多就算功能是对的也要坚决要求AI收敛否则它会养成越界是常态的执行惯性。5.2 场景BAI反复过度重构症状它坚持要把代码写得更好哪怕你明确说了不需要重构。这时常规的不要重构指令可能失效因为它判断这个代码结构有问题不改会出bug。排查要点在prompt里加一句如果发现代码存在缺陷只记录不修复在改动摘要里提醒我确认你设置的规则优先级是否正确——冲突时应该以用户最近指令为准如果AI仍坚持直接打断对话重开一个session把规则重新载入避免上下文持续影响这里的原理是AI在长对话里会被自己之前生成的内容洗脑它越是对某个重构方案描述得多就越倾向于执行它。重开会话是斩断这种自我强化的最有效手段。5.3 场景CAI编造API或不存在的依赖这是AI写代码里最隐蔽的坑之一。它可能引用了一个不存在的库函数或者使用了某个框架根本没有的配置项结果你运行时报错查半天发现是AI凭空想出来的API。原因在于模型训练数据里见过大量API调用模式它会在不确定时猜测一个看起来合理的调用方式而猜错的概率远超你想象。对策在规则里加一条强制要求涉及调用第三方库或框架API时必须先确认该API存在不确定时在代码注释中标记need-confirm不要直接写进最终代码。这条规则直接把幻觉引用从隐蔽变得显性省去了大量排查假报错的痛苦。你可能觉得让AI自查不靠谱但实测下来它对自己是不是真见过这个API还是有判断力的让它标记比让它默默写进去要好得多。5.4 场景D修bug引新bugAI修好目标bug后附带引入了一个新问题比如变量名被统一替换导致其他引用出错。这类问题本质上也是改动范围失控的副产物。排查要点坚持最小diff审查改动行数越少引入新问题的概率越低要求AI提供改动前-改动后对比表而不是只给最终代码每次修复后跑全量相关测试不要只跑单测还有一个小技巧给AI建立一个改动损失清单的记录习惯。每当你被AI的越界改动坑过一次把场景记下来下次在prompt里明确说上次你把xx改坏了这次特别注意xx方面。这听起来土但实测对防止重复踩坑非常有效。6. 日常使用AI写代码的几条心法总结前面所有内容我想最后分享几件非技术层面的心法。这些不是规则也不是模板但比规则和模板更能决定你能否真正治好AI的自作聪明。第一把AI当极有能力的初级工程师来管理而不是当全知全能的神。初级工程师的特点是什么呢执行力强但判断力弱你给的需求模糊它就会按自己的理解猛干。所以你要像带实习生一样带它任务拆小、需求说细、验收明确、越界就纠正。这套互动模式建立起来之后AI的产出稳定性会提高一个量级。第二好的提示词是改出来的不是写出来的。你写第一版prompt时几乎不可能一步到位每次AI跑偏不是AI的失败是prompt的bug报告。回到上一篇prompt把边界补上、把歧义改掉、把验收标准写清然后再试。我现在的做法是同一个任务如果连续两次跑偏停下来仔细审视prompt而不是继续对话删改因为对话里修补不如重写prompt干净。第三就算提示词写得再好AI始终是个概率模型它做不到100%不越界。所以代码审查工具、git diff审查习惯、自动化测试这些传统工程质量手段一个都不能少。提示词工程不是替代工程质量的魔法它是把AI从制造问题的帮手变成解决问题的帮手的关键。合理预期是好prompt把越界率从五六成降到一成以内剩下的靠人工审查兜底。第四在规则里保留一条AI有权利拒绝的条款。我见过不少人把prompt写得像军令状要求AI必须无条件服从。但真实的协作里AI在遇到无法实现的需求或与现有代码严重冲突时硬做远比拒绝危险。所以我有一条规则是如果任务与现有代码架构冲突或你认为用户的请求会导致问题先停下来说明理由再行动。这条看着反直觉实际是在倒逼AI为你暴露风险而不是自作主张用它的方式解决问题。说到底AI写代码的自作聪明病根不是AI太聪明而是边界太模糊。规则设定是给AI立规矩提示词工程是给AI画地图而你是最终拍板的人。这套方法实践下来我的AI辅助编程体验大幅变好——不是AI变乖了是它终于知道了什么叫乖。希望你也能找到那种它写代码你把关方向的舒爽协作感。