K3.1.2 Task 3.1

提到一个文件不等于加载了它

在 CLAUDE.md 里写”遵循 docs/coding-style.md 中的标准”只是文本。Claude 读到这句话但不会打开那个文件。要真正把外部内容加载到上下文中,用 @import 语法:@docs/coding-style.md

这一个区别——文本引用 vs @import——是大多数”Claude 无视我们指南”报告的根源。

@import 怎么工作

在 CLAUDE.md 任何位置放 @文件路径。Claude Code 以项目根目录为基准解析路径,把文件内容加载到上下文中,和 CLAUDE.md 其余内容一起。

# 项目标准

@docs/coding-standards.md
@docs/testing-guide.md
@docs/security-policy.md

Claude 看到的是合并后的内容,就像全部写在行内一样。主 CLAUDE.md 保持简短可读。被引用的文件留在它们自然的位置——docs 里、wiki 导出里、团队已经在维护的任何地方。

巨型 CLAUDE.md 是反模式

一个 800 行的全内联 CLAUDE.md 技术上能用。但 8 个开发者都编辑同一个文件时,合并冲突会堆积。一个团队在重构前每月有 12 次 CLAUDE.md 合并冲突。

拆成 120 行的 CLAUDE.md 加 6 个 @import 引用后,合并冲突降到每月 2 次。指南遵循率保持在 94%——证明 @import 把内容交付给 Claude 和内联完全一样。唯一变的是可维护性。

重构路径很直接:把每个章节提取到自己的文件、用 @文件路径 替换内联内容、提交。不需要迁移工具、不需要重建步骤、不需要清缓存。

用户级路径:@~/.claude/...

@import 语法支持 ~/ 路径。@~/.claude/team-preferences.md 解析到每个开发者的 home 目录。

这产生了和用户级 CLAUDE.md 一样的”我机器上能用”陷阱。创建了文件的现有团队成员看到它能用。从没创建过的新人什么也得不到——import 悄悄解析为空。如果被引用的文件必须每个人都有,它就该在项目仓库里,不是用户 home 目录。

这个模式在跨领域场景也会出现。项目的 .mcp.json 可能用 ${GITHUB_TOKEN} 做 MCP server 认证,而 CLAUDE.md 用 @import 引用本地设置指南。两个都依赖本地资源——环境变量和本地文件。新开发者两个都没配,同时遇到两个失败,根因相同:本地设置缺失。

过度 import 适得其反

一个架构师曾提议:“每个子目录的 CLAUDE.md 都应该交叉 import 所有其他的,这样 Claude 总是有完整上下文。”

12 个子目录、3000 行合计下来,编辑前端 UI 代码时加载了后端 API 规则。写单元测试时加载了基础设施 Terraform 规则。目录级层级的存在就是为了把规则范围限定到相关的地方。交叉 import 一切撤销了这个范围划定,在噪音上浪费上下文 token。

正确做法:只 @import 真正共享的标准。如果 coding-style.md 和 security.md 处处适用,从根 CLAUDE.md import。如果 backend-api.md 只和后端代码有关,留在后端目录的 CLAUDE.md 或 path 范围的规则文件中。

@import 和 .claude/rules/ 结合

选择性加载——全局标准始终加载,区域专属标准有条件加载——用两种机制一起:

  1. 根 CLAUDE.md 带 @import 放处处适用的标准(编码风格、安全策略)。
  2. .claude/rules/ 文件带 paths frontmatter 放只适用于特定文件类型或目录的标准。
# 根 CLAUDE.md
@docs/coding-standards.md
@docs/security-policy.md
# .claude/rules/backend-api.md
---
paths:
  - "src/api/**"
---
[后端 API 规范在这里]

全局标准每次编辑都加载。后端规则只在编辑 src/api/ 文件时加载。没有重复,没有无关上下文,没有条件注释 hack。

不存在的东西

  • HTML 风格的 <include src="..."/> — 不是 CLAUDE.md 特性。用 @文件路径
  • YAML imports: frontmatter — YAML frontmatter 是给 .claude/rules/ 的 path 配置用的,不是给 CLAUDE.md import 用的。
  • 基于注释的条件加载<!-- backend only -->)— 所有 @import 的内容无条件加载。条件范围来自文件放置和 paths glob。
  • import 深度限制 — 没有在 2 层或其他深度的静默截断。
  • 缓存或索引重建@import 在每次会话加载时解析。不需要清缓存,不需要跑重建命令。

一句话总结: @文件路径 把文件加载到上下文中——纯文本提及不会——这两者的区别解释了大多数”Claude 无视我们指南”的问题。