← 返回教程库

把错误变成规则:踩坑后回写规则文件让AI不再犯

最后更新 2026-06-25
你将学到
  • 理解为什么AI会重复犯同类错误,以及规则文件是唯一系统性的解法
  • 掌握"发现错误→提炼规则→写入文件→验证生效"四步飞轮的完整操作
  • 学会写出真正有效的规则:具体、可执行、带正反例
  • 建立定期整理规则库的习惯,让规则文件越用越精而不是越积越乱

你花了二十分钟纠正 AI:不要用 any,Repository 层不要直接抛原始异常,API 返回必须统一包一层 { success, data, error }。它改好了,你满意了,会话结束。

第二天新开一个对话,同样的问题,它照犯。

这不是 AI 变笨了,也不是你记性差。AI 本来就没有跨会话记忆——每次新对话都是白纸一张,你上次的纠正连一个字都没留下来。

很多人的应对方式是忍:每次开对话都重新交代,或者改完就算了。但如果你每天用 AI 写代码,同类错误你会碰到几十次、几百次。与其每次都亲手救火,不如把每次踩的坑固化成规则,让规则文件替你盯着 AI,下次自动避开。

这就是本篇要讲的飞轮:踩坑 → 提炼规则 → 写入规则文件 → 验证不再犯


为什么AI会重复犯同样的错

AI 生成代码的方式是在当前对话的上下文里预测最合理的输出。它没有"记得上次你骂过它"的机制,它只看这次对话里有什么信息。

这意味着:

  • 你的纠正不会自动存档。你在对话里说"不要这样写",它这次会改,但那句话随着会话关闭一起消失了。
  • AI 的默认行为有偏向。比如 TypeScript 里它默认愿意写 any,因为训练数据里到处都是这种写法。你不明确禁止,它就继续写。
  • 每次新任务都重置。就算是同一个项目,新开对话后 AI 对你项目的"了解"完全来自它当次能读到的文件,之前你口头交代的全没了。

所以规则文件的作用不是让 AI 变聪明,而是把你的约定变成 AI 每次启动都能看到的书面材料。相当于给新入职的员工一份写清楚了的工作守则,而不是靠每天口头提醒。

关于规则文件的存放位置和生效方式,见上一节:CLAUDE.md / .cursor/rules——项目规则文件写法与实战,和 AGENTS.md 跨工具配置标准。本篇专注讲怎么从错误里提炼规则、写进去、让它真的起效


飞轮:踩坑→回写规则→不再犯

这个飞轮只有四步,但需要你养成习惯,才能真正转起来。

第一步:发现错误,识别是不是"类型问题"

AI 犯的错有两类:

  • 一次性的:比如它误解了你这个函数的具体业务逻辑。改完就行,不用写规则。
  • 类型性的:比如它总是在没有 try/catch 的地方直接 throw,或者总是把中文注释写成英文,或者总是用 var 不用 const。这类错误下次还会犯,值得写规则。

判断标准很简单:如果你改这个问题的时候,脑子里冒出来的是"这是第几次了",就该写规则。

第二步:提炼成一句明确的规则

这是最关键的一步,也是最容易写废的地方。

错误的提炼方式:

"写代码要规范一点"

AI 看到这句话,完全不知道该改什么行为。

正确的提炼方式:

"TypeScript 中禁止使用 any 类型。如果类型不确定,用 unknown 并在使用前做类型收窄。"

规则越具体,AI 越能照做。后面会专门讲规则怎么写才有效。

第三步:写进规则文件

选对文件位置:

  • 只有这个项目里才有这条规则 → 写进项目根目录的 CLAUDE.mdClaude Code 用)或 .cursor/rules/(Cursor 用)
  • 所有项目都适用 → 写进全局规则文件(~/.claude/CLAUDE.md 或 Cursor 全局设置)
  • 跨工具、需要在 CI 环境也生效 → 同步写进 AGENTS.md

