撰写优秀的 CLAUDE.md
注:本文同样适用于 AGENTS.md,这是 CLAUDE.md 在 OpenCode、Zed、Cursor 和 Codex 等开源代理工具中的等效文件。
原则:LLM 基本是无状态的
LLM 是无状态函数。在用于推理时,它们的权重是冻结的,因此不会随时间学习。模型对你的代码库的唯一了解就是你输入给它的标记。类似地,Claude Code 等编码代理工具通常需要你显式管理代理的内存。CLAUDE.md(或 AGENTS.md)是唯一一个默认会进入每一次对话的文件。这有三个重要含义:
CLAUDE.md 引导 Claude 了解你的代码库
由于 Claude 在每次会话开始时对你的代码库一无所知,你应该使用 CLAUDE.md 来引导 Claude 了解你的代码库。从高层次来看,它应该涵盖:
但具体做法很重要!不要试图把 Claude 可能需要运行的每个命令都塞进 CLAUDE.md 文件中——这样效果会很差。
Claude 经常忽略 CLAUDE.md
无论你使用哪个模型,你可能会注意到 Claude 经常忽略 CLAUDE.md 文件的内容。你可以通过在 Claude code CLI 和 Anthropic API 之间使用 ANTHROPIC_BASE_URL 设置日志代理来亲自调查这一点。Claude code 会向代理的系统消息中注入以下提醒,并将你的 CLAUDE.md 文件放在用户消息中:复制
<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 中。我们建议不要这样做。虽然这个话题还没有经过极其严谨的研究,但一些研究已经完成,表明以下几点:
我们对 Claude Code 工具的分析表明,Claude Code 的系统提示包含约 50 条独立指令。根据你使用的模型,这已经占用了你的代理可以可靠遵循的指令中的近三分之一——这还是在添加规则、插件、技能或用户消息之前。这意味着你的 CLAUDE.md 文件应该包含尽可能少的指令——理想情况下只有那些普遍适用于你任务的指令。
CLAUDE.md 文件长度与适用性
在其他条件相同的情况下,当 LLM 的上下文窗口充满聚焦、相关的上下文(包括示例、相关文件、工具调用和工具结果)时,它在任务上的表现会比上下文窗口中有大量无关上下文时更好。由于 CLAUDE.md 会进入每一次会话,你应该确保其内容尽可能普遍适用。例如,避免包含关于(例如)如何构建新数据库模式的指令——当你处理与此无关的其他内容时,这只会分散模型的注意力!就长度而言,少即是多的原则同样适用。虽然 Anthropic 没有关于 CLAUDE.md 文件应该多长的官方建议,但普遍共识是少于 300 行最佳,越短越好。在 HumanLayer,我们的根目录 CLAUDE.md 文件少于六十行。
渐进式披露
编写一个简洁的 CLAUDE.md 文件并涵盖你希望 Claude 了解的所有内容可能具有挑战性,尤其是在较大的项目中。为了解决这个问题,我们可以利用渐进式披露原则,确保 Claude 只在需要时看到特定于任务或项目的指令。我们建议将不同任务的指令(如构建项目、运行测试、编码规范或其他重要上下文)保留在独立的 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 先向你展示它想阅读的文件以获得批准,然后再阅读它们。优先使用指针而非副本。如果可能,避免在这些文件中包含代码片段——它们很快就会过时。相反,使用 file:line 引用将 Claude 指向权威上下文。从概念上讲,这与 Claude Skills 的工作方式非常相似,尽管技能更侧重于工具使用而非指令。
Claude 不是(昂贵的)代码检查工具
我们在 CLAUDE.md 文件中最常看到人们放入的内容之一是代码风格指南。永远不要让 LLM 做代码检查工具的工作。LLM 相对昂贵,而且极其缓慢,相比之下传统的代码检查工具和格式化工具要好得多。我们认为你应该始终使用确定性工具。代码风格指南不可避免地会在你的上下文窗口中添加大量指令和大部分无关紧要的代码片段,降低 LLM 的性能和指令遵循能力,并占用你的上下文窗口。LLM 是上下文学习者!如果你的代码遵循特定的风格指南或模式,你会发现,配备几次代码库搜索(或一份优秀的研究文档!)后,你的代理应该会在没有被明确告知的情况下倾向于遵循现有的代码模式和规范。如果你对此有强烈感受,你甚至可能考虑设置一个 Claude Code ,运行你的格式化工具和代码检查工具,并将错误呈现给 Claude 来修复。不要让 Claude 自己发现格式化问题。加分项:使用能够自动修复问题的代码检查工具(我们喜欢 Biome),并仔细调整关于哪些内容可以安全自动修复的规则,以实现最大(安全)覆盖率。你还可以创建一个斜杠命令,包含你的代码规范,并指向版本控制中的更改,或你的 git status 等类似内容。这样,你可以分别处理实现和格式化问题。这样做会让两者都获得更好的结果。
不要使用 /init 或自动生成 CLAUDE.md
Claude Code 和其他带有 OpenCode 的工具都提供了自动生成 CLAUDE.md 文件(或 AGENTS.md)的方法。因为 CLAUDE.md 会进入每一次与 Claude code 的会话,它是工具中杠杆效应最高的点之一——是好是坏,取决于你如何使用它。一行坏代码就是一行坏代码。实现计划中的一行坏代码有可能产生大量坏代码。一项研究中误解系统工作原理的一行坏代码有可能导致计划中大量坏代码,因此更多坏代码随之产生。但 CLAUDE.md 文件影响工作流程的每一个阶段以及它产生的每一个产物。因此,我们认为你应该花时间仔细思考其中的每一行内容:







评论