# Lesson 5.1: 上下文治理分层——Memory、Rules 与 AGENTS.md

## 本课目标

- 理解 CLAUDE.md 为什么是上下文治理的入口，而不是全部
- 学会把不同上下文需求分配给 Memory、Rules、AGENTS.md 和事实源
- 掌握 `.claude/rules` 的路径触发写法，避免把所有规则塞进常驻上下文
- 建立“Memory 是提示，不是事实源”的判断习惯

## 核心内容

### 从一个文件到一套治理系统

上一课你学会了写 CLAUDE.md。它解决的是第一个问题：

> 每次 Claude 进入项目时，应该先知道什么？

所以 CLAUDE.md 是**上下文治理入口**。它负责项目级常驻总纲：项目定位、启动命令、测试命令、架构边界、红线和压缩保命信息。

但项目一复杂，治理需求会自然分化：

```text
CLAUDE.md
  ↓ 项目级常驻总纲：启动、测试、架构边界、红线

需求开始分化：
  ↓ 个人偏好 / 协作习惯 / 历史原因
Memory

  ↓ 不同语言 / 不同目录 / 不同文件类型的专项约束
.claude/rules

  ↓ 多 Agent / 多工具生态共享项目说明
AGENTS.md

  ↓ 当前真实状态、接口、函数、配置
代码 / docs / Git / Issue
```

这不是“多几个配置文件”，而是上下文需求长大后自然拆层。你要做的不是记住文件名，而是判断：**这条信息应该常驻、按需、长期记忆，还是现查事实源？**

### 五类上下文载体

| 载体 | 一句话定位 | 最适合放什么 |
|------|-----------|--------------|
| **CLAUDE.md** | 项目级常驻入口 | 启动、测试、架构边界、团队红线 |
| **AGENTS.md** | 跨工具项目说明 | 多 Agent / Codex / Cursor / Aider 都要共享的约束 |
| **Memory** | 个人化长期记忆 | 用户偏好、协作习惯、历史原因、外部线索 |
| **.claude/rules** | 模块化专项规则 | 语言、目录、文件类型、API 契约相关规则 |
| **代码 / docs / Git / Issue** | 当前事实源 | 函数位置、真实接口、配置值、任务状态 |

判断标准很简单：

```text
所有人、所有任务都要知道？        → CLAUDE.md
多个 Agent 工具都要知道？         → AGENTS.md
只跟这个用户长期协作有关？        → Memory
只在某些路径或技术栈下成立？      → .claude/rules
会随代码变化、必须保持最新？      → 代码 / docs / Git / Issue
```

### AGENTS.md：跨工具共享说明

如果你的团队只用 Claude Code，`CLAUDE.md` 就是首选入口。

但如果团队同时使用 Claude Code、Codex、Cursor、Aider 或其他 Agent 工具，就需要一个更通用的入口：`AGENTS.md`。

```text
CLAUDE.md
  面向 Claude Code，可以写 Claude Code 专属命令、Hooks、Skills、settings。

AGENTS.md
  面向所有 Agent 工具，写跨工具都成立的项目约束。
```

推荐分工：

| 场景 | 放哪里 |
|------|--------|
| `npm test`、目录结构、核心架构边界 | CLAUDE.md 或 AGENTS.md |
| `/cc4pm-guide`、Claude Code Hooks、Skills 触发方式 | CLAUDE.md |
| 所有 Agent 都必须遵守的安全红线 | AGENTS.md |
| Claude Code 独有的状态栏、权限、Skill 说明 | CLAUDE.md |

关键是避免重复。不要把同一大段规则复制到两个文件里，否则几个月后一定会过期、冲突。


### Memory：记人和原因，不记代码事实

Memory 解决的是另一个问题：

> 这个用户和 Agent 长期协作时，有哪些偏好、纠正和背景应该被记住？

适合写入 Memory：

| 信息 | 示例 |
|------|------|
| 沟通偏好 | “回答先给结论，再给细节” |
| 反复纠正过的行为 | “不要默认创建新文档，优先修改现有文件” |
| 非显然工作方式 | “课程内容先保持叙事线，再补工具细节” |
| 外部资源线索 | “客户反馈记录在某个外部系统，使用前先确认链接” |
| 历史决策原因 | “选择轻量脚本而不是服务化，是为了降低维护成本” |

不适合写入 Memory：

| 信息 | 为什么不适合 |
|------|--------------|
| 某函数在哪个文件 | 代码会变，现查更准 |
| 某 API 当前字段 | 接口会变，读 docs 或代码 |
| 当前任务下一步 | 这是临时状态，用 task / issue / plan |
| 密钥、Token、账号密码 | 安全风险 |
| 团队工程规范 | 应进入 CLAUDE.md、Rules 或 docs |

Memory 的核心原则：

> Memory 是提示和索引，不是事实源。

