Skip to content

深度解析 Claude Code 的 Memory 策略与演进路径

本文从上下文工程(Context Engineering)视角,系统拆解 Anthropic Claude Code 的 Memory 体系,并以"问题—方案—取舍—遗留"四要素叙事,回顾它从单文件 prompt 注入演进到分层 + 按需加载 + 压缩续接的完整路径。文中凡涉及未公开实现细节,均以 [推测] / [未公开] 显式标注。


1. 概览:什么是 Claude Code 的 Memory

一句话定义

Claude Code 的 Memory,是一套以用户可读 Markdown 文件为载体、按"作用域 + 触发时机"分层注入到模型上下文窗口的持久化指令与事实集合——它既不是模型权重的一部分,也不是临时对话历史,而是介于两者之间的"工程化长期上下文层"。

与相关概念的边界

概念是否持久化是否进入每轮 prompt主要载体与 Memory 的关系
Context Window模型一次推理的 token 缓冲Memory 是其中"被显式预算的一段"
Session State部分(会话内)对话历史、TodoWrite、临时变量Memory 是 Session State 的"跨会话超集"
RAG否(按 query 检索)否(按需召回)向量库、外部检索器Memory 是"无需检索、默认在场"的高优先级前置上下文
Persistent Memory(如 ChatGPT Memory)平台后端结构化存储Claude Code 走"文件 + Git 友好"路线,而非"黑盒后端"

一句话区别:RAG 是"被检索的知识",Session State 是"当前对话的记忆",Memory 是"始终在场的契约"。

架构总览(Mermaid)

核心设计哲学可以一句话概括:"持久化的一切都落到文件、运行时的一切都按预算拼装、不确定的一切都隔离到子上下文"


2. 当前 Memory 体系的完整拆解

下面按"作用 / 存储位置 / 生命周期 / 加载时机 / 写入方式 / 典型示例"六维度展开。

2.1 项目级记忆:CLAUDE.md / AGENTS.md

维度描述
作用承载项目特定的"协作契约":技术栈、目录约定、跑测试的命令、禁止事项、领域术语
存储位置项目根目录 ./CLAUDE.md;新约定下也读 ./AGENTS.md(与 Cursor、Codex CLI 共享)
生命周期与代码仓库同寿,随 Git 版本化
加载时机CLI 启动时读入;/memory 编辑后会重新加载 [推测]
写入方式直接编辑文件;# 开头的 prompt 自动追加;/memory 命令打开编辑器
典型示例"本项目用 pnpm 而非 npm"、"提交前必须跑 make lint"、"不要修改 generated/ 目录"

Why(为什么是 Markdown 文件而不是 JSON / YAML):Markdown 既被人读、又被模型读,且天然支持代码块、列表、链接,避免了"配置即代码即文档"三态分裂。Git diff 友好是关键的工程权衡。

Trade-off:纯文本无 schema → 容易写得啰嗦;不同团队的写法风格差异极大;模型对长 CLAUDE.md 有"前置预算挤占后续推理"的代价。

2.2 用户级记忆:~/.claude/CLAUDE.md

维度描述
作用跨项目的个人偏好:语言("始终用中文回答")、口吻、提交规范、常用工具偏好
存储位置~/.claude/ 用户目录下的全局 Memory 文件
生命周期与用户账户同寿
加载时机任何项目启动 Claude Code 时都会加载,优先级低于项目级 [推测:当冲突时项目级覆盖]
写入方式手动编辑;# 写入时会被 Claude 询问"写到项目级还是用户级"
典型示例"回答用中文"、"不要使用 emoji"、"喜欢函数式风格"

Why(为什么要分用户级 / 项目级):避免把"我的口味"污染到团队仓库;同时把"团队规范"和"个人偏好"做出明确的归属边界。

2.3 子目录 / 模块级 Memory(嵌套合并)

