这是一份我写给自己的 Cursor 全局规则(
code-rules.mdc),每次对话都强制生效。它不是流程模板,而是一组「写代码时的底线」------无论走不走工作流,都得守。
为什么需要一套「底线规则」?
用过 AI 编程工具的人大概都有体会:AI 写代码容易「用力过猛」。
- 你让它改一个小 bug,它顺手帮你重构了半个文件;
- 你让它加个功能,它在项目里留下一堆临时脚本和调试日志;
- 你让它修个报错,它把异常
catch掉返回个默认值,bug 看着没了,根因还在; - 你让它写注释,它把
let a = 1解释成「声明变量 a 并赋值为 1」。
这些问题单看都不大,但叠在一起,代码库会迅速变得难以审查、难以维护。尤其是当你用 Cursor 这类工具频繁让 AI 动代码时,每一条 diff 都需要人来 review,AI 的「自由发挥」会直接拖垮 CR(Code Review)效率。
所以我写了这份 code-rules.mdc,核心目标只有一个:让 AI 的每次改动都尽量小、准、可读、可审。
下面逐条拆解。
规则总览
| # | 规则 | 一句话 |
|---|---|---|
| 1 | 禁止临时文件 | 不在项目内留调试脚本、日志、草稿 |
| 2 | 抽函数要克制 | 别为了「好看」就包一层 function |
| 3 | 用简体中文 | 给人看的都用中文,给机器看的不动 |
| 4 | 动手前先读 | 不凭记忆编造接口,复用本仓写法 |
| 5 | 改完自检 | 改了相关代码才跑检查,不空转 |
| 6 | 定位根因 | 禁止空 catch、默认值藏错误 |
| 7 | 回复先给结论 | 短句、完整句,不复述工具过程 |
1. 禁止在项目内创建临时文件
禁止在项目内创建临时文件(调试脚本、日志、备份、草稿、未请求的文档)。用户要求的正式文件除外。
这是最常见也最恼人的问题。AI 为了「验证一下」,会在项目里建个 test-temp.js、debug.log、backup-old.js,然后忘了删。这些文件进入 git,污染 diff,还会被后续的 linter、构建工具误抓。
底线:项目里只放正式文件。要验证就说明,别偷偷建文件。
2. 抽函数是为了 CR 更小,不是为了「好看」
抽函数是为了让 CR 的 diff 更小、更好读,不是凡是新逻辑都新建 function。
- 一行或两三行直接改原处;再包一层 function 会让 diff 更大。
- 仅当改的是已合入主干的函数,且新逻辑是一整段流程、会明显拉长或打乱原函数时,才抽成独立 function。
- 新增文件、新增函数按正常结构写。
这条是反直觉的,值得多说两句。
很多团队的习惯是「新逻辑就抽函数,函数越短越好」。但在 AI + CR 的场景下,这条会反噬:
- AI 把原本 3 行的改动包成一个新函数 → diff 里多了「函数定义 + 函数调用 + 原处替换」,行数反而更多;
- CR 的时候,reviewer 要跳转去看新函数实现,上下文被打断。
所以这里的取舍是:抽函数的唯一判据是「原函数会不会被打乱」。如果新逻辑只是一两行,直接写在原处,diff 最小、最好读。只有当新逻辑是一整段流程、塞进去会让原函数变得又长又乱时,才抽出去。
3. 给人读的用简体中文
给人读的用简体中文(说明、注释、提交说明、文档正文)。 代码、API、文件名、YAML key、OpenSpec 名称保持原规范。不翻译第三方 skill/命令模板,不改未触及的旧注释。
原则很简单:人读的归人,机器读的归机器。
- 注释、提交说明、文档正文 → 简体中文;
- 变量名、API 字段、YAML key、文件名 → 保持原规范,不硬翻。
同时强调「不改未触及的旧注释」------别让 AI 顺手把别人的英文注释也翻译了,那是不相关的 diff。
4. 动手前先读,不凭记忆编造
动手前先读现有实现和同类写法。禁止凭记忆编造接口、字段、路由、配置;找不到就明确说找不到。 优先复用本仓库已有写法。只做需求所需的最小改动:不提前抽象、不顺手重构、不补没要的文档/防御代码。 注释格式跟本仓。新增和改到的代码默认要写;一行赋值/透传、名字已能说明用途的可不写。禁止复述代码。
这条管的是 AI 最危险的失败模式:幻觉。
AI 会「猜」接口名、字段名、路由路径,然后写得有模有样,编译还不一定报错------因为 TS 类型可能 any 逃逸。等上线才发现 getUserInfo 其实叫 fetchUser,已经晚了。
底线:
- 动手前先读现有实现,找不到就说找不到,不许编;
- 复用本仓已有写法,不引入新的风格;
- 最小改动:不提前抽象、不顺手重构、不加没要的防御代码;
- 注释默认要写,但「禁止复述代码」------
let a = 1不需要注释说「声明变量 a」。
5. 改完自检,但别每次小改都跑全量
改完自检:符合需求、无多余文件、无无关 diff。 改了相关代码才跑本仓已有检查(eslint / stylelint / typecheck 以当前
package.json为准),不要每次小改都跑,也不要只改不验。
两个要点:
- 改了相关代码才跑检查 ------改个 README 不用跑 eslint,改了
.ts才跑 typecheck; - 不要只改不验------动了该测的代码就必须验,不能图省事跳过。
判据是「相关性」,不是「频率」。
6. 修问题先定位根因,禁止藏错误
修问题先定位根因。禁止空 catch、默认值、提前 return 把错误藏掉。 不要为每段逻辑套 try/catch;能由现有请求封装/全局错误处理接住的,业务里不要再套一层。仅在本层确有恢复、降级或需要转换成用户可理解错误时才 catch。
这条直指 AI 修 bug 的典型「偷懒」姿势:
ts
// ❌ 错误示范:把异常藏掉,根因还在
try {
const data = await fetchUser(id)
} catch (e) {
return null
}
报错没了,bug 也没了吗?不,bug 还在,只是你看不见了。
底线:
- 先定位根因,再修;
- 禁止空 catch、默认值、提前 return 这些「藏错误」手段;
- 能由全局错误处理接住的,业务层不要再套一层 try/catch;
- 只有本层确有恢复/降级/转译成用户可理解错误时,才 catch。
7. 回复先给结论
回复先给结论,再给必要依据。用短句、完整句;项目术语第一次出现时用一句话解释。不要复述工具过程。
这条管的是 AI 的回复可读性。
AI 喜欢这么回:「我先用了 Get-Content 读取文件,然后发现......接着我执行了......最终......」。这些工具过程对人是噪音。
底线:先说结论(改了什么、结果如何),再给必要依据(为什么这么改)、短句、完整句。项目术语第一次出现要解释。不复述工具过程。
这套规则的定位
这份规则刻意写得「克制」------它不是流程规范,不规定你怎么拆任务、怎么做设计,它只管一件事:AI 动代码时的底线行为。
- 走工作流(
lwc-*skill)时:阶段流程、验证清单、CR 维度以对应 skill 为准,写代码行为仍守本文件; - 不走工作流时:本规则是唯一约束。
换句话说,它是「无论你用什么流程,都得守的最低门槛」。
📌 关于
lwc-*工作流(一套 AI 前端开发工作流 skill)的详细介绍,会在下一篇文章中展开,欢迎关注。
配置方式
在 Cursor 中,把规则文件放在 .cursor/rules/ 目录下,文件名 code-rules.mdc,设置 alwaysApply: true,即可让规则每次对话都生效:
yaml
---
name: code-rules
description: 写代码时的全局底线;小任务不走工作流时仍全部生效
alwaysApply: true
---
alwaysApply: true 是关键------它保证规则在所有对话中都加载,不需要手动 @ 引用。
写在最后
AI 编程工具的效率红利,前提是 diff 可审、代码可控。一旦放任 AI「自由发挥」,节省的编码时间会被翻倍的 review 成本吃掉,甚至埋下隐患(藏掉的异常、编造的接口)。
这 7 条规则本质都在回答同一个问题:怎么让 AI 的每次改动都尽量小、准、可读、可审。
如果你也在用 Cursor 或类似工具高频让 AI 动代码,不妨参考这套底线,按自己团队的实际情况调整。规则不用多,能守住底线就够。
下面附上完整的规则文件原文,可以直接复制到你的
.cursor/rules/code-rules.mdc中使用。
完整规则文件原文
yaml
---
name: code-rules
description: 写代码时的全局底线;小任务不走工作流时仍全部生效
alwaysApply: true
---
本规则每次对话都生效,走 `lwc-*` 时也不关闭。
走工作流时:阶段流程、验证清单、CR 维度以对应 skill 为准;写代码行为仍守本文件。
不走工作流时,本规则是唯一约束。
1. 禁止在项目内创建临时文件(调试脚本、日志、备份、草稿、未请求的文档)。用户要求的或实现所需的正式文件除外。
2. 抽函数是为了让 CR 的 diff 更小、更好读,不是凡是新逻辑都新建 function。
- 一行或两三行直接改原处;再包一层 function 会让 diff 更大。
- 仅当改的是已合入主干的函数,且新逻辑是一整段流程、会明显拉长或打乱原函数时,才抽成独立 function。
- 新增文件、新增函数按正常结构写。不要为遵守本条去全量对比主干。
3. 给人读的用简体中文(说明、注释、提交说明、文档正文)。
代码、API、文件名、YAML key、OpenSpec 名称保持原规范。不翻译第三方 skill/命令模板,不改未触及的旧注释。
4. 动手前先读现有实现和同类写法。禁止凭记忆编造接口、字段、路由、配置;找不到就明确说找不到。
优先复用本仓库已有写法。只做需求所需的最小改动:不提前抽象、不顺手重构、不补没要的文档/防御代码。能一行说清的不要拆成一段;不为「看起来完整」加空转代码。
注释格式跟本仓。新增和改到的代码默认要写;一行赋值/透传、名字已能说明用途的可不写。禁止复述代码。
5. 改完自检:符合需求、无多余文件、无无关 diff。
改了相关代码才跑本仓已有检查(eslint / stylelint / typecheck 以当前 `package.json` 为准),不要每次小改都跑,也不要只改不验。
6. 修问题先定位根因。禁止空 catch、默认值、提前 return 把错误藏掉。
不要为每段逻辑套 try/catch;能由现有请求封装/全局错误处理接管的,业务里不要再套一层。仅在本层确有恢复、降级或需要转换成用户可理解错误时才 catch。
7. 回复先给结论,再给必要依据。用短句、完整句;项目术语第一次出现时用一句话解释。不要复述工具过程。