Cursor Rules 最佳实践:怎么写 AI 才听话
很多人抱怨 Cursor “不听话”:明明在聊天里反复强调过用 TypeScript、别加注释、组件放某个目录,它转头就忘。问题往往不在模型,而在你没给它一份稳定、可复用的”规矩”。 Cursor Rules 就是这份规矩——它在每次对话里自动注入你的工程约定,让 AI 的输出对齐你的项目。这篇讲清 cursor rules 最佳实践:规则该怎么组织、写什么不写什么、怎么让它该挂的时候自动挂上。
为什么需要 Rules:把”反复叮嘱”沉淀成配置
聊天框里的指令是一次性的:这一轮说了,下一轮、换个文件、换个 session 就没了。而真实项目里的约定是长期不变的——技术栈、目录结构、命名规范、不许碰的文件。
Rules 的价值就是把这些长期约定沉淀成文件,每次对话由 Cursor 自动喂给模型。你写一次,之后所有人、所有对话都受益。可以把它理解成给 AI 的**「团队编码规范 + 新人入职文档」**:不是临时口令,是常驻背景知识。
这套思路和给 Claude Code 写 CLAUDE.md 是一脉相承的,详见 CLAUDE.md 怎么写才好用(规划中)。
.cursor/rules 目录结构
现在的 Cursor 推荐把规则放在项目根目录的 .cursor/rules/ 文件夹里,每条规则是一个独立的 .mdc 文件(旧版的单个 .cursorrules 文件仍兼容,但不推荐新项目用)。典型结构:
your-project/
├── .cursor/
│ └── rules/
│ ├── general.mdc # 全局通用约定
│ ├── frontend.mdc # 前端/组件规则
│ ├── api.mdc # 后端接口规则
│ └── testing.mdc # 测试规则
└── src/
每个 .mdc 文件由两部分组成:frontmatter 元数据(控制这条规则什么时候生效)+ 正文 Markdown(具体约定内容)。元数据的字段名与取值以官方文档为准,核心是下面四种挂载方式。
规则的四种挂载方式
这是新手最容易踩坑的地方——不是所有规则都该一直生效。Cursor 提供四种触发模式,理解它们是用好 Rules 的关键:
| 挂载方式 | 何时生效 | 适合放什么 |
|---|---|---|
| Always(始终) | 每次对话都注入 | 真正全局的铁律(技术栈、语言、绝对禁忌) |
| Auto / glob 匹配 | 编辑命中 glob 的文件时自动挂 | 某目录/某类文件的专属规则 |
| Agent 按需 | AI 判断相关时自己调用 | 描述清晰、偶尔用到的专项规则 |
| Manual(@调用) | 你在对话里 @规则名 手动引用 | 不常用、按需触发的规则 |
最佳实践是:尽量少用 Always,多用 glob 自动挂载。 因为每条 Always 规则都会占用上下文窗口、稀释注意力——全堆成 Always,等于没有重点。
用 glob 让规则”对文件生效”
glob 是最优雅的方式。在规则的 frontmatter 里写上文件匹配模式(如 src/components/**/*.tsx),当你编辑命中的文件时,这条规则自动挂载,不命中就不占上下文。
举例:前端组件规则只在改 .tsx 时生效,测试规则只在改 *.test.ts 时生效,互不干扰。这样既精准又省上下文,是大型项目的标配做法。具体 glob 语法与 frontmatter 字段写法,见 Cursor Rules 的 .mdc 写法详解(规划中)。
三条核心原则:短、拆小、按需
1. 规则要短(控制在 500 行内)
规则不是越多越好,是越精准越好。 一份动辄上千行的规则文件,模型读起来注意力被严重稀释,反而抓不住重点。建议单个规则文件控制在 500 行以内,越短越好。具体行数上限以官方文档为准,但原则不变:能删的废话都删。
写规则像写宪法,不像写百科全书——只留必须遵守的硬约束,别把教程、背景、客套都塞进去。
2. 拆小:一条规则只管一件事
别写一个”万能 rules”管全项目。按关注点拆成多个小文件:前端一个、API 一个、测试一个、数据库一个。好处有三:
- 可按需挂载:配合 glob,改哪类文件挂哪条规则
- 好维护:改前端规范不影响后端
- 可复用:通用规则能在项目间复制
3. 按需 @调用:不常用的别设成 Always
偶尔才用到的规则(比如”生成数据库迁移脚本时的规范”),设成 Manual,需要时在对话里 @migration 手动引用即可。把它设成 Always 只会无谓占用每一轮对话的上下文。
写什么 vs 不写什么
这是决定规则质量的分水岭。
该写(具体、可执行的约束):
- 技术栈与版本约定:
用 React 19 + TypeScript,禁用 any - 目录与命名:
组件放 src/components,文件名用 kebab-case - 代码风格:
优先函数组件、不写 class;注释只写为什么不写做什么 - 禁忌清单:
别动 src/legacy/、别改 package.json 的依赖版本 - 项目特定模式:
API 调用统一走 src/lib/api.ts 的封装
不该写(空泛、模型本就会的):
- ❌ “写出高质量、可维护的代码”——废话,等于没说
- ❌ “遵循最佳实践”——太空泛,模型无法落地
- ❌ 把整个框架文档复制进去——浪费上下文
- ❌ 频繁变动的临时需求——那是聊天框该干的事
口诀:写”你的项目特殊在哪”,别写”通用编程常识”。 模型已经会通用规范,你要告诉它的是你这个项目的个性。
给规则配上例子,效果翻倍
光说”组件要这样写”不如直接贴一段正确示例代码。模型对具体范例的对齐能力远强于抽象描述。好的规则常长这样:
## 组件规范
- 用函数组件 + TypeScript
- Props 用 interface 定义在组件文件顶部
正确示例:
interface ButtonProps {
label: string
onClick: () => void
}
export function Button({ label, onClick }: ButtonProps) { ... }
一个好例子胜过十句描述。这也是 cursor rules 最佳实践里性价比最高的一招。
怎么验证规则真的生效了
写完别假设它在干活,主动验证:
- 看引用面板:Cursor 在对话里会显示本轮挂载了哪些规则(Applied Rules / Referenced Rules,具体 UI 位置以版本为准)。没看到你期望的规则,说明 glob 没匹配上或挂载方式设错了。
- 反向测试:故意让它做一件违反规则的事,看它会不会自动纠正。
- 改完文件再观察:调整 glob 后切到目标文件,确认对应规则被挂上。
常见坑与排查
| 现象 | 原因 | 解法 |
|---|---|---|
| 规则好像没生效 | 挂载方式设成了 Manual,但没 @调用 | 改成 Always 或配 glob 自动挂 |
| 规则生效了但 AI 还是不照做 | 规则太长/太空泛,被稀释 | 砍到 500 行内,换成具体示例 |
| glob 不匹配 | 路径模式写错(相对路径/通配符) | 核对 glob 语法,用真实文件路径测 |
| 上下文爆了、响应变慢 | 太多规则设成 Always | 只留铁律 Always,其余转 glob/Manual |
| 多人协作规则不一致 | 规则没提交进 Git | 把 .cursor/rules/ 纳入版本控制 |
常见问题
Cursor Rules 写在哪个文件?
新项目放在项目根目录的 .cursor/rules/ 文件夹里,每条规则一个 .mdc 文件。旧的单文件 .cursorrules 仍兼容,但官方推荐用新的目录结构,便于拆分和按需挂载。
规则要不要提交到 Git?
要。.cursor/rules/ 应纳入版本控制,这样团队所有人共享同一套约定,AI 的输出风格才统一。这正是 Rules 相比聊天框指令的核心优势——团队级、可沉淀。
规则越多 AI 越听话吗? 恰恰相反。规则太多、太长会稀释模型注意力,反而抓不住重点。原则是短、拆小、按需挂载:单文件控制在 500 行内,只写项目特有的硬约束,通用常识不用写。
.cursorrules 和 .cursor/rules 有什么区别?
.cursorrules 是早期的单文件方案,全项目共用一份、始终生效;.cursor/rules/ 是新的多文件目录方案,每条规则可独立设置挂载方式(Always / glob / Agent / Manual),更灵活、更省上下文。新项目一律用后者。
为什么我的规则没生效?
最常见三个原因:一是挂载方式设成了 Manual 却没 @调用;二是 glob 路径没匹配到当前文件;三是规则太空泛被模型忽略。先看对话里的已挂载规则面板确认,再逐项排查。
👉 看看我们的 AI 编程实战体系课,或逛 AI 编程教程大全 把基本功打扎实。