维度描述
作用大型 monorepo 中,让"前端 / 后端 / infra"各自维护局部规范
存储位置任意子目录下的 CLAUDE.md
加载时机当 Claude Code 在该子目录进行操作(读 / 写文件)时,按"由根向下"的顺序合并 [推测:实际可能是基于当前 cwd 或被操作文件路径触发的"按需上探 + 按需下探"]
合并规则后加载(更深层)的 Memory 追加到上层之后,遇到冲突时由模型自行根据"局部优先"语义裁决 [推测]
典型示例frontend/CLAUDE.md:用 React + TypeScript;backend/CLAUDE.md:用 Go,禁止引入 ORM

Trade-off:嵌套带来"加载顺序"和"覆盖语义"的复杂度。Anthropic 选择不引入显式 override 关键字,而是让模型自然处理冲突——这是典型的"用模型能力换工程复杂度"的取舍。

2.4 会话级记忆:对话历史、TodoWrite、临时上下文

维度描述
作用保留当前会话上下文:用户消息、模型回复、工具调用结果、TodoWrite 列表
存储位置进程内(CLI)或服务端会话存储(Cloud Agent)
生命周期单次会话;CLI 退出即销毁(除非通过 --resume/会话恢复机制 [推测有此能力] 重连)
加载时机每轮推理整体前置
写入方式对话过程自动累加;TodoWrite 工具显式管理任务列表
典型示例用户上一条说"先重构再加测试",模型记住后续 5 轮内自动遵守

TodoWrite 的特殊地位:它是 Anthropic 把"任务规划"从"对话散文"中提取出来的结构化层,效果类似于"模型自己给自己写的、不会被压缩掉的便签"。在长任务中显著缓解了"模型走着走着忘了原始目标"的问题。

2.5 工具级 Memory:MCP / Skills / Hooks 协同

这一层是 Claude Code 近年最大的演进,把"记忆"从"被动文档"升级为"可执行能力 + 触发式上下文"

Skills(SKILL.md)

  • 本质:磁盘上的 SKILL.md 文件,包含"何时使用 + 详细操作指南"两段。
  • 加载策略默认只把所有 Skill 的"何时使用"摘要注入 prompt,模型判断需要时再用 Read 工具读取完整 SKILL.md。这是典型的两阶段加载
  • Why:避免上百个 SKILL 全文塞进 context 浪费 token;同时保留"模型自主决策"的弹性。
  • Trade-off:模型必须能正确识别触发条件——这对 SKILL 的 description 写作质量提出了很高要求。

MCP(Model Context Protocol)

  • 本质:标准化的"外部工具/资源"对接协议。Memory 维度上,MCP 服务器可以暴露 resources,被模型按 URI 拉取。
  • 与 Memory 的关系:MCP 资源是**"按需的、外部托管的 Memory"**,与 CLAUDE.md 的"始终在场的本地 Memory"形成互补。

Hooks

  • 本质:事件驱动脚本(如 PreToolUsePostToolUseUserPromptSubmit),可往上下文里注入文本阻断操作
  • 与 Memory 的关系:Hooks 提供"动态、上下文敏感"的记忆——例如 UserPromptSubmit 时自动注入当前 git 分支和 PR 状态。它是**"运行时计算出来的 Memory"**,弥补了静态文件的不足。

2.6 长期记忆与外部知识:/memory# 快捷写入

入口行为设计意图
/memory打开 $EDITOR,让用户直接修改 CLAUDE.md(询问层级)高频维护时的低摩擦入口
# 前缀用户输入 # 以后所有 SQL 都用 snake_case,Claude 询问写入哪个 Memory,确认后追加"对话即配置",把零散偏好沉淀到文件

Why(为什么要有两种入口)/memory 适合"系统化整理",# 适合"边聊边沉淀"。两者覆盖了不同的心流场景——这是从纯 IDE 配置工具向"会话式 IDE"演进的关键产品决策。