写的时候,把规则加到已有的规则文件里,不要新建太多文件。规则库越集中,AI 越容易加载完整。

关于上下文加载效率,见 上下文工程:管 Token、防飘移,规则文件也是 Token 的一部分,写太啰嗦会影响实际效果。

第四步:验证不再犯

规则写完不代表一定生效。用一个新对话验证一下:

  1. 新开对话,进入同一个项目目录。
  2. 给 AI 一个容易触发这个错误的任务(比如"帮我写一个用户服务的 TypeScript 函数")。
  3. 看它输出的代码里,之前的问题还在不在。

如果还在,说明规则写得不够具体,或者 AI 加载上下文时没读到这个文件。调整规则措辞,或者检查文件路径是否正确。


规则怎么写才有效

有效的规则有三个特征:具体可执行带正反例

特征一:具体,不说废话

无效写法 有效写法
代码要写好 所有函数必须有 JSDoc 注释,至少包含参数说明和返回值描述
错误处理要注意 所有 async 函数必须用 try/catch 包裹,catch 块里要记录日志,不能只是 console.log
不要用不好的写法 禁止使用 var,使用 const;只在需要重新赋值时使用 let

特征二:可执行,给 AI 明确的行动路径

"注意安全"是没法执行的。"所有 SQL 查询必须使用参数化查询,禁止用字符串拼接构造 SQL" 是可以执行的——AI 知道该做什么、不该做什么。

涉及分叉判断的规则,要把每条分支都写清楚:

// ✅ 可执行
API 响应格式统一使用:
- 成功:{ success: true, data: <结果> }
- 失败:{ success: false, error: { code: string, message: string } }
禁止直接返回裸数据或裸错误信息。

// ❌ 不可执行
API 返回格式要统一

特征三:带正反例,消除歧义

对于容易出现"它以为它照做了"的规则,加上正反例:

TypeScript 枚举使用规范:
// ✅ 正确:用 const enum
const enum Direction { Up, Down, Left, Right }

// ❌ 错误:不要用普通 enum(会生成多余的 JS 对象)
enum Direction { Up, Down, Left, Right }

AI 看到正反例,会非常精准地知道你要的是什么。


定期整理规则库

规则文件会随着时间积累越来越多。如果不定期整理,它会变成一堆互相矛盾、过时的条目,反而让 AI 困惑。

建议每隔 1-2 个月做一次整理,步骤如下:

删过时的:技术栈换了,某条规则已经不适用了(比如你从 CommonJS 迁到 ESM,之前"用 require 不要用 import"这条就该删)。

合并重复的:有时候你会发现两条规则说的是同一件事,只是时间不同加的,表述有轻微差异。合并成一条,以最新、最具体的表述为准。

给规则分组:随着数量增多,加个小标题会让 AI 加载时更容易理解结构:

## 代码风格
- ...

## 错误处理
- ...

## API 接口规范
- ...

## 禁止事项
- ...

请 AI 帮你审一遍:把整个规则文件丢给 AI,问它"这里面有没有互相矛盾的规则,或者描述不够清楚的地方"。它往往能发现你自己看不到的问题。


从错误提炼规则:模板和真实例子

提炼模板

每次发现 AI 犯了类型性错误,用这个模板记录:

【错误描述】AI 做了什么:_____
【为什么不对】期望行为是:_____
【提炼的规则】(用一两句话,具体可执行):_____
【正例】(可选,但推荐写):_____
【反例】(即刚才 AI 做的事):_____

记录完之后,把"提炼的规则"那一行,连同正反例一起,添加到规则文件里。


真实例子一:TypeScript 类型逃逸

错误描述:写 Express 中间件时,AI 把 req.user 标注成了 any,而不是项目里已经定义好的 AuthUser 类型。

为什么不对:用了 any 就等于关掉了这部分的类型检查,中间件里出了类型错误运行时才能发现,不是编译期。

提炼的规则

