编写高质量的 CLAUDE.md
注意:本文也适用于 AGENTS.md,这是相当于开源版 CLAUDE.md 的文件,主要用于 OpenCode、Zed、Cursor 和 Codex 等 Agent 与工具。
## 原则:LLMs (极大程度上) 是无状态的
LLMs 是无状态函数。它们的权重在用于推理时已被冻结,因此它们不会随时间推移而学习。模型对你的代码库的了解仅限于你输入的 token。
同样,像 Claude Code 这样的编程智能体工具通常需要你显式地管理智能体的记忆。CLAUDE.md(或 AGENTS.md)是默认情况下唯一会被包含在你与智能体进行的每一次对话中的文件。
这有三个重要的含义:
- 编程智能体在每次会话开始时,对你的代码库完全一无所知。
- 每次启动会话时,你都必须把所有关于代码库的重要信息告诉 AI 智能体。
CLAUDE.md是实现这一点的首选方式。
## CLAUDE.md 帮助 Claude 快速上手你的代码库
由于 Claude 在每次会话开始时对你的代码库都一无所知,你应该使用 CLAUDE.md 来引导 Claude 熟悉你的项目。概括来说,该文件应该包含以下内容:
- WHAT(是什么):向 Claude 介绍所用的技术、技术栈以及项目结构。给 Claude 提供一份代码库的地图。这点在单一代码库(monorepos)中尤为重要!告诉 Claude 有哪些应用、哪些是共享包,以及每个部分的作用,这样它就知道该去哪里查找内容。
- WHY(为什么):告诉 Claude 该项目的目的以及代码库中各部分都在做什么。项目不同部分的意图和功能分别是什么?
- HOW(怎么做):告诉 Claude 它应该如何在这个项目上开展工作。例如,你是使用
bun而不是node吗?你需要包含它在该项目上进行实质性工作所需的所有信息。Claude 如何验证它所做的更改?它如何运行测试、类型检查和编译步骤?
但是,你执行此操作的方式很重要!不要试图把你认为 Claude 可能需要运行的每一条命令都塞进你的 CLAUDE.md 文件中——这样效果反而不理想。
## Claude 经常忽略 CLAUDE.md
无论你使用的是哪种模型,你可能会注意到 Claude 经常忽略你 CLAUDE.md 文件的内容。
你可以通过 ANTHROPIC_BASE_URL 在 claude code CLI 和 Anthropic API 之间设置一个日志代理来亲自调查这一点。Claude code 会将包含你 CLAUDE.md 文件的以下系统提醒注入到发送给智能体(agent)的用户消息中:
<system-reminder>
IMPORTANT: this context may or may not be relevant to your tasks.
You should not respond to this context unless it is highly relevant to your task.
</system-reminder>
结果就是,如果 Claude 认为 CLAUDE.md 的内容与当前任务无关,它就会忽略这些内容。文件中包含的非普遍适用于你正让它处理的任务的信息越多,Claude 就越有可能忽略你在文件中的指令。
Anthropic 为什么要加入这个? 虽然很难断言,但我们可以推测一下。我们遇到的大多数 CLAUDE.md 文件都包含大量并不具有广泛适用性的指令。许多用户把这个文件当作一种添加“热修补丁”的方式,用来纠正他们不喜欢的行为,结果附加了大量未必普遍适用的指令。
我们只能假设,Claude Code 团队发现,通过告诉 Claude 忽略那些糟糕的指令,这个工具实际上能产出更好的结果。
## 创建优秀的 CLAUDE.md 文件
下文将基于上下文工程的最佳实践 ,就如何编写优质的 CLAUDE.md 文件提供一系列建议。
具体情况可能因人而异。 并非所有规则都一定适用于每种设置。就像做任何事情一样,一旦你满足以下条件,大可不必拘泥于这些规则……
- 你理解何时以及为何可以打破规则
- 你有充分的理由打破规则
### 少即是多(的指令)
人们很容易想要把 Claude 可能需要运行的每一条命令,以及你的代码规范和风格指南全都塞进 CLAUDE.md 里。 我们建议不要这样做。
虽然对这个话题尚未进行极为严谨的调查,但已有一些研究表明了以下几点:
- 前沿的具备思考能力的 LLMs 能够保持合理的一致性,遵循大约 150-200 条指令。 较小的模型比较大的模型能顾及的指令更少,非思考型模型比思考型模型能顾及的指令也更少。
- 较小的模型表现会迅速且急剧地下降 。具体来说,随着指令数量的增加,较小模型的指令遵循能力往往呈现指数级衰减,而前沿的大型思考模型则表现为线性衰减(见下文)。因此,我们建议不要使用较小的模型来执行多步骤任务或复杂的实施计划。
- LLM 更倾向于关注提示词边缘的指令 :即最开头的(Claude Code 系统消息和
CLAUDE.md)以及最末尾的(最新的用户消息) - 随着指令数量的增加,指令遵循的质量会均匀下降 。这意味着,当你给 LLM 提供更多指令时,它并不会单纯地忽略较新的(即“文件中较靠后的”)指令——而是开始均匀地、整体地忽略所有指令