未在 Memory 内但相关:Claude Code 不内置向量化的长期记忆 [截至公开信息],跨会话事实主要靠 Markdown 文件 + Git;如果需要"语义化召回",要走 MCP 接外部向量库。


3. 演进时间线(核心章节)

下面以"问题—方案—取舍—遗留"四要素叙事,复盘 Claude Code Memory 体系的迭代路径。部分阶段的时间顺序是基于公开信息的逻辑重建,并非严格的版本号时间线 [推测]

【阶段 1】纯 Prompt 注入:无持久化记忆

  • 痛点:早期 Claude API 用法只能在每次请求里手写 system prompt;用户每开一个新会话都要"重新教 Claude"项目背景,认知负担大、复用差。
  • 方案:CLI 提供命令行参数 / 环境变量,把若干"通用指令"塞到 system prompt。本质是**"无 Memory"**——一切都依赖会话内对话或调用方手写。
  • 取舍:实现极简、可控性最强;但完全没有跨会话传承,团队协作时每个人都要"私藏一份 prompt"。
  • 遗留问题:用户开始把 prompt 存为文件、互相复制;事实上的"野生 CLAUDE.md"在社区里出现,倒逼官方收口。

【阶段 2】单文件 CLAUDE.md:项目记忆诞生

  • 痛点:野生 prompt 文件命名混乱、加载方式各异、无法被官方 CLI 自动识别。
  • 方案:约定俗成 CLAUDE.md 作为项目根的官方 Memory 文件,CLI 启动时自动加载到 system prompt 之后。用文件名约定代替配置项——零配置、Git 友好、对人和模型双重可读。
  • 取舍:优雅但作用域只有一层——大型 monorepo 中根目录的 CLAUDE.md 会变成"什么都往里塞"的垃圾桶;不同模块的规范打架。
  • 遗留问题:需要分层;同时"是否应该把个人偏好也写进项目 CLAUDE.md"成为新的争议。

【阶段 3】分层记忆:用户级 + 项目级 + 子目录级

  • 痛点:阶段 2 的单层文件无法区分"团队约定"和"个人口味";monorepo 子模块差异无处安放。
  • 方案:引入三层 Memory:
    1. ~/.claude/CLAUDE.md(用户级,跨项目)
    2. ./CLAUDE.md(项目级,进入仓库)
    3. 子目录 CLAUDE.md(模块级,按 cwd / 操作路径动态加载)
  • 关键设计决策不引入显式优先级关键字,让"路径越深 = 越具体 = 隐式优先"作为约定,把冲突解决交给模型。
  • 取舍:心智模型清晰、扩展性强;代价是调试困难——当出现"模型为什么不按我说的做"时,用户可能要排查多层文件;同时Token 占用变大,长 monorepo 下三层叠加可能吃掉数千 token。
  • 遗留问题:用户编辑 Memory 的摩擦依然高(要主动 vim),且没有"边对话边沉淀"的入口

【阶段 4】快捷写入与 /memory 命令:把"沉淀"变成对话动作

  • 痛点:阶段 3 的 Memory 文件需要用户主动跳出对话去维护,违反心流。许多临时偏好("以后用 pytest 而不是 unittest")说完即忘。
  • 方案
    • # 前缀:用户在对话中以 # ... 开头输入,Claude 识别为"沉淀指令",追问"写到项目级还是用户级",确认后追加。
    • /memory:斜杠命令直接打开编辑器,结构化整理。
  • 关键设计决策写入需要二次确认——避免模型误把普通对话当成 Memory 写入,保证"用户始终是 Memory 的最终所有人"。
  • 取舍:交互摩擦显著降低;但 # 触发依赖用户记住语法,新用户发现成本高;且模型解读"是否该追问"本身有错误率。
  • 遗留问题:Memory 越积越多 → 上下文预算紧张;且不同用户的 Memory 写作质量参差,模型表现不稳定。

