12 · Rules 规则系统
从 .cursorrules 到 .mdc,从简单的提示词文件到结构化的规则系统——理解 Cursor 规则系统,让 AI 真正懂你的项目。
01 为什么需要规则系统
当你用 Cursor 的 Chat 或 Agent 写代码时,有没有遇到过这些问题:
- AI 写了你不想要的技术栈(比如用 Vue 写法写 React 项目)
- AI 不遵循项目的代码风格(命名规范、目录结构、错误处理模式)
- AI 不知道你的项目里有哪些工具和配置
- 每次开新对话都要重复说一遍”我们项目用 pnpm,不用 npm”
这些问题根源于一个核心矛盾:大语言模型知道整个互联网的知识,但不知道你的项目的”本地知识”。你的项目有自己的:
- 技术栈和版本
- 代码规范和风格约定
- 目录结构和文件组织习惯
- 测试策略和部署流程
- 团队特有的命名约定
在 Cursor 早期版本,解决这个问题的方式是一个名叫 .cursorrules 的文件——你把它放在项目根目录,写上你的项目规则,AI 会读取它作为系统提示的一部分。
但 .cursorrules 的问题也很明显:它只是一个孤零零的文本文件,没有结构,没有作用域,没有条件触发,团队协作时无从管理。
从 Cursor 0.45 版本开始,规则系统迎来了根本性的升级——从 .cursorrules 迁移到了 .cursor/rules/*.mdc。
02 从 .cursorrules 到 .mdc:一次结构化的进化
2.1 旧时代的 .cursorrules
.cursorrules 是一个纯文本文件,放在项目根目录。它的内容直接追加到 AI 的系统提示中,相当于给 AI 一个”项目说明书”。
示例 .cursorrules:
You are an expert in TypeScript and React development.
- Use functional components with hooks
- Use TypeScript strict mode
- Use pnpm for package management
- Follow the existing project structure
- Write unit tests for all new functions
- Use named exports, not default exports这种方式的局限:
| 问题 | 说明 |
|---|---|
| 无结构化 | 所有规则混在一起,AI 无法区分优先级 |
| 无作用域 | 无法针对特定文件或目录应用不同规则 |
| 全局生效 | 对不相关的文件也会产生影响 |
| 团队协作难 | Git 冲突、没有版本管理的内在机制 |
| 无元数据 | 无法描述规则的用途、适用场景、作者 |
2.2 新时代的 .mdc 规则系统
.cursor/rules/*.mdc 引入了一套结构化的规则格式。每个 .mdc 文件包含两部分:
- Frontmatter(YAML 格式的元数据头部)
- Markdown 内容(规则的具体描述)
.cursor/
└── rules/
├── react-best-practices.mdc
├── typescript-style.mdc
├── test-requirements.mdc
├── project-structure.mdc
└── commit-message.mdc这个变化的意义在于:规则从”一段提示词”变成了”一个结构化的配置单元”。你可以精细控制每条规则何时生效、对谁生效、优先级如何。
03 .mdc 文件结构:理解 Frontmatter
每个 .mdc 文件以 YAML frontmatter 开头,用 --- 包裹。Frontmatter 定义了规则的元数据,决定了这条规则什么时候起作用。
3.1 Frontmatter 字段详解
---
description: React 组件开发规范
globs: src/components/**/*.tsx, src/pages/**/*.tsx
alwaysApply: false
---| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
description | string | 是 | 规则的简短描述,在 UI 中显示 |
globs | string (逗号分隔) | 否 | 文件 glob 模式,匹配的文件适用此规则 |
alwaysApply | boolean | 否 | 是否始终应用(默认 false) |
3.2 description:给规则一个身份
description 是规则的”名字”。它在 Cursor 的设置界面(Rules 面板)中显示,帮助你快速识别每条规则的用途。
---
description: 确保所有 API 调用都包含错误处理
---一个好的 description 应该让人一眼就知道这条规则是干什么的。
3.3 globs:精确控制作用范围
globs 定义了这条规则作用于哪些文件。它的语法和 .gitignore 中的 glob 模式一致:
---
description: React 组件使用函数式编程风格
globs: src/components/**/*.tsx
---多组 glob 用逗号分隔:
---
description: 测试文件使用 describe/it 模式
globs: src/**/*.test.ts, src/**/*.spec.ts, tests/**/*.ts
---globs 的核心价值:一条规则只对特定文件生效,不污染不相关文件的 AI 上下文。
3.4 alwaysApply:两条”全天候规则”
alwaysApply: true 表示这条规则对所有文件、所有场景都生效,不管当前在编辑什么文件。
---
description: 项目使用 pnpm 管理依赖
alwaysApply: true
---在 Cursor 的设置界面中,alwaysApply: true 的规则会显示在 “Always Apply” 列表中。系统内置了两条这样的规则:
- Rules for Cursor — 定义 Cursor 自身在项目中的行为规范
- Rules for AI — 定义 AI 助手的行为规范
这两条规则用户无法删除,但可以修改。
03 四种规则类型
根据 globs 和 alwaysApply 的组合,规则可分为四种类型。理解这四种类型,是在项目中正确配置规则系统的前提。
3.1 Type 1:Always Apply(始终应用)
配置方式: alwaysApply: true,无 globs
---
description: 项目基础规范
alwaysApply: true
---
## 项目技术栈
- 框架: Next.js 14 (App Router)
- 语言: TypeScript 5.x (strict mode)
- 包管理: pnpm
- 测试: Vitest + Testing Library
- CSS: Tailwind CSS
## 通用规范
- 使用命名导出(named exports),避免默认导出
- 所有公共函数和组件必须有 JSDoc 注释
- 禁止使用 `any` 类型
- 国际化使用 `next-intl`何时使用: 技术栈声明、全局编码规范、项目约定等对所有文件都适用的规则。
心智模型: 这是项目的”宪法”——不管你在项目的哪个角落,这些规则都在。它们定义了项目的底色。
3.2 Type 2:Apply Intelligently(智能应用)
配置方式: 有 globs 且 Cursor 自动匹配
---
description: React 组件开发规范
globs: src/components/**/*.tsx, src/app/**/*.tsx
---
## 组件规范
- 使用函数式组件 + Hooks
- Props 使用 `interface` 定义(而非 `type`),以 `Props` 为后缀
- 组件文件使用 PascalCase 命名
- 每个组件文件只导出一个主要组件
- 使用 Tailwind CSS 类名,不使用 CSS Modules
- 复杂组件拆分成子组件,放在同目录的 `_components/` 下Cursor 的 AI 引擎会自动判断:当用户正在处理或引用匹配 globs 模式的文件时,自动加载对应规则。不需要用户手动选择。
何时使用: 特定技术领域的规范(React 组件、API 路由、数据库查询等),当 AI 进入相关上下文时自动生效。
心智模型: 像智能的”上下文开关”——你切到 React 文件,AI 自动加载 React 规范;你切到测试文件,AI 自动加载测试规范。不用手动管理,也不会互相干扰。
3.3 Type 3:Apply to Specific Files(指定文件应用)
配置方式: 有非常精确的 globs,只匹配特定文件或目录
---
description: PostgreSQL 数据库操作规范
globs: src/lib/db/**/*.ts, src/server/actions/db/**/*.ts
---
## 数据库操作规范
- 所有查询使用 `prisma` client,不写原生 SQL
- 事务操作使用 `prisma.$transaction`
- 查询必须分页,使用 `take`/`skip` 参数
- 所有数据库操作函数必须包含错误处理,使用 try-catch
- 敏感字段(password, token)在查询结果中排除
- 批量操作使用 `createMany`/`updateMany`这与 Type 2(智能应用)在技术上没有区别——都是通过 globs 匹配。区别在于意图:Type 2 面向一类通用文件(如所有 React 组件),Type 3 面向特定模块或功能层面的文件。
何时使用: 针对项目中特定模块的定制规范——API 层、数据库层、配置层等。
3.4 Type 4:Apply Manually(手动应用)
配置方式: 无 globs,alwaysApply: false
---
description: 代码 Review 检查清单
---
## Code Review 检查清单
- [ ] 是否有未处理的错误(缺少 try-catch、Promise 未 catch)
- [ ] 是否有硬编码的敏感信息(API Key、密码)
- [ ] 是否所有用户输入都经过验证和清理
- [ ] 是否有性能问题(N+1 查询、不必要的重渲染)
- [ ] 是否遵循了项目的命名规范
- [ ] 测试覆盖率是否足够
- [ ] 是否遗留了 debug 代码(console.log、debugger)这类规则不会自动加载,需要用户在 Cursor 的 Rules 面板中手动勾选开启。用户可以在 Chat 或 Composer 的上下文中手动引用此类规则。
何时使用: 特定工作流使用的规则(代码审查清单、部署前检查清单、迁移指南)、不常用的规范(只在特定任务中需要的指导)、个人工作流偏好(每个人的工作流偏好不同)。
心智模型: 像一本”工作手册”——你遇到特定场景时才翻开对应的章节,日常开发时不需要它自动跳出来。
四种规则类型对比
| 类型 | alwaysApply | globs | 触发方式 | 典型用途 |
|---|---|---|---|---|
| Always Apply | true | 无 | 始终自动加载 | 项目技术栈、全局规范 |
| Apply Intelligently | false | 有(通配) | AI 自动匹配 | 技术领域规范(React、API、测试) |
| Apply to Specific Files | false | 有(精确) | AI 自动匹配 | 模块级规范(数据库、认证) |
| Apply Manually | false | 无 | 手动选择 | 代码审查清单、迁移指南 |
04 规则层级:Project / Team / Global
规则系统支持三个层级的作用域,按优先级从高到低排列。
4.1 Project 级别(最高优先级)
位置:.cursor/rules/*.mdc
只在当前项目中生效,是规则的默认层级。存放在项目仓库中,随代码一起版本控制。
4.2 Team 级别
位置:.cursor/team/rules/*.mdc(在共享的团队配置目录中)
Team 规则适用于一组项目共享的规范。比如一个微服务架构的团队,所有服务的代码规范一致时,可以把公共规则放在 Team 级别,避免在每个项目中重复配置。
Team 目录需要团队手动同步(如通过 Git 子模块、符号链接或配置管理工具)。通常的做法是创建一个 rules 仓库,团队成员将其链接到各自项目的 .cursor/team/rules/。
4.3 Global 级别(最低优先级)
位置:~/.cursor/rules/*.mdc
全局规则作用于你机器上的所有 Cursor 项目。适合:
- 你个人的编码偏好(缩进、命名风格)
- 全局工具链配置的常识(如:你所有项目都用 pnpm)
- 常用的规则模板
4.4 优先级覆盖规则
当多条规则冲突时,优先级规则如下:
具体来说:
- 更具体的规则覆盖更一般的规则:Project 级别覆盖 Team 级别,Team 级别覆盖 Global 级别
- 同级别规则按文件字母顺序应用:
a-react.mdc在b-test.mdc之前 - 同级别规则内容合并:不是互相覆盖,而是追加到系统提示中
这意味着:你可以在 Global 级别设置通用的 TypeScript 规范,在 Team 级别设置团队的代码风格规范,在 Project 级别的 alwaysApply 规则中声明项目技术栈——三者共存不冲突。
05 Monorepo 中的嵌套规则
Monorepo 是规则系统面临的最大挑战——也是最展现其设计精妙的地方。
5.1 问题:一个根目录,多个项目
一个典型的 monorepo 结构:
monorepo/
├── .cursor/rules/ ← 根规则:通用 monorepo 规范
│ ├── monorepo-common.mdc
│ └── commit-convention.mdc
├── apps/
│ ├── web/ ← React Next.js 项目
│ │ └── .cursor/rules/ ← 子规则:Web 项目特有规范
│ │ └── web-react.mdc
│ └── api/ ← Node.js API 项目
│ └── .cursor/rules/ ← 子规则:API 项目特有规范
│ └── api-express.mdc
├── packages/
│ └── shared/
│ └── .cursor/rules/ ← 子规则:共享包规范
│ └── shared-lib.mdc5.2 嵌套规则的工作机制
当你在 apps/web/src/components/Button.tsx 中工作时,Cursor 会依次加载:
- 根目录规则:
monorepo/.cursor/rules/*.mdc(匹配的 globs 规则) - 子目录规则:
monorepo/apps/web/.cursor/rules/*.mdc(匹配的 globs 规则)
子目录的规则优先级更高,同名规则会覆盖根目录的规则。
5.3 嵌套规则的最佳实践
| 层级 | 应该放什么 | 不应该放什么 |
|---|---|---|
| Root | Monorepo 工具配置(Turborepo、pnpm workspace)、提交规范、CI/CD 约定 | 具体技术栈的编码规范 |
| App/package | 该子项目的技术栈规范、命名约定、目录结构约定 | 全局 monorepo 约定 |
| 深层目录 | 该模块的特有规范(极少数情况) | 任何通用规则 |
5.4 实际例子
假设一个 monorepo 包含 web 应用和 API 服务。
根规则 .cursor/rules/monorepo.mdc:
---
description: Monorepo 基础规范
alwaysApply: true
---
## 项目结构
- 使用 pnpm workspaces 管理依赖
- 所有包在 `packages/` 或 `apps/` 下
- 共享类型定义在 `packages/shared/` 中
- 使用 changesets 管理版本发布
## 代码规范
- TypeScript strict mode
- ESLint + Prettier(配置在根目录)
- 提交信息遵循 Conventional CommitsWeb 规则 apps/web/.cursor/rules/web-react.mdc:
---
description: Web 应用 React 规范
globs: src/**/*.tsx, src/**/*.ts
---
## Web 应用技术栈
- 框架: Next.js 14 App Router
- UI: Tailwind CSS + shadcn/ui
- 状态管理: React Query + zustand
- 表单: react-hook-form + zod
## 组件规范
- 服务端组件优先,客户端组件最小化
- 数据获取在服务端组件中完成
- 使用 `next/navigation` 处理路由跳转API 规则 apps/api/.cursor/rules/api-express.mdc:
---
description: API 服务规范
globs: src/**/*.ts
---
## API 技术栈
- 框架: Express.js
- ORM: Prisma
- 验证: zod
- 认证: JWT (jsonwebtoken)
## API 设计规范
- 所有接口前缀 `/api/v1`
- RESTful 路由命名
- 统一错误响应格式
- 所有接口需包含请求日志
- 敏感操作需鉴权中间件06 实用案例:从零构建规则系统
案例 1:最简配置——新人友好的入门规则
适合个人项目或小型项目,只做一个基础的 .cursorrules 迁移:
# .cursor/rules/project-basics.mdc
---
description: 项目基本信息
alwaysApply: true
---
## 项目
- 技术栈: Next.js 14 + TypeScript + Tailwind CSS
- 包管理: pnpm
- 测试: Vitest
- 目录: `/src` 源码,`/app` 路由
## 规范
- 使用命名导出
- 禁止 any 类型
- 函数式组件 + Hooks
- 添加必要的错误处理这是最入门的配置——两条 Always Apply 规则覆盖了项目的技术栈和基础规范。
案例 2:团队项目——细粒度规则
适合 3-10 人团队的中型项目:
# .cursor/rules/01-typescript-style.mdc
---
description: TypeScript 编码规范
alwaysApply: true
---
## TypeScript 规范
- 使用 `strict: true`
- Interface 前缀 `I`?否——不使用匈牙利命名法
- 类型定义放在 `src/types/` 下
- 使用 `type` 定义联合类型,`interface` 定义对象类型
- 泛型参数使用有意义的命名(非单字母)# .cursor/rules/02-react-components.mdc
---
description: React 组件规范
globs: src/components/**/*.tsx, src/app/**/*.tsx
---
## React 组件规范
- 使用 `function ComponentName() {}` 而非箭头函数
- Props 接口以组件名 + `Props` 命名
- 组件文件同名:`Button.tsx` 导出 `Button`
- 事件处理函数以 `handle` 前缀:`handleClick`
- 状态使用 `useState`,复杂状态用 `useReducer`# .cursor/rules/03-test-standards.mdc
---
description: 测试标准
globs: src/**/*.test.ts, src/**/*.test.tsx
---
## 测试规范
- 使用 Vitest + Testing Library
- 测试文件与源文件同目录
- 使用 `describe`/`it` 模式
- 避免测试实现细节,测试行为
- 快照测试仅用于组件结构验证
- Mock 外部 API 调用# .cursor/rules/04-api-routes.mdc
---
description: API 路由规范
globs: src/app/api/**/route.ts
---
## API 路由规范
- 遵循 Next.js App Router API 模式
- 请求体验证使用 zod
- 统一错误响应:`{ success: false, error: string }`
- 成功响应:`{ success: true, data: ... }`
- 所有路由函数为 async
- 鉴权检查放在每个路由的第一层案例 3:代码审查检查清单(手动应用)
---
description: 代码审查检查清单
---
## Code Review Checklist
### 正确性
- [ ] 是否有未处理的边界情况(空值、越界、非法输入)
- [ ] 异步操作是否有错误处理
- [ ] 状态更新是否不可变(immutable)
### 安全性
- [ ] 用户输入是否经过验证和转义
- [ ] 是否暴露了敏感信息(日志、错误消息中)
- [ ] API 端点是否有权限检查
### 性能
- [ ] 是否有不必要的重渲染
- [ ] 查询是否加了分页
- [ ] 是否有 N+1 查询问题
### 可维护性
- [ ] 命名是否清晰表达了意图
- [ ] 是否有遗留的调试代码
- [ ] 是否添加了必要的注释
- [ ] 是否有重复代码可以提取07 常见陷阱与最佳实践
陷阱 1:把所有东西都塞进 Always Apply
错误做法:
---
alwaysApply: true
---
- Jest 测试用 describe/it
- React 组件用函数式组件
- API 路由用 async handler
- 数据库查询用 Prisma
- CSS 用 Tailwind
- TypeScript strict mode
- 使用 pnpm
- 提交信息用 Conventional Commits
- ...(共 50 条)问题: AI 的上下文窗口是有限的。Always Apply 规则中的每一条都会占用上下文空间,不分场景地加载。当规则过多,AI 会”记不住”或忽略靠后的规则。
最佳实践: Always Apply 只放必须全局知晓的信息(技术栈、项目结构、语言级别规范)。领域特定的规范(React、测试、API)放进 globs 规则中,让 AI 按需加载。
陷阱 2:globs 模式写得太粗糙
错误做法:
globs: src/**/*.ts问题: 这条规则会匹配 src/ 下的所有 TypeScript 文件——包括组件、工具函数、API 路由、测试文件、配置文件。当你写 API 路由时,AI 加载了 React 组件规则;当你写组件时,AI 加载了 API 规则——互相干扰。
最佳实践: globs 模式要精确,不同领域的文件分开:
# 组件
globs: src/components/**/*.tsx
# API 路由
globs: src/app/api/**/route.ts
# 测试
globs: src/**/*.test.ts, src/**/*.test.tsx陷阱 3:规则内容过于抽象
错误做法:
---
description: 代码质量规范
alwaysApply: true
---
- 写高质量的代码
- 遵循最佳实践
- 代码要可维护
- 确保性能良好问题: 这些”规则”对 AI 没有任何实际指导意义。AI 无法从”写高质量代码”中知道你要什么。规则的价值在于具体到可执行的程度。
最佳实践: 每一条规则都应该让 AI 能够判断对错:
- 所有异步函数必须有 try-catch 错误处理
- Props 接口以组件名 + `Props` 命名
- API 响应统一格式:`{ success: boolean, data?: T, error?: string }`陷阱 4:规则之间互相矛盾
当多个 .mdc 文件包含矛盾的规则时,AI 会感到困惑,甚至可能随机选择执行哪一条。
常见矛盾场景:
- 一个规则说”使用命名导出”,另一个说”使用默认导出”
- 一个规则说”CSS Modules”,另一个说”Tailwind CSS”
- 一个规则说”testing-library”,另一个说”enzyme”
最佳实践: 建立规则的”唯一来源”原则——同一件事只有一条规则说了算。如果团队有历史遗留矛盾,在规则中显式说明选择:
# 本项目的 CSS 方案为 Tailwind CSS
# 虽然历史代码中有 CSS Modules,新代码统一使用 Tailwind
- 新组件使用 Tailwind CSS,不创建新的 .module.css 文件陷阱 5:忽视规则之间的加载顺序
同级别规则按文件名字母顺序加载。这意味着:
a-react.mdc在b-api.mdc之前- 如果两条 alwaysApply 规则有冲突,字母顺序决定了哪条”更后面”(后加载的会覆盖先加载的相似指令)
最佳实践: 用数字前缀明确控制顺序:
01-project-basics.mdc # 最先加载:项目基本信息
02-typescript-style.mdc # 第二:语言级规范
03-react-components.mdc # 第三:框架级规范
04-test-standards.mdc # 第四:测试规范陷阱 6:Monorepo 中在子目录乱放规则
把本该放在根目录的规则放在了子目录,导致其他项目无法受益;或者把本该在子目录的规则放在了根目录,导致所有项目都被迫加载。
最佳实践: 遵循”就近作用域”原则:
- 影响所有包的东西 → 根
.cursor/rules/ - 只影响一个包的东西 → 该包的
.cursor/rules/ - 影响一组包的东西 → 考虑 Team 级别规则
08 规则系统的”心智模型”
在建立了对规则系统的全面理解后,以下三个心智模型可以帮助你在实际项目中做出更好的决策。
心智模型 1:规则是”AI 的程序”
把规则系统理解为”你在给 AI 写程序”:
.mdc文件是函数globs是函数的作用域(只在特定上下文中执行)alwaysApply是全局变量(到处可用)- 规则层级是作用域链(局部变量覆盖全局变量)
写规则就像写代码——越具体、越可测试,效果越好。模糊的规则就是有 bug 的程序。
心智模型 2:上下文是稀缺资源
AI 的上下文窗口(现在主流是 200K tokens)看似很大,但实际使用中:
- Always Apply 规则占用的是永久配额——每一条都在每次交互中消耗上下文
- Globs 规则是按需加载——只在匹配的文件中消耗上下文
- 手动规则是零开销——只有你手动开启时才消耗上下文
一个 2000 字的规则文件相当于约 500-800 tokens。如果你有 10 条 Always Apply 规则,那就是 5000-8000 tokens 的永久开销。这条”税”在你每次和 AI 交互时都要交。
所以:少放 Always Apply,多用 Globs 规则。
心智模型 3:规则是活的文档
规则系统不仅仅是”让 AI 不犯错”的工具——它也可以成为项目的活文档。
传统文档的问题在于:
- 写完之后没人看
- 看了也不一定记得遵守
- 代码和文档容易不一致
规则系统的独特价值在于:规则不是给人读的,是给 AI 读的。AI 每次写代码都会自动遵守规则——这意味着规则是”被执行”的文档。
把这个心智模型推进一步:你的项目文档中最重要的部分,应该被提炼成规则。架构决策记录(ADR)的结论、代码审查中反复出现的问题、团队从错误中总结的经验——这些都应该变成 .cursor/rules/*.mdc。
09 从零到一:搭建规则系统的路线图
如果你刚接手一个项目,以下是搭建规则系统的推荐步骤:
第一阶段:迁移(30 分钟)
- 如果有
.cursorrules,迁移第一条alwaysApply规则 - 把技术栈声明转为规则
- 提交到 Git
第二阶段:扩展(1-2 小时)
- 添加 3-5 条领域的
globs规则(React、测试、API) - 团队 Code Review 规则内容
- 观察 AI 行为是否改善
第三阶段:优化(持续)
- 根据团队反馈调整规则
- 添加手动应用的清单(Code Review、部署检查)
- Monorepo 中为各子项目添加独立规则
- 定期审视 Always Apply 规则,精简冗余
10 小结
| 要点 | 说明 |
|---|---|
| 从 .cursorrules 到 .mdc | 从单文件到结构化规则系统,支持元数据、作用域、层级 |
| Frontmatter | 每个 .mdc 文件以 YAML frontmatter 开头,包含 description、globs、alwaysApply |
| 四种规则类型 | Always Apply(全局)、Apply Intelligently(智能匹配)、Apply to Specific Files(精确匹配)、Apply Manually(手动选择) |
| 三个规则层级 | Project > Team > Global,优先级依次递减 |
| Monorepo 嵌套 | 子目录可以有独立规则,优先级更高 |
| 核心心智模型 | 规则是”AI 的程序”;上下文是稀缺资源;规则是活的文档 |
| 常见陷阱 | 滥用 Always Apply、globs 写太粗、规则太抽象、规则矛盾、忽视加载顺序 |
规则系统是 Cursor 最具杠杆价值的功能之一。花一个小时精心配置的规则,会在日后的每一次 AI 交互中产生复利效应——规则配置越精准,AI 输出越接近你对项目的要求。
下一篇:13 提示词工程与 AI 协作 —— 掌握与 Cursor AI 的高效沟通方式,让提示词成为你最高的生产力。