我们对 Claude Code 利用架构(harness)的分析表明,Claude Code 的系统提示词包含了约 50 条独立指令 。根据你使用的模型不同,这可能已经占据了你的智能体(agent)所能可靠遵循的指令总数的近三分之一——而这还没算上规则、插件、技能或用户消息。
这意味着你的 CLAUDE.md 文件应包含尽可能少的指令——理想情况下,只保留那些对你的任务普遍适用的指令。
### CLAUDE.md 文件的长度与适用性
在其他条件相同的情况下, 如果 LLM 的上下文窗口中充满了诸如示例、相关文件、工具调用和工具结果等聚焦且相关的内容,它在任务上的表现将会更好 ,而如果其上下文窗口中充斥着大量不相关的内容,表现则会相对较差。
由于 CLAUDE.md 会进入每一个会话 ,你应该确保其内容具有尽可能广泛的适用性。
例如,要避免包含(举个例子)关于如何构建新数据库模式的指令——因为当你处理其他不相关的工作时,这些内容不仅无关紧要,还会干扰模型的注意力!
在长度方面, 少即是多的原则同样适用。虽然 Anthropic 对于 CLAUDE.md 文件的长度没有官方建议,但普遍的共识是最好控制在 300 行以内,而且越短越好。
在 HumanLayer,我们根目录下的 CLAUDE.md 文件不足六十行 。
### 渐进式披露 (Progressive Disclosure)
编写一份既简洁又能涵盖 Claude 所需全部知识的 CLAUDE.md 文件可能具有挑战性,尤其是在大型项目中。
为了解决这个问题,我们可以利用渐进式披露(Progressive Disclosure) 原则,确保 Claude 只有在需要时才看到特定于任务或项目的指令。
建议不要将构建项目、运行测试、代码规范或其他重要上下文的所有指令都堆积在 CLAUDE.md 文件中,而是将针对特定任务的指令保存在项目某处的独立 Markdown 文件中,并使用具有自描述性的文件名。
例如:
agent_docs/
|- building_the_project.md
|- running_tests.md
|- code_conventions.md
|- service_architecture.md
|- database_schema.md
|- service_communication_patterns.md
然后,在你的 CLAUDE.md 文件中,你可以列出这些文件及其简要说明,并指示 Claude 决定哪些文件(如果有的话)是相关的,并在开始工作前读取它们。或者,你也可以让 Claude 先列出它想要读取的文件供你批准,然后再进行读取。
首选指针引用而非直接复制 。如果可能,不要在这些文件中包含代码片段——它们很快就会过时。相反,应包含 文件:行号 引用,指向权威的上下文供 Claude 参考。
从概念上讲,这与 Claude Skills 的运作意图非常相似,尽管 Skills 更侧重于工具的使用,而非指令。
### Claude (不)是一个昂贵的代码检查工具
我们看到人们最常放进 CLAUDE.md 文件中的内容之一就是代码风格指南。 千万不要让 LLM 去做代码检查工具(Linter)该做的工作 。相比传统的代码检查工具和格式化工具,LLMs 的成本相当高昂,而且速度极其缓慢。我们认为,只要有可能,你应该始终使用确定性的工具 。
代码风格指南不可避免地会在你的上下文窗口中加入一堆指令和大部分不相关的代码片段,这会降低 LLM 的性能和指令遵循能力,并消耗宝贵的上下文窗口空间。
LLMs 是上下文学习者 !如果你的代码遵循特定的风格指南或模式,你应该会发现,通过对代码库进行几次搜索(或参考一份好的研究文档!),你的智能体(agent)往往会倾向于遵循现有的代码模式和约定,而无需额外指示。
如果你对此非常在意,甚至可以考虑设置一个 Claude Code Stop 钩子 ,用于运行格式化程序和代码检查工具(linter),并将错误展示给 Claude 让其修复。不要让 Claude 自己去查找格式问题。
加分项 :使用一个能够自动修复问题的代码检查工具(我们喜欢 Biome),并仔细调整你的规则,确定哪些内容可以安全地被自动修复,从而实现最大程度的(安全)覆盖。
你也可以创建一个 Slash Command(斜杠命令),在其中包含你的代码规范,并指示 Claude 关注版本控制中的变更,或者你的 git status 等内容。通过这种方式,你可以将功能实现与格式调整分开处理。 这样一来,你在两方面都会看到更好的结果 。
### 不要使用 /init 或自动生成你的 CLAUDE.md
Claude Code 和其他使用 OpenCode 的工具都提供了自动生成 CLAUDE.md 文件(或 AGENTS.md)的方法。
因为 CLAUDE.md 会进入 Claude Code 的每一个会话中,所以它是该工具杠杆率最高的关键点之一——至于是好是坏,则取决于你如何使用它。
一行糟糕的代码仅仅是一行糟糕的代码。但在实施计划中哪怕出现一句糟糕的描述,都有可能导致生成大量糟糕的代码。而在调研阶段,如果对系统工作原理产生了一句误解,则可能导致计划中出现大量错误描述,进而最终导致生成更多糟糕的代码。
但是,CLAUDE.md 文件会影响你工作流程的每一个环节以及由此产生的所有生成物。因此,我们认为你应该花点时间,非常仔细地推敲写入其中的每一行内容:

## 结语
CLAUDE.md旨在帮助 Claude 熟悉你的代码库。它应该定义你项目的 目标(WHY)、 内容(WHAT) 以及方法(HOW)。- (指令)少即是多 。虽然不应遗漏必要的指令,但你应该尽可能精简文件中的指令数量。
- 请确保你的
CLAUDE.md内容简洁且通用 。 - 采用渐进式披露(Progressive Disclosure) 原则——不要试图一次性把所有你希望 Claude 知道的信息都告诉它。相反,告诉它如何查找重要信息,这样它只会在需要时去查找和使用这些信息,从而避免造成上下文窗口臃肿或指令数量过多。
- Claude 不是一个代码检查工具(Linter)。请根据需要使用专门的代码检查工具和代码格式化工具,以及钩子(Hooks) 和斜杠命令(Slash Commands) 等其他功能。
CLAUDE.md是整个工具体系中杠杆率最高的支点 ,因此请避免自动生成它。你应该精心打磨其内容以获得最佳效果。