【阶段 5】Skills / Subagents / Hooks 协同:从"被动文档"到"按需能力"

  • 痛点:阶段 4 的 Memory 都是"全量前置注入"——一段写给"做 React 时怎么办"的指令,在"写 SQL"时也白白占用 token;同时复杂任务(如 PR 审查)希望走"独立子流程",不污染主上下文。
  • 方案
    • SkillsSKILL.md 文件 + 两阶段加载:默认只注入 description,模型自主决定是否 Read 完整内容。把 Memory 从"始终在场"升级为"按需召回"。
    • Subagents:派生独立子上下文执行子任务,结果以摘要形式回传父上下文。子上下文不继承父级的对话历史——这是用"上下文隔离"换取"长任务下的认知聚焦"。
    • Hooks:事件驱动注入(如 UserPromptSubmit 钩子可以注入当前 git 状态、CI 失败信息)——这是**"运行时计算的 Memory"**。
  • 关键设计决策Memory 的语义从"文档"扩展到"可执行 + 可触发"。CLAUDE.md 仍然存在,但只承担"高频、跨任务、无法计算"的契约层,其余下放给 Skills/Hooks。
  • 取舍:架构复杂度陡增(用户要理解四种机制:CLAUDE.md / Skill / Subagent / Hook 各自的边界);description 写作质量直接决定 Skill 是否被正确触发。
  • 遗留问题:长会话下,即便每段 Memory 都很精简,对话历史本身也会增长到接近上下文上限,必须解决"会话续接"问题。

【阶段 6】上下文压缩(Auto-Compact)与会话续接

  • 痛点:长任务(数小时连续对话、数十次工具调用)下,对话历史本身变成最大的 token 消耗者;接近上下文上限时模型会"忘头"。
  • 方案Auto-Compact——当 token 预算接近阈值时,CLI 自动用模型对早期历史做摘要,把摘要替换原文。Memory(CLAUDE.md 等持久层)不参与压缩,始终原样保留——这是关键的优先级设计。
  • 关键设计决策
    1. 持久化 Memory 优先级最高:宁可压缩对话,也不动 CLAUDE.md。
    2. TodoWrite 内容受保护 [推测]:任务规划结构化数据要避免被摘要稀释。
    3. 压缩对用户可见:UI 提示"已压缩",避免模型行为变化让用户困惑。
  • 取舍:会话寿命大幅延长;但摘要必然丢失细节,**长会话末期模型对早期细节的"模糊化"**是无法消除的副作用。
  • 遗留问题:单机会话仍然受"进程生命周期"限制;CI / 远程协作场景需要会话能跨设备续接。

【阶段 7】跨会话 / 跨设备:Cloud Agent 与会话恢复

  • 痛点:CLI 退出 = 会话消失;想从笔记本切换到云端继续任务很难。
  • 方案:Anthropic 推出 Cloud Agent / 会话恢复能力 [部分公开],把会话 State 持久化到服务端,可以跨设备恢复。
  • 与本地 Memory 的关系:Cloud Agent 启动时仍然读取项目仓库内的 CLAUDE.md / AGENTS.md,Memory 文件依然是真理之源——云端只补齐"会话历史 + TodoWrite + 工具调用结果"。
  • 取舍:协作 / 移动场景大幅改善;带来隐私和数据所有权的新问题(哪些上下文被持久化到云端?)。
  • 遗留问题:Memory 仍然是"文本 + 文件",缺乏语义化召回结构化关系,对超大型仓库(百万行代码)的"长期事实积累"还是手工活。