禁止在代码中使用 any 类型。
- 如果类型暂时不确定,使用 unknown 并在使用前做类型收窄(typeof / instanceof 判断)。
- 如果是第三方库的类型,在 @types/xxx 里找或者手写类型声明,不要用 any 绕过。
- 如果是项目内已有的 AuthUser、ApiResponse 等类型,必须从对应的 types/ 目录导入,不要重新定义。

写进 CLAUDE.md 后,下次让 AI 写 Express 中间件,它会自动从 types/ 目录导入类型,不再写 any


真实例子二:数据库操作没走仓库层

错误描述:在 UserService 里,AI 直接用 prisma.user.findMany() 查数据库,而不是调用 UserRepository

为什么不对:这个项目规定所有数据库操作走仓库层,Service 层不直接操作 Prisma,目的是让 Repository 层可以被单独 Mock 测试。

提炼的规则

项目架构分层规范:
- Service 层(src/services/)不直接使用 prisma 客户端。
- 所有数据库操作必须通过 Repository 层(src/repositories/)。
- ✅ 正确:UserService 调用 userRepository.findById(id)
- ❌ 错误:UserService 直接调用 prisma.user.findUnique({ where: { id } })

写进规则文件后,AI 在写 Service 时会自动找对应的 Repository,而不是直接操作 Prisma。


常见问题

Q:我写了规则,AI 好像没按规则来,是没读到吗?

有几个原因要逐一排查:一是文件路径不对,CLAUDE.md 要放在项目根目录,或者你启动 claude 命令所在的目录;二是规则写得太模糊,AI 读到了但不知道该怎么改变行为;三是规则和任务描述之间有冲突,任务描述里隐含的需求覆盖了规则(这时候你需要在任务里主动提一句"按规则文件里的分层要求来")。最直接的排查方式:在 Claude Code 里问它 /status,看一下它加载了哪些上下文文件。

Q:每次犯一个错就要去改规则文件,感觉很麻烦?

踩坑当下改规则文件需要一两分钟。不改的代价是每次碰到同类问题都要花时间纠正,而且错误可能已经进了代码库。量大了以后,几分钟的规则投入会省掉几十倍的纠错时间。不过你也不用每次都当场去改文件——养成一个习惯:每天结束工作前花五分钟,把今天碰到的"AI 又犯了同样的错"提炼成规则,一次性写进去。

Q:团队用同一个项目,规则文件谁来维护?

规则文件纳入 git,用 PR 评审来维护最稳——改规则等于改项目约定,应该经过至少一个人的确认。如果团队里有"AI 编程负责人"或者技术 Lead,规则文件由他主导维护,其他人提 issue 或者 PR 来添加。另外,全局规则~/.claude/CLAUDE.md)是个人的,不纳入 git,那是你自己的编程习惯偏好,不用和团队同步。

Q:规则文件会不会影响 AI 的灵活性?

写得太死会影响。规则要管"规范性底线",不要管"实现思路"——比如"禁止用 var" 是规范,不影响 AI 怎么组织逻辑;但"所有列表处理都必须用 reduce" 就是在限制实现思路,这类规则不要写。好的规则文件让 AI 在正确的轨道上自由发挥,而不是把每一步都规定死。

Q:规则文件越来越长,会不会消耗太多 Token 影响效果?

会的。规则文件本身也是上下文的一部分,写得又长又罗嗦,真正有用的任务描述能用的 Token 就少了。保持规则简洁(一条规则一两句话),定期删过时的,是控制 Token 消耗的关键。具体的 Token 管理策略见 上下文工程:管 Token、防飘移


👉 看看我们的 AI 编程实战体系课,或逛 AI 编程教程大全 把基本功打扎实。

📄 来源 / 自校链接

本文为学习整理,关键步骤与代码请结合下列官方来源验证。

内容有错、看不懂、或想看下一期?告诉我们 →

本文为学习与落地整理,AI 工具与平台更新较快,关键步骤请结合官方最新资料验证。见免责声明