← 返回信息流
Agent SkillLINUX DO · AI·2026/4/1

深挖Claude Code源码:CLAUDE.md注入机制与优先级详解

原标题:深入浅出 Claude Code(一):从源码理解 CLAUDE.md,重写你的配置

速览

本文深入剖析Claude Code源码,纠正CLAUDE.md被拼入System Prompt的误区,指出其实际作为User Message注入。文章详细解释了加载顺序决定的优先级机制,即后加载内容权重更高,并建议编写具体可验证的指令以对抗降权信号。

AI 深度解读

背景

在 AI 辅助编程领域,Claude Code 作为 Anthropic 推出的基于终端的代码智能体,其配置灵活性深受开发者关注。其中,CLAUDE.md 文件常被用户视为自定义 AI 行为的关键入口。然而,许多用户在使用中存在认知误区:往往随意编写几条模糊规则,发现效果不佳后便放弃使用。这种低效的根源在于用户并不清楚 CLAUDE.md 的内容在模型底层是如何被解析、注入以及赋予优先级的。

本文基于 Claude Code 的开源源码(如 utils/api.tsutils/claudemd.ts 等),深入剖析其底层逻辑,揭示 CLAUDE.md 的真实工作机制、加载优先级、外部引用规则以及与 Memory 系统的交互方式,旨在帮助开发者从“盲目配置”转向“基于底层逻辑的精准调控”。

核心内容

1. CLAUDE.md 的注入机制与优先级真相

最大的认知误区在于认为 CLAUDE.md 的内容被直接拼接到 System Prompt 中。源码分析显示,事实并非如此。

注入方式 CLAUDE.md 的内容通过 prependUserContext() 函数(位于 utils/api.ts:449-474)注入。它被包裹在 <system-reminder> 标签内,作为第一条 User Message 插入到对话历史的最前端,而非 System Prompt 的一部分。

优先级后果 这种注入方式导致 CLAUDE.md 的优先级天然低于 System Prompt。

  • 宪法 vs 法律:System Prompt 是模型的“宪法”,拥有最高权威;User Message 是“法律”。当两者冲突时,System Prompt 通常胜出。
  • 显式降权信号:注入内容中包含一句关键提示:“IMPORTANT: this context may or may not be relevant to your tasks.” 这是一条显式的降权指令,暗示模型这些内容可能不相关。

对抗降权的策略 尽管存在降权信号,CLAUDE.md 开头包含一条强指令(utils/claudemd.ts:89):“Codebase and user instructions are shown below. Be sure to adhere to these instructions. IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.” 这条指令试图用强语气覆盖默认行为。然而,其效果取决于指令的具体性

  • 模糊指令无效:如“尽量简洁”、“保持专业”等模糊要求,极易被模型忽略。
  • 具体指令有效:如“回答不超过 3 句话”、“不要向未修改的代码添加注释”等可验证、可执行的具体指令,更容易被模型遵守。

2. 文件加载顺序与优先级层级

Claude Code 并非只读取项目根目录的 CLAUDE.md,而是从当前工作目录开始,逐级向上遍历至文件系统根目录,并在多个层级检查特定文件。

文件类型与位置

  • Project 类型:可版本控制。包括 CLAUDE.md.claude/CLAUDE.md 以及 .claude/rules/*.md(递归扫描子目录)。
  • Local 类型:不应提交到版本控制。即 CLAUDE.local.md
  • User 类型:个人全局指令。位于 ~/.claude/CLAUDE.md~/.claude/rules/*.md
  • Managed 类型:企业管理员策略。位于 /etc/claude-code/CLAUDE.md/etc/claude-code/.claude/rules/*.md

加载顺序与优先级 源码注释明确指出:“Files are loaded in reverse order of priority... the latest files are highest priority with the model paying more attention to them.” 即最后加载的文件优先级最高,这利用了模型对输入末尾内容的“近因偏差”(recency bias)。

完整的加载顺序(从低优先级到高优先级)如下:

  1. /etc/claude-code/CLAUDE.md (Managed - 企业策略)
  2. /etc/claude-code/.claude/rules/*.md (Managed)
  3. ~/.claude/CLAUDE.md (User - 个人全局)
  4. ~/.claude/rules/*.md (User)
  5. /repo-root/CLAUDE.md (Project - 仓库根)
  6. /repo-root/.claude/CLAUDE.md (Project)
  7. /repo-root/.claude/rules/*.md (Project)
  8. /repo-root/src/CLAUDE.md (Project - 更近目录)
  9. /repo-root/src/.claude/rules/*.md (Project)
  10. /repo-root/src/feature/CLAUDE.md (Project - 当前目录)
  11. /repo-root/src/feature/CLAUDE.local.md (Local - 最高优先级)

最佳实践建议

  • 仓库根目录:放置通用的 .claude/rules/ 规则。
  • 个人偏好:放在 ~/.claude/CLAUDE.md
  • 子目录特定规则:例如在 frontend/CLAUDE.md 中指定“使用 React 不用 Vue”。
  • 就近原则:离当前工作目录越近的文件,优先级越高。

3. @include 指令与模块化配置

CLAUDE.md 支持使用 @ 语法引入外部文件,实现配置的模块化。

解析逻辑

  • @./path@path:相对于当前 CLAUDE.md 文件的路径。
  • @~/path:相对于 Home 目录。
  • @/path:绝对路径。
  • 支持转义空格:@./my\ file.md
  • 支持 #fragment 后缀(被忽略):@./rules.md#section-1

安全与限制

  • 扩展名白名单:仅支持文本文件,包括 .md, .txt, .json, .yaml, .ts, .py, .go, .rs, .sql 等约 80 种扩展名。二进制文件被静默忽略。
  • 循环引用检测:通过 processedPaths Set 追踪已处理路径,并设置最大递归深度 MAX_INCLUDE_DEPTH 防止无限循环。
  • 代码块免疫@ 指令仅在 Markdown 的文本节点中生效。代码块(code blocks)或行内代码(inline code)中的 @ 不会被解析。
  • 外部文件审批:引入工作目录以外的文件需要配置项 claudeMdExternalIncludesApproved 启用。User 类型的 CLAUDE.md 默认允许引入,但 Project 类型需要显式审批。
  • 静默忽略:如果引用的文件不存在,系统不会报错或中断加载。

模块化示例

# 项目根目录 CLAUDE.md

@.claude/rules/code-style.md
@.claude/rules/git-conventions.md
@.claude/rules/testing.md

4. Memory 系统机制

Memory 系统(位于 memdir/)与 CLAUDE.md 是两套独立机制,但在 System Prompt 中紧密相邻。

加载与截断 Memory 通过 loadMemoryPrompt() 加载,注入到 System Prompt 的动态部分(SYSTEM_PROMPT_DYNAMIC_BOUNDARY 之后)。

  • 硬编码限制MAX_ENTRYPOINT_LINES = 200 行,MAX_ENTRYPOINT_BYTES = 25,000 字节(25KB)。
  • 截断逻辑:先按行截断至 200 行,若仍超限,则在最后一个换行符处切断。
  • 警告信息:截断后会追加警告:“WARNING: MEMORY.md is 350 lines (limit: 200). Only part of it was loaded. Keep index entries to one line
查看原文 →linux.do