Cursor Rules:写出 Agent 真会照办的 .mdc 文件

Cursor 的四种规则类型、.cursor/rules/*.mdc 与老的 .cursorrules 与 AGENTS.md 怎么选,以及怎么给规则定作用域让模型真听。内容更新至 2026 年 6 月。

一句话总结

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何时加载
AlwaysalwaysApply: true每次对话都注入,不看上下文。description/globs 被忽略。
Auto AttachedalwaysApply: false + 设了 globs上下文里有匹配 glob 的文件时加载。
Agent RequestedalwaysApply: false + 设了 description、不设 globsagent 读 description,自己判断这条规则跟当前任务相不相关。
ManualalwaysApply: 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 容易过度贴自己风格。

具体步骤

  1. 选格式。 新项目:.cursor/rules/*.mdc。单人小项目:.cursorrules 够用。团队:用 .cursor/rules/,能拆能分作用域。不管哪种,别让 .cursorrules .cursor/rules/ 同时都填着内容。
  2. 写第一条带作用域的规则。.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 规则:设了 globsalwaysApply 为 false,所以只在 src/ 的 TypeScript 文件进上下文时才加载。

  1. 加测试规则。.cursor/rules/tests.mdcglobs: ["**/*.test.ts", "**/*.spec.ts"]。测试专属规范不要混进通用 TypeScript rule。
  2. 加你的硬”绝不”清单。forbid.mdcalwaysApply: true,放仓库范围的硬规则——绝不动的路径、绝不内联的密钥、绝不跑的命令。这是少数几个真该设 Always 的文件之一。
  3. 验规则加载上了。 打开 Cursor 设置 → Rules,确认每个 .mdc 都列出来,且类型和你预期一致(Always / Auto Attached / Agent Requested / Manual)。该激活却显示成别的类型,就查 glob 和 frontmatter 有没有打错(rules 没加载排查)。
  4. 拿真实 prompt 测。 跑一个之前出错那种的 prompt,看输出。rule 没起作用就是太含糊或太长。改紧再来——别又加一条。
  5. 提交 .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)

标签: #AI 编程 #教程 #Cursor