一句话总结
Cursor 读四种规则,选错类型正是大多数人规则被忽略的原因。截至 2026 年 6 月:
- 项目 rules 放在
.cursor/rules/*.mdc(进版本控制、可定作用域),由 frontmatter 决定四种触发模式:Always、Auto Attached(按 glob)、Agent Requested(按 description)、Manual(@rule-name)。 - 老的仓库根单文件
.cursorrules还能用,但没作用域。别两种格式同时开——混用行为是未定义的。 - 纯 markdown 的
AGENTS.md现在也是受支持的替代方案,不想写 frontmatter 就用它。 - 真能改行为的规则是具体、按文件挂、且短的(Cursor 建议每条控制在 500 行内;实际上指令式规则远在 100 行以内最管用)。那种 200 行”做个高级工程师、写干净代码”的废话墙会被忽略。
这篇讲清四种模式、User / Project / Team 三层规则的优先级、怎么验证规则真加载上了,以及当前版本里 alwaysApply: true 被静默降级的那个坑。
这篇讲什么
怎么写真能改模型行为的 Cursor rules——不是那种被礼貌忽略的愿望式废话墙。当前 Cursor 从三个地方读规则:项目级的 .cursor/rules/*.mdc(带 frontmatter)、老的仓库根单文件 .cursorrules,以及较新的纯 markdown 文件 AGENTS.md。这篇每个都讲,什么时候选哪个、里面该写什么、哪些反模式写完等于零效果。
还没做完基础上手的,先走Cursor 新手 30 分钟跑通完整工作流。
四种规则类型
这部分大多数教程都跳过,但它才是关键。一条 .mdc 规则的触发模式不是单独的开关——它是从你填了哪些 frontmatter 字段推断出来的:
| 类型 | Frontmatter | 何时加载 |
|---|---|---|
| Always | alwaysApply: true | 每次对话都注入,不看上下文。description/globs 被忽略。 |
| Auto Attached | alwaysApply: false + 设了 globs | 上下文里有匹配 glob 的文件时加载。 |
| Agent Requested | alwaysApply: false + 设了 description、不设 globs | agent 读 description,自己判断这条规则跟当前任务相不相关。 |
| Manual | alwaysApply: false,不设 description 也不设 globs | 默认休眠,直到你在对话里 @ 引用它(如 @my-rule)。 |
实战对应:
- 技术栈声明、一小串”绝不”清单 → 用 Always(一两个文件,别更多)。
- 按区域分的规范(API handler、React 组件、迁移脚本)→ 用 Auto Attached 配精准 glob。这是主力模式。
- 任务形态的知识(“我们怎么接 Stripe 结账”)→ 用 Agent Requested 配一条锐利的 description,这样哪怕还没打开匹配文件,agent 认出任务就会加载它。
- 一次性或很少用的上下文 → 用 Manual,需要时
@拉进来。
滥用 Always 是头号错误:每条 always-apply 都在每次请求上吃上下文预算,五条同时生效时模型会在它们之间折中,结果大部分都只部分满足。
这篇适合谁看
Cursor 老在同一处犯同一种错的人——import 风格不对、用错测试 runner、文件放错位置——已经意识到每次重 prompt 不可持续。团队尤其用得上:共享 rules 目录是项目规范不再依赖口口相传的方式。
什么时候适合用
一周里看到 Cursor 同一种可纠正的错犯两次——这就是该把约束变成 rule、不是 prompt 的信号。或者队友的 Cursor 会话产出和你风格明显不一致;rules 就是用来同步默认值的。一次性的约束就别写 rule,直接 @File 提就行。
Project、User、Team 三层规则与优先级
Cursor 从几个作用域读规则,它们是叠加而不是互相替换:
- Project 规则——
.cursor/rules/*.mdc,提交进仓库,clone 的人都共享。 - User 规则——在 Cursor 设置里配,对你所有项目生效。注意:User 规则只对 Agent/Chat 生效,不对内联编辑(Cmd/Ctrl+K)生效。
- Team 规则——Team/Enterprise 套餐在控制台管理,可以设为对所有成员强制。
作用域冲突时,优先级是 Team → Project → User。强制的 Team 规则盖过你的个人偏好;你提交的 Project 规则盖过你的全局 User 设置。把个人口味(比如”解释你的思路”)放 User 规则、把共享规范放 Project 规则,它们就不会打架。
开始前准备
- 仓库根有
.cursor/目录(Cursor 第一次用会建,或者mkdir .cursor/rules)。 - 列一下你现在对 Cursor 输出的具体不满——这些是 rule 候选。含糊的不满写不出好 rule。
- 知道仓库 glob:哪些路径是测试、哪些是服务端、哪些是生成的。Auto Attached 规则按 glob 挂。
- 一两个队友帮你 dogfood。一个人写的 rule 容易过度贴自己风格。
具体步骤
- 选格式。 新项目:
.cursor/rules/*.mdc。单人小项目:.cursorrules够用。团队:用.cursor/rules/,能拆能分作用域。不管哪种,别让.cursorrules和.cursor/rules/同时都填着内容。 - 写第一条带作用域的规则。 建
.cursor/rules/typescript.mdc,写 frontmatter 和聚焦的正文。要短——太长就会被当文档浏览,而不是当指令照办:
---
description: src/ 的 TypeScript 规范
globs: ["src/**/*.ts", "src/**/*.tsx"]
alwaysApply: false
---
# TypeScript 规则
- 用 named export。`src/` 里禁 default export,`pages/` 除外。
- 所有 async 函数必须写明返回类型。
- 优先 `unknown` 不用 `any`。`any` 不可避免就留一行 `// eslint-disable-next-line @typescript-eslint/no-explicit-any` 并一句话写原因。
- Import:`src/` 内用绝对路径 `@/`,同级用相对。
- HTTP handler 里抛的错必须继承 `AppError`。
这是一条 Auto Attached 规则:设了 globs、alwaysApply 为 false,所以只在 src/ 的 TypeScript 文件进上下文时才加载。
- 加测试规则。 建
.cursor/rules/tests.mdc,globs: ["**/*.test.ts", "**/*.spec.ts"]。测试专属规范不要混进通用 TypeScript rule。 - 加你的硬”绝不”清单。 建
forbid.mdc,alwaysApply: true,放仓库范围的硬规则——绝不动的路径、绝不内联的密钥、绝不跑的命令。这是少数几个真该设 Always 的文件之一。 - 验规则加载上了。 打开 Cursor 设置 → Rules,确认每个
.mdc都列出来,且类型和你预期一致(Always / Auto Attached / Agent Requested / Manual)。该激活却显示成别的类型,就查 glob 和 frontmatter 有没有打错(rules 没加载排查)。 - 拿真实 prompt 测。 跑一个之前出错那种的 prompt,看输出。rule 没起作用就是太含糊或太长。改紧再来——别又加一条。
- 提交
.cursor/rules/。 当源代码一样进 code review。
你也可以在 Agent 模式用 /create-rule 命令,从一段来回对话里生成一条起步规则(早期版本是 /Generate Cursor Rules;这个命令的入口在不同 Cursor 版本之间挪过位置,看不到就在 设置 → Rules → Add Rule 手动加)。生成的规则一定要自己再读一遍——它们往往比你手写的更长更含糊。
一份”逼它说实话”的 rule
“做个有用的助手、写干净代码”那种 rule 没用。这种才真改模型行为——具体、按文件挂、带可运行的例子:
---
description: API handler 规范
globs: ["src/api/**/*.ts"]
alwaysApply: false
---
# API handlers
`src/api/` 里所有 handler 必须:
1. 用同文件定义的 `zod` schema 验入参。禁内联 `as` 转换。
2. 业务逻辑调用包 try/catch,重抛为 `AppError`,带稳定 error code。
3. 响应走 `respond.ok(data)` / `respond.error(code, message)`——绝不直接构造 Response 对象。
4. 函数开头 `logger.handler(req, "name")` 记日志。
示例形状:
```ts
export const POST = async (req: Request) => \{
logger.handler(req, "createOrder");
const input = OrderSchema.parse(await req.json());
try \{
const order = await orders.create(input);
return respond.ok(order);
\} catch (e) \{
throw new AppError("ORDER_CREATE_FAILED", \{ cause: e \});
\}
\};
具体胜过愿望。模型抄你给的样子,不抄你说的话。如果规范本身就在真实文件里,在规则里用 `@filename.ts` 引用它,而不是整段贴进来——这样规则又短又始终最新。
## AGENTS.md:不写 frontmatter 的那个选项
不想学 MDC frontmatter 的话,Cursor 也读 `AGENTS.md`——纯 markdown、无 frontmatter,放仓库根或子目录里。它对所在目录表现得像一条 Always 规则,而且嵌套的 `backend/AGENTS.md` 对 `backend/` 下的文件优先于根目录那份。这是给 agent 项目上下文最省事的方式,而且可移植:好几个其他 AI 编程工具也读同一套 `AGENTS.md` 约定。代价是没有 glob 作用域——要细粒度控制还是得用 `.cursor/rules/*.mdc`。
## 完成后检查
- 每个 `.mdc` 聚焦一件事。一个 rule 涵盖"TypeScript 加测试加 API 加样式"——拆。
- Glob 精准——`src/**/*.ts` 不会意外挂到 `node_modules`(Cursor 默认忽略,再查一遍)。
- `alwaysApply: true` 最多用在一两个文件。每个 always-apply 都吃上下文预算。
- Rule 正文要短——远在 Cursor 建议的 500 行上限之下,指令式规则最好控制在 100 行内。再长模型当文档看,不当指令。
- 代表性测试 prompt 跑出你要的行为。没跑出来就重写这条 rule,不要又加一条。
- 你只在跑一种格式,不是两种。`.cursorrules` 和 `.cursor/rules/` 同时填着内容,是最常见的"Cursor 不听我规则"原因。
## 容易踩的坑
- **200 行愿望式废话**——"做高级工程师,写干净可维护代码"。模型直接忽略。
- **滥用 `alwaysApply: true`。** 每条 always-apply 都吃实际代码的预算,堆多了模型会折中、结果大部分只部分满足。
- **含糊规则("写好测试")没例子。** 模型没法拿它跟当前任务对照,于是它融进模型的通用行为里、等于消失。把你要的形状秀出来。
- **一个大 rule 覆盖整个项目。** 按关注点拆;模型对聚焦文件更上心。
- **规则类型选错。** 把任务知识塞进 Auto Attached 规则,没打开匹配文件它就一直休眠。想让 agent 按相关性主动拉进来,就改成 Agent Requested(设 `description`、去掉 `globs`)。
- **同时跑 `.cursorrules` 和 `.cursor/rules/`。** 行为未定义;挑一个。
- **Team、Project、User 三层规则互相冲突。** 表现是"Cursor 不听我的规则"——见 [Cursor rules 没加载](/zh/articles/cursor-rules-not-loaded/)。
## 当前版本的一个坑
在最近的某些 3.x 版本里,多名用户反映 `alwaysApply: true` 的规则(以及老的 `.cursorrules` 文件)被静默当成 **Agent Requested** 处理、不再自动注入——也就是你标了 Always 的规则,只在 agent 觉得相关时才加载。如果升级 Cursor 后你的 Always 规则像被忽略了:
1. 打开 设置 → Rules,确认这条规则的类型还是 **Always**,不是 Agent Requested。
2. 临时方案:把关键约束同时写进仓库根的 `AGENTS.md`,它更难被静默降级。
3. 关注 Cursor 的 changelog 和论坛——这个行为在版本之间一直在变,具体表现取决于你的构建版本。
## FAQ
- **要把 `.cursorrules` 迁到 `.cursor/rules/` 吗?** 文件超过约 50 行或有多个关注点——迁,能拿到作用域和四种触发模式。小且单一目的的留着 `.cursorrules` 没问题。只是别两种格式一起跑。
- **每个 prompt 模型都看得到我所有 rules 吗?** 不是。只有 Always 规则、glob 匹配上下文文件的 Auto Attached 规则、agent 判定相关的 Agent Requested 规则,加上你 `@` 引用的 Manual 规则。
- **Agent Requested 和 Auto Attached 有啥区别?** Auto Attached 按 glob 加载(必须有匹配文件在上下文里)。Agent Requested 按相关性加载(agent 读你的 `description` 自己判断),所以它能在还没打开任何匹配文件之前就生效。
- **规则能引用其他文件吗?** 能——在规则里用 `@filename.ts` 把真实文件拉进来,而不是贴它的内容。这样规则又短又始终最新。
- **为啥 Cursor 侧栏看不到我的 rule?** 通常是 frontmatter 打错(最常见少了闭合 `---`)、YAML 无效(写 `true` 不是 `True`;globs 要是列表)、或者文件放错位置。查[Cursor rules 没加载](/zh/articles/cursor-rules-not-loading/)。
- **规则对内联编辑(Cmd/Ctrl+K)生效吗?** Project 规则生效。User 规则只对 Agent/Chat 生效。
## 相关阅读
- [Cursor 新手 30 分钟跑通完整工作流](/zh/articles/cursor-getting-started/)
- [Cursor 索引——又快又有用](/zh/articles/cursor-indexing-tutorial/)
- [Cursor rules 没加载](/zh/articles/cursor-rules-not-loaded/)
- [给 agent 喂项目报告](/zh/articles/feed-project-reports-to-agents/)
- [Cursor Rules — Rules | Cursor Docs](https://cursor.com/docs/context/rules)