Claude Code 上下文工程与 Memory 系统 —— 让 AI 不再"失忆"

你用 Claude Code 做了一上午的功能开发,AI 对你的项目越来越熟。中午吃了个饭回来,重开一个会话——AI 又回到了"第一次见面"的状态。这就是上下文断裂。这篇文章教你如何让 AI 跨会话"记住"关键信息,以及如何管理上下文不让它被污染。


上下文五层模型

Claude Code 在处理你的请求时,实际上有多层信息在同时起作用:

┌─────────────────────────────────────────────────────────┐
│ 第五层:即时层(Immediate Context)                       │
│ 当前对话的内容——你说的、AI 回复的、它读的文件。            │
│ 生命周期:当前会话。窗口关闭就消失。                       │
│ 容量:~200K Token(Claude Opus)                         │
├─────────────────────────────────────────────────────────┤
│ 第四层:任务层(Task Context)                            │
│ 当前任务的上下文——相关文件、相关讨论、中间产物。            │
│ 生命周期:当前任务。任务结束可能就不再需要。                │
│ 容量:随任务复杂度变化                                     │
├─────────────────────────────────────────────────────────┤
│ 第三层:记忆层(Memory)                                  │
│ 跨会话持久化的关键信息——用户偏好、项目决策、已知问题。       │
│ 生命周期:持久化(写入文件)                               │
│ 容量:受 MEMORY.md 索引限制(200 条),但存储无硬上限       │
├─────────────────────────────────────────────────────────┤
│ 第二层:项目层(Project Context)                         │
│ CLAUDE.md、AGENTS.md、Skills 配置、项目结构。              │
│ 生命周期:随 Git 版本管理                                  │
│ 容量:CLAUDE.md 建议 < 200 行,Skills 按需加载             │
├─────────────────────────────────────────────────────────┤
│ 第一层:系统层(System Prompt)                           │
│ Claude Code 内置的系统指令——工具定义、权限规则、格式要求。  │
│ 生命周期:由 Anthropic 维护                               │
│ 容量:固定,不可修改                                       │
└─────────────────────────────────────────────────────────┘

每一层的问题和策略

核心问题 管理策略
即时层 容量有限,新信息会挤掉旧信息 只加载当前需要的内容,用完就释放
任务层 任务切换时上下文残留 一个任务一个会话,完成就 /clear
记忆层 写什么、什么时候写、写了怎么找 有触发条件地写,有结构地存
项目层 写太多 AI 记不住,写太少 AI 乱来 精炼到 200 行以内,只写决策和约束
系统层 不可控 通过 Permissions 间接影响

Memory 五种类型

Claude Code 的 Memory 不是一个大文件,而是按类型分门别类存储的:

.claude/memory/
├── MEMORY.md          # 索引文件(AI 每次启动都会读)
├── user_role.md       # 用户角色和偏好
├── project_context.md # 项目背景和决策
├── feedback_*.md      # 用户反馈和修正记录
├── reference_*.md     # 外部系统引用(Slack 频道、Jira 项目等)
└── decision_*.md      # 关键决策记录

类型一:User(用户记忆)

存什么:
  - 你的角色和背景("我是后端工程师,前端不太熟")
  - 你的偏好("解释概念时用 Python 示例")
  - 你的知识盲区("异步编程不太熟")

什么时候写:
  - 你明确告诉 AI "记住这个"
  - AI 发现你反复问某一类基础问题时
  - 你纠正了 AI 对你角色的判断

示例:
  # user_role.md
  用户是后端工程师(Go/Python),前端经验有限。
  解释前端概念时用后端类比。代码示例首选 Python。
  偏好简洁回复,不喜欢啰嗦。

类型二:Project(项目记忆)

存什么:
  - 项目的核心目标和架构决策
  - 为什么选了 A 技术而不是 B
  - 已知的技术债和待解决问题
  - 重要的里程碑和截止日期

什么时候写:
  - 重大架构决策之后
  - Sprint 计划确定时
  - 记录了新的技术债

