项目说明文件与配置分层
CLAUDE.md、AGENTS.md 等说明文件怎么写,用户、项目、本地配置如何叠加。
一句话理解:项目说明文件(
CLAUDE.md、AGENTS.md)是写给 Agent 的“入职手册”,会按层级拼进上下文,模型尽量遵守;配置文件(settings)则由程序按优先级合并、强制执行。分清“哪些写进说明、哪些写进配置”,是这一课的核心。
每次打开一个新会话,Coding Agent 都像第一天来上班的新同事:不知道测试怎么跑、哪个目录不能碰、团队约定金额用什么单位。你在对话里解释过一遍,下一次会话它又忘了。项目说明文件就是把这些“每次都要重新解释的事”写下来,让 Harness 在每次会话开始时自动装进上下文(装配位置见上一课 上下文装配)。
但很多团队用着用着就出了问题:说明文件越写越长,模型反而更常忽略;个人偏好被提交进仓库,影响了所有同事;把“绝对不能推送到主分支”写在说明里,以为这样就安全了。这一课讲清楚说明文件怎么写、多层文件如何叠加,以及它和配置文件的根本区别。
说明文件是上下文,不是强制规则
先记住一个区别:
| 项目说明文件 | 配置文件 | |
|---|---|---|
| 例子 | CLAUDE.md、AGENTS.md |
.claude/settings.json、.codex/config.toml |
| 读者 | 模型 | Harness 程序 |
| 多层如何叠加 | 按顺序拼接进上下文 | 按优先级合并成一份生效配置 |
| 冲突时 | 由模型自己权衡,可能随机选一条 | 由程序按规则决定,结果确定 |
| 能保证什么 | 模型大概率照做 | 程序一定执行 |
Claude Code 的官方文档说得很直接:CLAUDE.md 被当作上下文而不是强制配置;如果要无论模型怎么决定都拦住某个动作,应该用权限规则或 Hooks。它还给了一张分工表:禁止某些命令或文件路径、强制沙箱隔离,放进设置;代码风格、合规提醒、行为指引,放进说明文件。
AGENTS.md 是另一种常见的说明文件。它是一个开放格式,由 Linux 基金会下的 Agentic AI Foundation 维护,本质就是普通 Markdown,没有必填字段。OpenAI 的 Codex 默认读取它,Claude Code 的新版本在项目里没有 CLAUDE.md(或 CLAUDE.local.md)时也会直接读取它。
写什么,不写什么
好的说明文件只写“模型每次会话都需要、又无法从代码里推断出来”的东西。
| 该写 | 不该写(应该放到哪里) |
|---|---|
| 构建、测试、检查命令 | 能从代码看出来的目录清单、依赖列表(删掉) |
| 与工具默认习惯不同的约定 | 多步骤的操作流程(做成 Skill) |
| 结构中不显而易见的部分 | 只与某个目录相关的规则(子目录说明或按路径规则) |
| 反复踩过的坑 | 必须百分之百执行的规则(权限规则或 Hook) |
| “总是做 X”的简短规则 | 密钥、账号、个人偏好(环境变量、个人级文件) |
一份售后工单系统仓库的 AGENTS.md 可以是这样:
# AGENTS.md —— 售后工单系统
## 常用命令
- 安装依赖:`pnpm install`
- 单元测试:`pnpm test`(改动 `src/` 后必须运行)
- 类型检查:`pnpm typecheck`
## 不显而易见的结构
- 工单状态只能通过 `src/tickets/state.ts` 里的状态机修改
- `legacy/` 是旧系统的只读镜像,不要修改
## 约定
- 金额一律用“分”为单位的整数,不用浮点数
## 容易踩的坑
- 本地跑测试前要先执行 `docker compose up redis`
几条来自 Claude Code 文档的写作建议,对其他工具同样适用:
- 短:每个文件建议控制在 200 行以内,越长越占上下文,遵循度也越低。
- 具体到可验证:写“用两个空格缩进”,而不是“代码格式要规范”;写“提交前运行
pnpm test”,而不是“注意测试”。 - 不自相矛盾:两条规则打架时,模型可能随便选一条。定期检查各层文件,删掉过时和冲突的内容。
- 拆分不等于省预算:
@路径形式的导入能让文件更好维护,但被导入的文件同样在启动时加载,照样占上下文。 - 从生成开始:在 Claude Code 里运行
/init可以根据代码库生成一份初稿,再补上它推断不出来的内容。
多层说明文件如何叠加
真实项目里,说明文件往往不止一份:组织统一下发的、你个人的、仓库根目录的、某个子服务的。两种主流工具的叠加方式如下:
Claude Code 的规则(来自官方文档):
- 四个位置:组织托管的说明文件、用户级
~/.claude/CLAUDE.md、项目级./CLAUDE.md(或./.claude/CLAUDE.md)、个人本地的./CLAUDE.local.md(应加入.gitignore)。 - 启动目录及其所有上级目录中的说明文件在启动时加载,全部拼接,互不覆盖,从文件系统根目录往下排,离启动目录越近越靠后;同一目录里
CLAUDE.local.md排在CLAUDE.md之后。 - 子目录里的说明文件在 Agent 读到该目录下的文件时才加载。规则还可以拆到
.claude/rules/目录,用paths声明适用的文件,只在处理匹配文件时进入上下文。 - 组织托管的说明文件不能被个人设置排除;大型 monorepo 可以用
claudeMdExcludes跳过其他团队的说明文件。
Codex 的规则(来自 OpenAI 官方文档):
- 全局层:在 Codex 主目录(默认
~/.codex)里,有AGENTS.override.md就读它,否则读AGENTS.md,只取一个。 - 项目层:从项目根(通常是 Git 根目录)逐级走到当前目录,每个目录最多取一个文件,优先级是
AGENTS.override.md、AGENTS.md,再到配置的备用文件名。 - 从根往下拼接,越靠近当前目录的越靠后,因而会“覆盖”前面的指引;合并后的总大小默认上限 32 KiB,超出部分不再加入。
两者的共同点值得强调:多层说明是拼在一起给模型看的,“覆盖”只是模型倾向于相信更靠后、更具体的那条。 程序不会替你解决冲突,所以最好的做法是从源头上不写冲突。
一份文件,多个工具共用。 如果团队同时用 Claude Code 和 Codex,常见做法是把通用内容写进 AGENTS.md,再放一个只有一行 @AGENTS.md 导入的 CLAUDE.md,下面追加只对 Claude 生效的内容。注意 Claude Code 默认只在没有 CLAUDE.md 时才直接读 AGENTS.md,一旦有了 CLAUDE.md,就要靠导入把它带进来。
配置分层与优先级
说明文件管“模型怎么想”,配置文件管“Harness 允许什么”。以 Claude Code 为例,设置分成四个文件加一层组织托管,同一个键出现在多层时,取最高层的值:
读这张图要注意三点(均来自 Claude Code 官方文档):
- 单值覆盖,列表合并。 例如默认模型这类单个值,项目本地会覆盖项目共享;而
permissions.allow这类列表会跨层合并,每一层都可以追加条目。 - 权限规则按 deny、ask、allow 的顺序判断。 不论写在哪一层,只要有一条 deny 匹配,操作就会被拦下;更具体的 allow 也不能从 deny 里“挖出”例外。
- 仓库里的文件不能给自己“授权”。 提交到仓库的 allow 规则要等每位同事信任该目录后才生效,而 deny 和 ask 立即生效;把默认权限模式设为自动或跳过审批,在项目文件里也不会生效。这防止了一个陌生仓库克隆下来就给 Agent 放开权限。
一份团队共享的 .claude/settings.json 可以只写团队共识的边界:
{
"permissions": {
"allow": ["Bash(pnpm test)", "Bash(pnpm typecheck)"],
"deny": ["Read(./.env)", "Bash(git push *)"]
}
}
Codex 的配置层级思路相近,从高到低是:命令行参数、项目里的 .codex/config.toml(从项目根到当前目录,越近越优先,且只在信任该项目时加载)、指定的 profile、用户级 ~/.codex/config.toml、组织下发的默认值、系统配置、内置默认值。细节不同,原则一致:越具体、越临时的层越优先;来自仓库的配置要经过信任这一关。
一条规则该写在哪里
把上面的内容合起来,遇到一条新规则时可以按下面的顺序判断:
顺序很重要:先问要不要强制,再问作用范围。 很多团队把“不要推送到主分支”写进说明文件就以为万事大吉,而它本该是一条 deny 规则。说明文件里只留下“为什么”和“应该怎么做”,帮模型一开始就走对路。
常见误区
- “写进
CLAUDE.md就一定会被遵守。” 它是上下文,不是强制配置。必须遵守的规则放进权限规则或 Hook,说明文件负责解释原因和正确做法。 - “说明越详细越好。” 说明文件每次会话都占上下文,越长遵循度越低。能从代码推断的内容删掉,多步骤流程做成 Skill,局部规则按路径加载。
- “子目录的说明会覆盖根目录的。” 两层都会进入上下文,只是子目录的更靠后。两条规则互相矛盾时,模型可能随便选一条,应当改写成一致的规则。
产品经理检查清单
- 仓库里有没有说明文件?它是否只写了命令、约定、坑和“总是做 X”这几类内容?
- 说明文件多长?有没有人定期删掉过时和互相矛盾的条目?
- 哪些规则是“必须百分之百执行”的?它们是否已经落到权限规则或 Hook 里?
- 个人偏好和本地环境信息是否放在了不入库的文件里?
- 团队用了几种 Agent 工具?说明文件是否只维护一份,其余通过导入或兼容机制共用?
- 从仓库带来的配置,是否需要成员信任后才生效?
练习
为你熟悉的一个仓库(没有的话,就用上面的售后工单系统)完成下面三件事,约 45 分钟:
- 写一份不超过 40 行的
AGENTS.md,只包含命令、不显而易见的结构、约定和坑四部分。 - 写一个
CLAUDE.md,用@AGENTS.md导入通用内容,再补一条只对 Claude Code 生效的规则。 - 列出 5 条你原本想写进说明文件的规则,用图 3 的流程逐条判断它们应该落在哪里,并为其中“必须强制”的规则写出对应的
permissions.deny条目。
如果在用 Claude Code,完成后开一个新会话运行 /context,在 Memory files 列表里确认你的文件都被加载了。
延伸阅读
- Claude Code 文档:How Claude remembers your project,
CLAUDE.md的位置、加载顺序、按路径规则,以及与AGENTS.md的关系。 - Claude Code 文档:Settings files and precedence,设置文件的层级与合并规则。
- Claude Code 文档:Configure permissions,权限规则的判断顺序与跨层行为。
- Codex 文档:Custom instructions with AGENTS.md,
AGENTS.md的发现与合并规则。 - Codex 文档:Config basics,
config.toml的配置层级。 - AGENTS.md:开放格式的官方介绍与写作建议。
下一步
说明文件告诉模型“该怎么用工具”,下一课「工具运行时」讲 Harness 这一侧:工具如何注册、参数如何校验、多个调用如何并行,以及超时与超长结果怎么处理。