所以当 Memory 涉及当前代码、文件、函数、接口或配置时，你要让 Claude 先验证：

```text
Memory 提到文件路径 → 检查文件是否存在
Memory 提到函数名字 → grep 或读代码确认
Memory 提到外部文档 → 打开权威来源确认
Memory 和当前代码冲突 → 以当前代码和正式文档为准
```

### Rules：不同语言、文件和目录的专项约束

Rules 解决的是第三类问题：

> 这条规则不是所有任务都需要，但在某些路径、语言或文件类型下必须生效。

比如：

- Python 文件必须补类型提示
- API/RPC 契约不能随意新增字段
- 数据库 migration 必须先考虑回滚
- React 组件目录必须遵守特定拆分方式

这些规则如果全塞进 CLAUDE.md，会让入口文件膨胀，反而降低信噪比。更好的做法是拆到 `.claude/rules/`。

#### 全局项目规则

没有 frontmatter 的 rule 更像项目级补充规则：

```md
修改 API 契约前，必须先检查调用方和测试；不允许只改服务端不改客户端。
```

适合：短小、硬约束、所有任务都可能相关的规则。

#### 路径触发规则

路径相关规则使用 YAML frontmatter 的 `paths` 字段：

```md
---
paths:
  - "src/**/*.ts"
  - "tests/**/*.ts"
---

TypeScript 代码必须避免 any。外部输入先用 unknown 接住，再用 schema 或类型守卫收窄。
```

当 Claude 处理匹配路径的文件时，这条规则才会进入上下文。

再看一个 API 契约规则：

```md
---
paths:
  - "src/**/api/**/*.ts"
  - "src/**/rpc/**/*.ts"
---

修改 API/RPC 契约时，不要在未确认下游调用方的情况下新增字段；优先复用既有 error_code 语义。
```

注意：不要把 Cursor Rules 的字段直接搬过来：

```md
---
description: "..."
globs:
  - "**/*.py"
alwaysApply: true
---
```

Claude Code 的路径触发重点是：

```md
---
paths:
  - "..."
---
```

如果你想让规则总是生效，优先使用无 frontmatter 的 rule，或者把短规则放回 CLAUDE.md。

### 事实源：代码、文档、Git 和 Issue

上下文治理最容易犯的错，是把 Memory 当数据库，把 CLAUDE.md 当百科全书。

真正的事实源永远是当前项目状态：

| 事实类型 | 应该查哪里 |
|----------|------------|
| 函数、类、模块位置 | 代码搜索 |
| 当前依赖版本 | package.json、lockfile、配置文件 |
| 接口字段 | API 文档、schema、测试、服务端代码 |
| 当前任务状态 | issue、PR、任务列表、计划文件 |
| 架构决策 | docs / ADR / 设计文档 |
| 最近发生了什么 | Git log、PR、commit diff |

一个好习惯：当 Claude 引用 memory 或旧文档时，你可以要求它先验证：

```text
“先不要根据记忆回答。请读取当前代码和 course-map.yaml，验证后再给结论。”
```

这句话能防止大量“记忆正确但已经过期”的错误。

### LLM Wiki 视角：项目目录全景

把 `.claude/` 目录看成一个 **LLM Wiki**（AI 的项目知识库），CLAUDE.md 就是这个 Wiki 的首页。Wiki 的价值不仅在于系统层面的结构化存放，更在于**微操层面的主动指向**——当你知道某个任务和哪些历史上下文有关，直接用 `@path` 指向它们。下面的目录结构就是这个 Wiki 的完整页面地图：

```text
Project/
├── CLAUDE.md                      # 上下文治理入口：项目常驻总纲
├── AGENTS.md                      # 可选：跨 Agent / 跨工具共享说明
├── .claude/
│   ├── rules/                     # 专项规则：路径、语言、文件类型约束
│   │   ├── api-contract.md
│   │   ├── python-type-safety.md
│   │   └── release.md
│   ├── skills/                    # 任务型工作流，按需加载
│   ├── agents/                    # 专家角色，独立上下文执行
│   └── settings.json              # 权限、Hooks、环境变量、MCP
├── docs/
│   ├── architecture.md            # 正式架构事实
│   └── adr/                       # 架构决策记录
└── src/                           # 当前代码事实源
```

加载频率也不同：

```text
              加载频率 ↑
                      │
    CLAUDE.md ●───────│─── 每次必加载，必须精简
    AGENTS.md ●/○─────│─── 跨工具团队常驻，避免重复
    Rules     ●/○─────│─── 全局或路径触发，按主题拆分
                      │
    ──────────────────│──── 分界线：上方是治理规则，下方是按需能力 ────
                      │
    Skills    ○───────│─── 按需加载，可以很详细
    Agents    ○───────│─── 按需启动，独立上下文
    docs      ○───────│─── 需要事实时读取
    code      ○───────│─── 需要事实时搜索
                      │
              加载频率 ↓
```