示例:
  # project_context.md
  项目:内部 CMS 系统重构
  决策:从 Django 单体 → FastAPI 微服务
  原因:Django ORM 在 50 万行数据下性能不足(#42)
  已知问题:旧系统 3 个 API 的调用方还没迁移完
  截止日期:2026-07-15 MVP 上线

类型三:Feedback(反馈记忆)

存什么:
  - 你纠正 AI 的方式("不是这样做,应该...")
  - AI 犯过的错误和正确的做法
  - 你的代码风格偏好

什么时候写:
  - 你说了"不要这样",然后给了正确的做法
  - AI 的输出被多次修改后才符合你的要求

示例:
  # feedback_testing.md
  规则:集成测试必须连真实数据库,不要 Mock
  原因:上次 Mock 的测试全过了但生产数据迁移失败(2026-03-15)
  应用:写数据库相关测试时,用 Docker 启动临时 PostgreSQL 做测试库

类型四:Reference(引用记忆)

存什么:
  - 外部资源的位置(不是内容本身)
  - 相关文档的链接
  - 团队频道的引用

什么时候写:
  - AI 需要知道"去哪找"而不是"是什么"时
  - 链接了外部资源后

示例:
  # reference_monitoring.md
  Grafana Dashboard:grafana.internal/d/api-latency(API 延迟监控)
  Oncall Slack:#ops-alerts
  Jira 项目:CMS(Key: CMS-xxx)
  Postman Collection:https://postman.internal/workspace/cms

类型五:Decision(决策记忆)

存什么:
  - 为什么做了某个技术决策
  - 考虑过哪些替代方案
  - 当时的约束条件是什么

什么时候写:
  - 每次重要技术决策之后

示例:
  # decision_cache_strategy.md
  决策:用 Redis 做 API 响应缓存,TTL 5 分钟
  考虑过的方案:
    - 内存缓存 → 放弃,多实例不同步
    - CDN 缓存 → 放弃,API 响应多变不适合
    - Redis → 选中,团队已有 Redis 运维经验
  约束:当时的架构还没上消息队列,所以没做主动失效
  日期:2026-05-20

MEMORY.md 索引文件

AI 启动时不会读所有 Memory 文件——那样 Token 开销太大。它只读 MEMORY.md 索引:

# MEMORY.md

- [用户角色与偏好](user_role.md) — 后端工程师,Python/Go,简洁风格
- [项目 CMS 重构背景](project_context.md) — Django→FastAPI,7 月 MVP
- [测试策略要求](feedback_testing.md) — 集成测试用真实 DB,不 Mock
- [监控相关引用](reference_monitoring.md) — Grafana 面板、Oncall 频道
- [Redis 缓存决策](decision_cache_strategy.md) — 为什么选 Redis,TTL 5 分钟

每行一个链接 + 一句话描述。AI 读到这个索引,就能判断需要打开哪个 Memory 文件。

关键约束:MEMORY.md 的前 200 行会被加载。超出部分可能被截断。所以要精简——只保留最活跃的 Memory,不常用的归档。


上下文污染:AI 变笨的三大元凶

场景一:累积太多无关信息

你的会话进行了 2 小时:
  ├── 开头讨论了数据库选型(8000 Token)
  ├── 中间修了一个 CSS 样式 bug(3000 Token)
  ├── 然后讨论 API 设计(5000 Token)
  ├── 现在在处理用户认证逻辑(已经消耗 120K Token)
  └── 上下文里还留着前面三个话题的全部内容

结果:
  AI 在写认证代码时,脑子里还装着 CSS 样式和数据库选型的讨论。
  → 它的注意力被分散了
  → 认证代码里出现数据库相关的错误假设
  → 你感觉 AI "变笨了"

解决方案:一个会话只做一件事。做完了就 /clear 开始新会话。

❌ 一个长会话做完所有事
✅ 数据库选型 → /clear → CSS 修 bug → /clear → API 设计 → /clear → 认证逻辑

场景二:错误信息被反复引用

第 1 轮:AI 生成了一段有 bug 的代码
第 2 轮:你指出 bug,AI 修复了
第 3 轮:AI 在另一个函数里又写了类似的代码
第 4 轮:你发现这和第 1 轮的 bug 是同一类问题

原因:
  AI 在第 3 轮写代码时,上下文里既有第 1 轮的"错误版本",
  也有第 2 轮的"修复版本"。它不确定哪个是最终模式。

解决方案:修复 bug 后,明确告诉 AI 这是"新模式":

你: "这个修复是最终版本。后续所有类似代码都按这个模式写。"
    → AI 把这个结论记入 Memory
    → 后续写代码时优先参考这个"已确认的模式"

场景三:上下文接近容量极限

Token 用量诊断:
  /status
  → Context: 185K / 200K (92%)

  此时 AI 的行为会变得异常:
  - 读文件时只能读片段,可能漏掉关键上下文
  - 生成代码时容易做出不连贯的假设
  - 处理复杂逻辑时容易出错
  - 但它不会主动告诉你"上下文满了"

解决方案

# 如果上下文 > 80%,立即执行:
/compact    # 压缩上下文——去掉已完成的讨论,保留关键决策
# 或
/clear      # 清空重来——新会话 + 重新描述当前要做什么

习惯:每次做重要决策前,先 /status 看一眼上下文用量。


PreCompaction Hook:自动归档

配合第 12-13 篇的 Hook 知识,可以配置 PreCompaction Hook 在上下文压缩前自动保存关键信息:

#!/bin/bash
# hooks/pre-compaction.sh
# 在 AI 即将"失忆"之前,把关键信息写入 Memory

SESSION_ID="$1"
CONTEXT_SIZE="$2"
PROJECT_DIR="$3"

MEMORY_DIR="$PROJECT_DIR/.claude/memory"
mkdir -p "$MEMORY_DIR"

# 保存当前任务进度
echo "## 会话 $SESSION_ID 压缩记录" >> "$MEMORY_DIR/session_archive.md"
echo "- 压缩时间: $(date)" >> "$MEMORY_DIR/session_archive.md"
echo "- 压缩前上下文: $CONTEXT_SIZE Token" >> "$MEMORY_DIR/session_archive.md"

# 引导 AI 在压缩前输出关键决策摘要
echo ""
echo "📦 上下文即将压缩(当前 ${CONTEXT_SIZE} Token)"
echo "   请在压缩前确认以下内容已保存到 Memory:"
echo "   - 本次会话做的重要决策"
echo "   - 待继续的未完成任务"
echo "   - 新发现的已知问题"
echo ""

exit 0

跨会话知识持久化实践

策略一:每次会话结束时做"脑转储"

会话结束前的 2 分钟,问 AI:

"在结束前,列出这次会话的 5 个关键产出:
 1. 做了什么(1-2 句话)
 2. 做了什么决策,为什么
 3. 有什么没做完的事
 4. 有什么新发现的坑
 5. 下次会话第一件要做什么"

AI 的输出直接写入 Memory 或会话笔记。
下次启动时 AI 读到这些,就像"从未断过"。

策略二:决策即记录

不是"工作了 3 小时然后总结",而是每做一个决策就立即记录:

👤 "这个 API 用 POST 还是 PUT?"
🤖 "用 PUT,因为它是幂等的更新操作。"
👤 "好,记住这个决策:用户信息更新用 PUT /users/:id,
    理由是幂等性。因为前端可能会重试请求。"

→ AI 写入 decision_api_methods.md
→ 下次讨论 API 设计时,AI 自动引用这个决策

策略三:Memory 的定期清理

每月花 5 分钟清理 Memory:

□ 过期的决策(技术栈换了、截止日期过了)
□ 已解决的已知问题
□ 不再活跃的外部引用
□ 重复的记录(不同文件里记录了同一件事)

清理的好处:
  - MEMORY.md 索引更短,AI 加载更快
  - 不会出现过期的信息误导 AI
  - 留下的都是真正有用的上下文

上下文工程的原则总结

1. 分层管理
   → 项目级的放 CLAUDE.md(全团队共享)
   → 跨会话的放 Memory(AI 自动读取)
   → 当前任务的放即时上下文(会话结束就释放)

2. 精炼优先
   → Memory 索引不超过 200 行
   → 每个 Memory 文件不超过 500 字
   → 一句话能说清的决策不要写三段

3. 及时清理
   → 上下文 > 80% 就 /compact 或 /clear
   → 会话结束后 2 分钟"脑转储"
   → 每月清理过期 Memory

4. 决策即记录
   → 不是"做完总结",而是"做了就记"
   → 记录决策的理由,不只是结论
   → 后续的 AI 才能理解"为什么"而不只是"是什么"

延伸阅读

更多推荐