只对某一类文件成立的约束,别写进仓库说明——写进去,改任何文件的对话都会带上它。反过来,全局约束写成规则,它在最需要的时候不在场。
随便挑一条规则,能不能说出它在哪一类文件下、因为哪次改动被加载?
答不上来,说明这条规则是靠助手自己猜何时生效。评审的人没法复核。要补的是范围字段,不是再补一段解释。
规则按工具落在三个目录,文件名就是规则名。三处目录里的正文逐字照抄,只有前置元数据的字段名不同。
仓库根目录/ ├── AGENTS.md # 每次对话读;只对某类文件成立的句子不该留在这 ├── .cursor/rules/scope-tests.mdc # globs: "**/*_test.go";扩展名必须 .mdc ├── .claude/rules/scope-tests.md # paths:(YAML 列表);不用 globs └── .trae/rules/scope-tests.md # globs;字段名与 Cursor 同
三样细节里弄错哪一样都不报错,只是不生效:.cursor/rules/ 下放普通 .md 会被忽略,必须是 .mdc;TraeCode 是 .trae/rules/,不是 .trae/.rules;Claude Code 的字段名叫 paths。所以新增一条规则后要实测一次:改一个匹配的文件,看它有没有进上下文。
场景:让助手「给『记录不存在』这条行为补测试」。这次只碰 backend 下的 *_test.go。
*_test.go 的规则随之加载,助手照它写出成对断言——当前所属范围应当成功,其他所属范围应当失败,且响应与「记录不存在」无法区分。下午改 README 时这条规则根本不出现,那个对话里它一个字都不占。
第一层这六项最容易混用,因为它们装的都是「一条要求」。判据不是内容长短,是它什么时候生效——先问「谁在什么时候会读到它」,答案决定落点,也决定评审时能不能复核。本表是这一层的总表。
| 要做的事 | 做成什么 | 什么时候生效 | 怎么判 |
|---|---|---|---|
| 整仓都成立、每次改动都成立的一条约定 | 仓库说明 | 每次对话 | 删掉它,不相关的任务会不会变差?会 → 仓库说明 |
| 只对某一类文件成立的一条约束 | 规则 | 匹配的文件进入上下文时 | 这条约束只在改这类文件时才用得到吗?是 → 规则 |
| 必须被挡住、不能靠自觉的动作 | 钩子 | 工具调用前 | 一旦发生就必须拦下,靠不住自觉?是 → 钩子 |
| 人主动触发、步骤固定的清单 | 命令 | 人输入 /名称 时 | 需不需要人记得去用、由人拍板?是 → 命令 |
| 不止一条、有先后顺序、会反复照做 | 技能 | 助手识别到同类任务后 | 同类任务一出现就该想起来,而且不止一条步骤?是 → 技能 |
| 需要独立上下文,或要把工具权限收紧 | 子智能体 | 由主流程或人指定 | 要不要独立上下文,或更小的工具范围?是 → 子智能体 |
三个工具的目录与字段名都不同,写错不报错、只是不生效。新增一条规则后要实测一次:改一个匹配的文件,看它有没有进上下文。
| 工具 | 规则目录 | 限定字段 | 落地页 |
|---|---|---|---|
| Cursor | .cursor/rules/*.mdc(.md 被忽略) | globs + alwaysApply: false | Cursor 规则落地页 |
| TraeCode | .trae/rules/ | globs + alwaysApply: false | TraeCode 规则落地页 |
| Claude Code | .claude/rules/ | paths(YAML 列表,不是 globs) | Claude Code 规则落地页 |