【阶段 8 · 推测】未来方向:向量化 / 结构化记忆图谱 / 多 Agent 共享

  • 可能演进路径
    1. 本地向量化 Memory:把历史会话、提交记录索引化,按 query 动态召回相关片段,缓解"CLAUDE.md 越写越长"的问题。
    2. 结构化记忆图谱:把"约定 / 决策 / 实体"抽成节点—关系(类似 ADR + 知识图谱),让模型不仅"读到",还能"推理"。
    3. 多 Agent 共享 Memory:当 CLAUDE.md 被多个 Agent(Claude Code / Cursor / Codex)共同读取(即 AGENTS.md 趋势),是否会出现"agent-neutral memory schema"标准。
    4. Memory 可观测性:让用户能看到"模型这一轮用了哪些 Memory 段、在做决策时引用了哪条规则",把"黑盒上下文"变成"白盒审计"。
  • 上述均为 [推测],作为产品和研究的开放方向。

4. 关键设计原则提炼

从七个阶段的演进中,我归纳出五条可复用的设计原则

  1. "持久化的一切都落到文件,运行时的一切都按预算拼装"

    • Memory 不走云端黑盒,走 Markdown + Git;这保证了可审计、可版本化、可团队协作
    • 运行时再按"作用域 + 触发条件"动态拼装,避免一次性塞爆 context。
  2. "显式优于隐式,但默认要够智能"

    • # 前缀写入要追问"哪一层",强制用户做出归属选择 → 显式。
    • 但子目录 Memory 的合并不需要写 extends:override: → 隐式约定,靠路径深度作为优先级 → 默认够用。
    • 反例(错误的设计):要求用户写 YAML 配置 + 优先级数字。
  3. "Memory 优先级永远高于对话历史"

    • Auto-Compact 砍对话不砍 CLAUDE.md。
    • 这是一种**"契约 > 临时叙述"**的价值排序,避免长会话漂移。
  4. "用上下文隔离换长任务的认知聚焦"

    • Subagent / Skill 两阶段加载 / Hooks 都是同一思想:不要让 Agent 一次性记住所有事情
    • 这与人类认知一致:复杂任务要分模块、分会话、分笔记。
  5. "Memory 的载体必须人和模型双重可读"

    • Markdown 既是配置又是文档;写 Memory = 写团队规范 = 提交可 review。
    • 反例:JSON / 二进制格式 / 平台后端的"用户记忆"——人无法 review,模型也无法直接编辑。

5. 与同类产品的横向对比

