把项目规则写成 .cursor/rules/*.mdc,前置元数据用到三个字段:description、globs、alwaysApply。三个字段怎么组合,决定这份规则什么时候进上下文。只在某一类文件里才成立的句子,把文件名写进 globs,并把 alwaysApply 设为 false,这样只有改到匹配的文件时才生效。一份规则只讲一件事,正文压到 50 行以内。
三种情况下会打开这一页:有一条要求只在改某类文件时才成立 → 先在「规则文件的三个字段」里挑一种加载组合,再照「示例」抄前置元数据;规则写了却没生效,或者每轮对话都在提它 → 到「常见错误」的现象表里对一行,多数是写成了 paths:,或漏了 alwaysApply: false;从 Claude Code 或 TraeCode 搬过来 → 先逐行核「规则在三处」。
这两处写错都不报错:paths: 是 Claude Code 的字段,Cursor 认的是 globs;只填 description、既不限文件范围也不始终生效的规则,会和技能的 description 抢「什么时候想起」。
说得出这份规则匹配哪些文件吗?
说不出具体文件名,它就是缺了 globs,或者被写成了 alwaysApply: true。写不出 globs 的句子不属于这一层,把它放回 AGENTS.md。
规则是「只在某类文件里才需要」的约定,和 AGENTS.md 里写的全局事实分工不同。数据范围已经写在 AGENTS.md 里,就不要再写一份 alwaysApply: true 的规则把同一条约束重复一遍——重复的句子会留下两处真相,改的时候容易只改一处。
| 加载方式 | 前置元数据怎么写 | 什么时候进上下文 | 什么时候用 |
|---|---|---|---|
| 始终生效 | alwaysApply: true,不写 globs | 每次对话 | 几乎不用。全仓库都成立的句子该放回 AGENTS.md |
| 按文件范围命中 | globs: backend/**/*_test.go 配 alwaysApply: false | 改到匹配该 glob 的文件时 | 默认用法。只在某一类文件里成立的句子都走这里 |
| 由智能体按描述判断 | 只写 description,不写 globs | 助手觉得这次任务相关时 | 少用。它会和技能的 description 抢触发,这类句子更适合写成技能 |
| 手动点名 | —— | —— | Cursor 没有点名单份规则的入口(TraeCode 用 #Rule)。要点名就把步骤写成命令 |
globs: 限定,配 alwaysApply: false;正文只写这一类文件里要遵守的句子。
AGENTS.md 的数据范围再抄一份成始终生效的规则;只写 description 让规则「智能生效」;一份规则里同时讲测试、迁移和提交信息三件事。
什么时候不用规则:所有文件都要遵守、删掉就会做错的句子,放进 AGENTS.md;「任务一出现就该做」的步骤,写成技能。只有「改某一类文件时才需要」的句子才值得单独一份规则。
三个工具的规则目录和限定字段都不一样。最容易踩的是 paths 与 globs 的混用:写错字段不报错,规则只是不按文件范围生效。
| 项 | Claude Code | Cursor | TraeCode |
|---|---|---|---|
| 项目位置 | .claude/rules/(可再分 backend/、frontend/) | .cursor/rules/*.mdc | .trae/rules/*.md |
| 个人位置 | ~/.claude/rules/ | —— | ~/.trae-cn/user_rules |
| 限定文件范围 | 前置元数据 paths:(glob 列表) | globs: 加 alwaysApply: false | alwaysApply: false 加 globs:(逗号分隔多个通配符) |
| 不带范围时 | 每次会话开始就加载,和仓库说明一样占上下文 | alwaysApply: true 时始终生效 | 创建时选定生效方式,由 TraeCode 改 alwaysApply |
| 手动点名 | —— | —— | 对话里用 #Rule 点名 |
| 只写 description | —— | 会和技能的 description 抢触发;Cursor 也把这类规则视为可迁到技能 | 同上,本课不用 |
| 篇幅 | —— | 一份规则宜 50 行以内 | —— |
| 改完怎么验证 | —— | —— | 开一轮新对话再试 |
这张表给出一个结论:规则这一层只有 Cursor 要求显式写 alwaysApply: false 才不常驻。漏掉这一行,这份规则就变成每轮都占上下文的常驻内容。
AGENTS.md 已经要求 SQL 绑定会话中的 scope_id。测试文件里还要它成对断言,所以单独放一条规则;docker compose 文件里另有环境变量来源的要求,再放一条。两条都只在自己匹配的文件里生效。
globs 命中测试文件,alwaysApply: false 保证它不常驻。
--- description: 改 Go 测试时检查数据范围 globs: backend/**/*_test.go alwaysApply: false --- 断言必须区分所属范围。 用当前所属范围的用户读取本范围的数据应当成功。 同一会话去读其他所属范围应当失败,且与记录不存在无法从响应区分。 检索没有命中时,结果是「无依据」,不能出现资料里没有的句子。
只覆盖编排文件这一类。改完 globs 亲手验一次:改一个 docker-compose.yml 看它生效,再改一个 Makefile 看它不出现。
--- description: 改 docker compose 配置时的写法 globs: docker-compose*.yml alwaysApply: false --- 数据库口令与第三方密钥来自 .env,不在 compose 里写默认值。 新增服务时,同步更新 AGENTS.md 的启动段和 .env.example 的占位符。
写完做一次核对:把 globs 指向的文件各改一行,看助手有没有按这份规则行动。某条要求对所有文件都成立时,它不该待在规则里,把它移回 AGENTS.md。
规则不生效时大多没有报错,只能从现象反查。
| 现象 | 原因 | 修法 |
|---|---|---|
规则里写了 paths:,改到匹配的文件时助手还是没照做 | paths: 是 Claude Code 的字段,Cursor 用的是 globs | 把 paths: 改成 globs:,并确认写上了 alwaysApply: false |
| 每轮对话助手都在提一条和当前任务无关的规则,上下文变长 | 规则没设 alwaysApply: false,或设成了始终生效,于是每轮都进上下文 | 给它补上 globs: 限定文件范围,并把 alwaysApply 设为 false |
| 同一条数据范围要求,助手有时遵守有时忽略 | AGENTS.md 里有一份,又建了一份常驻规则重复,两处措辞不完全一致 | 删掉规则里的重复句,数据范围只留 AGENTS.md 一份 |
只写了 description 的规则,和技能在同一个任务里同时被想起,行为冲突 | 这类规则会和技能的 description 抢触发,Cursor 也把它们视为可迁到技能 | 文件范围清楚的用 globs 限定;任务范围清楚的写成技能 |
| 一份规则写到 120 行,改测试时助手只按前几条做 | 整份规则都进上下文,靠后的句子被稀释 | 一份规则只讲一件事,正文压到 50 行以内;多出来的拆成另一份规则 |