核心原则：**常驻信息要少，专项规则要按需触发，长期记忆要个人化，事实判断要回到代码和正式文档。**

### 实证研究：Augment 的六条规律

上下文治理不是玄学。Augment Code 用真实 monorepo 中的 `AGENTS.md` 做过评测：同一个任务，有配置文件和没有配置文件分别跑，再对比 Agent 输出质量。

结论很直接：**写得好的配置能显著提升质量，写得差的配置比没有更糟。**

| # | 规律 | 对你的启发 |
|---|------|------------|
| 1 | 渐进披露，不要大而全 | CLAUDE.md 写入口，细节放按需文档 |
| 2 | 步骤化工作流 | 写“先做 A，再做 B”，少写背景介绍 |
| 3 | 决策表解决歧义 | 多方案都合理时，用表格先定路 |
| 4 | 真实代码片段 > 文字描述 | 放 3-10 行真实片段，比长篇说明更有效 |
| 5 | 领域特定规则要克制 | 规则明确可执行才有用，堆太多会失效 |
| 6 | “别做”配“做这个” | 禁止项必须给替代方案 |

最常见的失败模式叫**上下文污染**：入口文件写太多，Agent 被吸引去读不相关资料，把上下文塞满，最后反而完不成任务。

预防问题只有一句：

> 这条规则会不会让 Agent 去翻不相关的文件？

如果会，就把它移到按需文档、路径规则或 Skill 里。

### 反模式清单

#### 把 CLAUDE.md 写成百科全书

问题：所有信息常驻，关键信息被稀释。

更好的做法：

```text
CLAUDE.md 写总纲
Rules 写专项细则
docs / ADR 写正式技术决策
代码和测试做事实源
```

#### 把 Memory 当数据库

问题：Memory 会过期，也可能被错误总结。

更好的做法：Memory 只记录个人偏好、协作原因和外部线索；项目事实现查。

#### Rules 的 paths 过宽

```md
---
paths:
  - "**/*"
---
```

这等于失去路径触发意义。

更好的写法：

```md
---
paths:
  - "src/**/api/**/*.ts"
  - "tests/api/**/*.ts"
---
```

#### 把个人偏好提交到项目规则

“回答用户时不要追加推销式结尾”更适合 Memory，不适合提交到项目 `.claude/rules/` 影响所有人。

#### 把当前任务状态写进长期记忆

“当前正在修 xxx bug，下一步跑测试”应该放 task、issue 或 plan，不应该写入长期 Memory。

## 动手试试

### 练习 1：给信息找位置

把下面五条信息分配到合适位置：

| 信息 | 你会放哪里？ |
|------|--------------|
| “本项目测试命令是 `npm test`” | CLAUDE.md |
| “用户喜欢先看结论再看细节” | Memory |
| “修改 `src/api/**` 时必须检查调用方” | `.claude/rules` + paths |
| “这个函数现在叫 `loadCourseMap`” | 不保存，现查代码 |
| “团队同时使用 Claude Code 和 Codex” | AGENTS.md |

### 练习 2：写一条路径规则

在自己的项目里设计一条只对 API 文件生效的规则：

```md
---
paths:
  - "src/**/api/**/*.ts"
---

修改 API 返回结构前，必须先检查客户端调用方和相关测试；如果字段含义变化，更新文档示例。
```


## 常见问题

**Q: 有了 CLAUDE.md，还需要 AGENTS.md 吗？**

A: 如果只用 Claude Code，不一定需要。只有当团队多 Agent 工具混用，并且希望共享同一套项目说明时，AGENTS.md 才有价值。

**Q: Memory 里能不能记项目背景？**

A: 可以记“代码里看不出来的背景”和“为什么这么做”，但不要把它当事实源。涉及当前文件、接口、函数、配置时，必须读取当前项目状态验证。

**Q: Rules 和 CLAUDE.md 都会加载，那为什么还要拆？**

A: 拆分的价值是降低入口噪音，并让路径相关规则只在相关任务中出现。CLAUDE.md 负责总纲，Rules 负责专项约束。

**Q: 架构决策应该放 Memory 吗？**

A: 不应该只放 Memory。架构决策影响团队所有人，应该写入 docs / ADR，并被 Git 管理。Memory 最多记录“下次先看哪份 ADR”。

## 下一步

请调用 `AskUserQuestion` 展示以下选项，让学习者点击选择；从每条中提炼 1-5 个词作为 label，其余写入 description，不要要求输入数字：

- 进入补充课：Lesson 5.2 - 持久上下文运维
- 返回主菜单
- 退出学习

---
*阶段 1 | Lesson 5.1/26 | 上一课: Lesson 5 - CLAUDE.md | 下一课: Lesson 5.2 - 持久上下文运维*
