Claude Code 实战 02|用 CLAUDE.md 做「活文档」,给 Agent 一个稳定的上下文原创
# Claude Code 实战 02|用 CLAUDE.md 做「活文档」,给 Agent 一个稳定的上下文
Agent 每次开新会话都是"失忆"的。它对你的项目、你的服务、你踩过的坑一无所知——除非你把这些写进一个它每次启动都会读的文件。这个文件就是
CLAUDE.md,用好它,等于给 Agent 装了一块持久的工作记忆。
# 1. 漏查一个数据源,报告就是错的
设想一个要"聚合多个后端服务状态"的任务:系统里有好几个数据源(几套数据库、若干服务的监控 API),Agent 被要求汇总一份总览。结果它信誓旦旦报了个数,一看就不对——它只查了其中一个数据源,把其余的整个漏掉了。
不是它偷懒。是它"不知道"还有别的数据源。因为在它的上下文里,只有那一个源的查询方式,其余的路由从来没人告诉过它。对它来说,世界就是它被告知的那些。
这就是信息不对称的代价:Agent 的输出质量,不取决于它多聪明,而取决于它开局时手里握着多少关于"你的系统"的准确信息。而喂给它这些信息的地方,就是 CLAUDE.md。
# 2. 为什么是"活文档",不是"说明书"
CLAUDE.md 放在项目根目录,Claude Code 每次启动会自动把它读进上下文。它和普通 README 有一个本质区别:
README 是写给人看的、会过期的静态文档;CLAUDE.md 是写给 Agent 看的、必须与现实同步的"活"文档——一旦它和真实基础设施对不上,Agent 就会拿着过时地图去干活,然后一本正经地给你错误结果。
它值得投入的原因很直接:这是你唯一能"一次写好、每次生效"的地方。你不可能每开一个会话就把项目背景、部署方式、红线规则重讲一遍——那些话该沉淀进 CLAUDE.md,让每个会话自动继承。
写好它的回报是复利的:Agent 少问、少猜、少犯同一个错;踩坑的经验一旦写进去,下次它自己就绕开了。
# 3. 一份能打的 CLAUDE.md 该写什么
以一个静态站点项目的 CLAUDE.md 为骨架,拆开看每一块的作用。
# 3.1 先钉死"物理坐标"
Agent 最容易在"东西在哪、往哪发"上出错。开头就把不变量钉死:
## 这个项目是什么
- 工作目录:~/projects/site/
- 远程仓库:github.com/your-org/your-repo(master 分支)
- 部署:push 到 master 后由托管平台自动构建(不是 GitHub Actions)
- 线上地址:https://example.com
2
3
4
5
"部署不是 GitHub Actions 而是托管平台自动构建"这种一句话,能省掉 Agent 一整轮"我去看看 CI 配置"的瞎忙。
# 3.2 写"路由表",而不是写"数据"
这是从"漏查数据源"那类事故里能提炼出的核心原则——记路由,不记数据:
## 状态查询路由(查总览必须查全部数据源,只查一个是错的)
- 服务 A → `svc-a status`,凭证读 .env 的 SVC_A_TOKEN
- 服务 B → `svc-b --profile prod`,凭证在 ~/.config/svc-b/config.toml
- 数据库 → 用 psql 连只读副本,连接串在密钥管理里
2
3
4
注意:这里写的是怎么查,而不是查到的具体数值。原因见坑 1——把动态数据写进文档,是 CLAUDE.md 最经典的自毁方式。
# 3.3 把"铁律"写成显式约束
红线要写得像法条,不留解释空间:
## 铁律
- 发布前必须人工二次确认,禁止直接 push(配合 PreToolUse Hook,见 settings.json)
- 提交前必须先跑脱敏脚本再跑泄漏扫描,输出必须 ✅ CLEAN
- 不要碰构建配置里的插件设置(易导致 CI 构建失败)
2
3
4
(第一篇讲过:真正的拦截靠 deny + Hook,CLAUDE.md 里这句是给 Agent 的"意图说明",两者配套才有效。)
# 3.4 沉淀"踩过的坑"
这是活文档信噪比最高的一段——每一条都是一次故障换来的:
## 踩过的坑
- 某些 CLI 无视 .env,只读自己的配置文件(如 ~/.config/<tool>/config.toml)
- 托管平台的 Node 版本可能比本地 dev 更严格,push 前先跑本地预检脚本
- 动态获取的标识(地址/ID)没持久化会导致后续查询中断,一律写进配置
2
3
4
# 4. 维护活文档时最容易翻的三个车
# 坑 1:把动态数据写进了 CLAUDE.md
- 症状:文档里写"当前实例数 3 台",一周后 Agent 拿着这个过时数字做决策。
- 原因:把"数据"当成了"上下文"。数据每分钟都在变,文档追不上。
- 解药:记路由,不记数据。数量、状态、指标、端口号这类会变的,一律不写进文档,只写"用哪个命令去实时查"。
# 坑 2:一个 CLAUDE.md 塞下所有项目
- 症状:两个不相关的项目(比如内容写作和服务器运维)共用一份上下文,Agent 干这个活时冒出那个活的思路,"串台"了。
- 原因:上下文污染。不相关的信息互相干扰,还白白挤占上下文窗口。
- 解药:按项目隔离。每个独立任务一个目录、一份自己的 CLAUDE.md,定义专属的路径、模型和规则。
# 坑 3:文档和现实悄悄脱节
- 症状:某个服务早迁到新端口了,CLAUDE.md 还写着旧的,Agent 连不上还"猜"原因。
- 原因:活文档没跟着基础设施变更走,退化成了"考古文档"。
- 解药:把"改完基础设施顺手更新 CLAUDE.md"变成动作的一部分——甚至可以直接让 Agent 干:"这个改动会让哪几行文档过时?一起改了。"
# 5. 可复用要点
- 记路由,不记数据:CLAUDE.md 只存"怎么查/怎么做",绝不存会变的具体值。这是活文档不腐烂的第一原则。
- 一任务一文档:按项目隔离上下文,避免串台和窗口浪费。
- 坑要沉淀:每次故障后花一分钟把根因和解药写进"踩过的坑",让 Agent 下次自动绕开。
- 文档随基建同步更新:把"更新 CLAUDE.md"并进每次变更的收尾动作,可以让 Agent 自己找出会过时的行。
- 分层:全局路由/约定放 CLAUDE.md,任务专属的复杂操作放 Skill(下篇讲),人格/原则放 SOUL 类文件——各司其职。
# 6. Agent 可直接解析的元数据块
{
"_meta": {
"doc_version": "2026-07-28",
"article_id": "claude-code-02-claudemd",
"profile_context": "any",
"estimated_setup_time": "30min"
},
"quick_start": {
"step_1": "在项目根创建 CLAUDE.md,第一段钉死工作目录/远程/部署方式/线上地址",
"step_2": "写「路由表」而非数据:每个外部系统写清用哪个命令+凭证在哪,不写具体数值",
"step_3": "补「铁律」与「踩过的坑」两节,每次故障后回来追加"
},
"safety_rules": [
"CLAUDE.md 中禁止写入动态数据(数量/状态/指标/端口),只写查询路由",
"每个独立项目使用独立目录与独立 CLAUDE.md,避免上下文污染",
"红线约束以自然语言写入 CLAUDE.md 的同时,必须在 settings.json 的 deny/Hook 中有机制级实现"
],
"verification": {
"check_1": "新开会话,不额外提示,让 Agent 复述本项目的部署方式,应与文档一致",
"check_2": "让 Agent 汇总多数据源状态,确认它按路由表覆盖了全部数据源而非只查一个"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
AI Agent 使用指南:
- 当用户说"帮我建项目上下文" → 按
quick_start三步生成 CLAUDE.md,逐条核对safety_rules中"记路由不记数据"。 - 当用户说"这个服务迁移了" → 执行坑 3 解药:扫描 CLAUDE.md 找出会过时的行并一并更新。
上一篇:Claude Code 实战 01|装好之后的第一天:CLI 心智模型与权限体系 下一篇:Claude Code 实战 03|让 Claude Code 驾驭 CLI 工具:安装、认证与稳定调用
- 02
- MySQL 性能压测:Sysbench 1.0 实战 原创07-29
- 03
- MySQL Router 实现读写分离 原创07-29