维度Claude CodeCursorCodex CLICline
项目记忆载体CLAUDE.md(也读 AGENTS.md.cursor/rules/*.mdc + AGENTS.md(多文件 + frontmatter 控制 globs/alwaysApply)AGENTS.md(与 Claude / Cursor 共享约定).clinerules/(多文件,类似 Cursor)
全局记忆~/.claude/CLAUDE.md用户级 Rules(IDE 设置)~/.codex/AGENTS.md 等 [推测路径,以官方为准]用户级 rules 目录
写入触发方式# 前缀 + /memory 命令手动编辑 .mdc,或在对话中让 Cursor 帮忙生成 rule手动编辑 AGENTS.md手动编辑 .clinerules
作用域控制文件路径深度(隐式)frontmatter 显式 globs / alwaysApply / agentRequested路径约定 [推测]frontmatter / 路径约定
上下文压缩Auto-Compact(自动摘要早期历史)自动摘要 + 用户可见的 Pin/Unpin(细节因版本而异)类似自动压缩(细节 [未公开])自动摘要
跨会话续接CLI 会话恢复 + Cloud AgentIDE 会话内置(IDE 进程内)CLI session [推测有]IDE 会话
按需能力机制Skills(SKILL.md,两阶段加载)Custom Modes / @-mentions / Rules 的 description 字段[未公开等价物]Custom Instructions / MCP
多 Agent 协作Subagents(独立 context)Background Agents、Bugbot[未公开]单 Agent 为主

核心差异点解读

  • Cursor 走的是"显式 schema 化 rule"路线(frontmatter + 多文件),适合工程化深度配置;
  • Claude Code 走的是"约定 + 文件名 + 模型自主裁决"路线,更轻量、更容易上手;
  • 三家都在收敛到 AGENTS.md 的事实标准,意味着未来 Memory 文件可能跨 Agent 复用。

6. 落地启示:从 Claude Code 中可借鉴的 5 条工程实践

如果你要为自己的 Coding Agent 设计 Memory 系统,下面是可以直接抄作业的 5 条:

启示 1:用文件名约定 + Markdown 作为 Memory 载体

  • 推荐文件名:直接复用 AGENTS.md 这一新兴标准(Claude / Cursor / Codex 都识别),同时兼容自己专属的 <YOURAGENT>.md
  • 加载顺序(强烈建议):
    1. ~/.<youragent>/AGENTS.md(用户级,先加载,优先级最低)
    2. 项目根 ./AGENTS.md(覆盖用户级冲突项)
    3. 当前操作路径上溯到根的所有 AGENTS.md由浅到深依次追加(深的在后,模型天然倾向于"最近上下文")
  • 冲突解决:不引入 override 关键字,让模型按"路径越深越具体"的常识裁决。

启示 2:把 Memory 写入做成"对话动作",但需要二次确认

  • 复刻 # 前缀语义:用户说 # 以后用 ruff 而不是 flake8,Agent 识别后追问"写入用户级还是项目级 Memory?",确认后追加到对应文件。
  • 关键约束永不未经用户确认就修改 Memory 文件——Memory 必须是"用户授权"的契约,不是模型偷偷记下的事实。

启示 3:Memory 在压缩时享有最高优先级

  • 实现 Auto-Compact 时,按以下优先级排队:
    System Prompt > 持久化 Memory > 当前 TodoWrite > 最近 N 轮对话 > 早期对话(可摘要)
  • 当 token 接近上限时,只摘要最早期的对话,永远保持 Memory 段原样。

启示 4:把"按需能力"和"前置 Memory"分开存放

  • 借鉴 Skills 的两阶段加载:
    1. AGENTS.md 只放"始终在场的契约"(短、稳定、跨任务)。
    2. 任务相关的详细 SOP 放在 skills/<name>/SKILL.md默认只注入 description,模型按需 Read。
  • 这能把 Memory 段控制在 1-2K token 内,避免"上下文越用越胖"。

启示 5:复杂任务派生 Subagent,结果以摘要回传

  • 长任务(如代码审查、批量重构)派生独立子上下文,只把任务描述 + 必要文件路径传入,不继承父级对话历史
  • 子任务完成后,强制要求"输出一段结构化摘要",由父 Agent 决定是否进一步处理。
  • 这是用架构隔离而非"prompt 提醒"来对抗长任务的认知漂移,效果更稳定。

7. 参考资料

注:以下链接为公开信息入口,建议读者按当前版本以官方文档为准;社区文章用于补充推测性内容,标注 [社区]。

  • Anthropic 官方文档:Claude Code 主页与 Memory / Settings 章节(docs.anthropic.com 下 Claude Code 部分)
  • Anthropic 官方博客:关于 Skills、Subagents、Cloud Agents 的发布说明
  • Claude Code CHANGELOG(GitHub anthropics/claude-code 仓库的 releases / CHANGELOG)
  • AGENTS.md 公开提案(agents.md 站点 / 各大 Agent 厂商的兼容声明)
  • Model Context Protocol 官方规范(modelcontextprotocol.io
  • [社区] 各类对 Claude Code 的逆向分析与实战总结(GitHub awesome-claude-code 类整理、个人博客)
  • 横向对比:Cursor 文档(Rules、Custom Modes、AGENTS.md 兼容说明)、Codex CLI README、Cline 文档

总结一句话:Claude Code 的 Memory 不是单一机制,而是**"持久层(文件) + 运行层(按需拼装) + 隔离层(Subagent)"三层结构逐步演进的结果。它的核心创新不在于发明了某个新概念,而在于坚持用最简单的工程原语(Markdown 文件、路径约定、二次确认)解决最复杂的上下文管理问题**,并把决策权稳稳地留在用户手中。这一思路,比任何具体的 API 都更值得借鉴。