SOTA Sync
全部文章
记忆与上下文2026-04-01

Claude Code 的七层记忆架构

Claude Code 源码反向工程完整披露:7层记忆系统如何协同,从毫秒级 token 裁剪到睡后后台的梦境整合,逐层防止成本逐级上升。

Claude Code 源码被公开后,有人对它做了完整的反向工程。它的记忆和上下文管理系统不是一个模块,是七层,每一层都比上一层更贵但更强,系统设计的基本逻辑是:让便宜的层拦截贵的层

#基础:Token 计数与上下文窗口

Claude Code 标准上下文窗口是 200K token(加 [1m] 后缀可扩展到 1M)。一次编码会话轻松超出这个限制——几次文件读取、grep 结果、几个编辑周期,就没了。

Token 计数的标准函数是 tokenCountWithEstimation():以上一次 API 响应的 input_tokens 为基数,加上后续消息的粗估。粗估规则:普通文本每 token 4 字节,JSON 每 token 2 字节(JSON tokenize 密度更高),图片和文档一律固定 2000 token。

有效上下文窗口 = 标称窗口 - 20K(预留 compaction 输出的空间)——你不能用满整个窗口,因为需要留空间生成把你救回来的摘要。

#七层记忆架构

#第一层:工具结果存储(Tool Result Storage)

文件:src/utils/toolResultStorage.ts|成本:仅磁盘 I/O,无 API 调用|触发:每个工具结果实时

问题是:一次 grep 可能返回 100KB+ 文本,一次 cat 大文件可能 50KB。这些结果占据大量上下文,且在几分钟后就会过时。

解法:超过阈值的工具结果,完整内容写入磁盘(tool-results/<sessionId>/<toolUseId>.txt),上下文里只保留约 2KB 预览,用 <persisted-output> 标签包裹。模型需要时可用 Read 工具访问完整结果。

关键细节:ContentReplacementState 会冻结每次替换决策——同一结果在后续所有 API 调用中都获得相同预览,保证 prompt cache 命中。状态甚至通过 transcript 持久化,支持 session resume。

#第二层:Microcompaction(微压缩)

文件:src/services/compact/microCompact.ts|成本:零到极低 API 成本|触发:每轮对话,API 调用前

Microcompaction 不做摘要,只是清除不太可能再被用到的旧工具结果。三种机制:

时间触发的微压缩 :空闲超过 60 分钟后(Anthropic 服务端 prompt cache 约 1 小时 TTL 过期),清除旧工具结果,保留最近 N 条。

缓存微压缩 (最有技术含量的机制):不修改本地消息(会破坏 prompt cache),而是用 API 的 cache_edits 机制从服务端 cache 删除指定工具结果,本地消息不变。API 层操作,不影响 cache 前缀。

API 层上下文管理apiMicrocompact.ts):用 context_management API 参数直接告诉服务端处理,客户端不需要跟踪。

可被清除的工具:FileRead、Bash/Shell、Grep、Glob、WebSearch、WebFetch、FileEdit、FileWrite。不包括:thinking blocks、assistant 文本、用户消息、MCP 工具结果。

#第三层:Session Memory(会话记忆)

文件:src/services/SessionMemory/|成本:每次提取一次 fork agent API 调用|触发:对话中周期性(采样后钩子)

核心思想:不要等到上下文满了才手忙脚乱地总结一切,而是持续维护会话笔记 。等到 compaction 真正需要时,摘要已经在那儿了,不需要昂贵的 summarizer API 调用。

Session memory 文件在 ~/.claude/projects/<slug>/.claude/session-memory/<sessionId>.md,有结构化模板:

# Session Title
# Current State
# Task specification
# Files and Functions
# Workflow
# Errors & Corrections
# Codebase and System Documentation
# Learnings
# Key results
# Worklog

触发条件:自上次提取以来 token 增量 ≥ 最小阈值 (工具调用数 ≥ 阈值 或 上一轮没有工具调用)。Token 阈值是必选项,"上一轮无工具调用"捕捉自然对话中断点。

提取作为 fork subagent 运行,只允许对记忆文件使用 FileEdit,其他工具全部拒绝,共享父 prompt cache 以节省成本。

#第四层:Session Memory Compaction(会话记忆压缩)

成本:无需 API 调用(使用已有的 session memory 文件)|触发:autocompact 时,session memory 有实际内容

这是整个系统的关键回报:当 autocompact 触发时,系统先尝试 trySessionMemoryCompaction()——用已有的 session memory markdown 作为压缩摘要,不需要 API 调用,直接注入上下文。系统只需要决定保留哪些最近的对话消息。

相比完整压缩,这不需要 summarizer API 调用,不需要构建摘要 prompt,不消耗输出 token。Session memory 文件本身就是摘要。

#第五层:Full Autocompact(完整自动压缩)

文件:src/services/compact/compact.ts|成本:一次全量 API 调用(输入 = 整段对话,输出 = 摘要)|触发:上下文超过 autocompact 阈值且 session memory compaction 不可用

触发条件:tokenCountWithEstimation(messages) > effective window - 13K

熔断机制 :连续失败 3 次后,autocompact 在本次会话剩余时间停止。加入这个机制是因为发现 1279 个会话各有 50+ 次连续失败(个别高达 3272 次),每天全球浪费约 25 万次 API 调用。

压缩算法四步:

  1. 预处理:执行用户配置的 PreCompact 钩子,剥离图片和技能发现附件
  2. 生成摘要:fork summarizer agent,请求 9 段结构化摘要(分析块 + 摘要块,分析块最终被剥离,不消耗压缩后的 token)
  3. 压缩后恢复:重新注入最近读取的 5 个文件(每个 5K token)、调用的技能内容(每个 5K)、Plan 附件、延迟工具 schema 等
  4. 写入边界消息 SystemCompactBoundaryMessage 标记压缩点

#第六层:Auto Memory Extraction(自动记忆提取)

文件:src/services/extractMemories/extractMemories.ts|成本:一次 fork agent API 调用|触发:每个完整查询循环结束时(模型产出最终响应且无工具调用)

功能是将对话中有价值的知识提炼为持久化记忆,存入 ~/.claude/projects/<path>/memory/

四种记忆类型及保存标准:User(你是谁)、Feedback(你给过的指导)、Project(代码库里发生的事)、Reference(外部系统指针)。提取 prompt 明确排除了:代码模式/规范/架构(可从代码推导)、Git 历史、调试解决方案(修复已在代码里)、CLAUDE.md 内容、临时任务细节。

如果主 agent 本轮已经写了记忆文件,后台提取 agent 跳过——避免重复劳动。

#第七层:Dreaming(梦境整合)

文件:src/services/autoDream/autoDream.ts|成本:一次 fork agent API 调用(可能多轮)|触发:后台运行,积累足够时间和会话后

概念是跨会话记忆整合——后台进程回顾过去的会话记录,将记忆组织进长期存储。类似于生物记忆在睡眠期间的整合过程:回顾一天的经历,组织并整合进长期记忆。

四级递进门控 (每级比下一级便宜,大多数检查提前退出):

  • Phase 1 Orient:读取记忆目录,理解当前索引
  • Phase 2 Gather Recent Signal:回顾每日日志,检查是否有与代码库矛盾的 drift 记忆,窄范围 grep session transcripts("不要穷尽式读 transcript,只看你已怀疑重要的事物")
  • Phase 3 Consolidate:写或更新记忆文件,合并新信号到已有主题而非创建近似重复,将相对日期转换为绝对日期
  • Phase 4 Prune and Index:更新 MEMORY.md 保持在 200 行 / 25KB 以内,删除过时/错误/被取代的记忆指针

梦境 agent 工具有严格限制:Bash 仅读命令,Edit/Write 仅限记忆目录,无 MCP 工具,无 Agent 工具,无破坏性操作。

#Forked Agent 模式

Claude Code 几乎所有后台操作(session memory、自动记忆、梦境整合、压缩、agent summaries)都使用 fork agent 模式。核心设计:

缓存安全参数 (CacheSafeParams):fork 的系统 prompt、工具、消息前缀必须与父 agent 字节完全一致,所以 API 能 cache 命中。

Fork 创建隔离上下文(克隆的 LRU cache、独立的 abortController、独立的 denialTracking),但共享 prompt cache(保持相同的 cache 关键参数)。

所有 fork child 产生字节级相同的 API 请求前缀,只有最后一个指令文本块因 child 而异——实现跨并发 fork 的最大 prompt cache 共享。

#核心工程洞察

几乎每个设计决策都考虑 prompt cache 影响。 Anthropic 的 API 服务端 prompt cache 约 1 小时 TTL。Cache 命中意味着你只需为新 token 付费;Cache 未命中意味着要从头 tokenize 整个 prompt。在 200K token 规模上,这是每次请求 ~0.003和 0.003 和 ~0.60 的差别。

七层系统的设计原则是让更便宜的层拦截更贵的层

  • 工具结果存储 → 防止 microcompact 需要清除太多
  • Microcompaction → 防止 session memory compaction
  • Session memory compaction → 防止完整压缩
  • 完整压缩 → 防止 context overflow 错误

每个系统都设有 GrowthBook feature flag 支持快速回滚。梦境扫描有 10 分钟节流阀。梦境锁是 PID-based mutex 加 60 分钟过期检测。完整压缩有 3 次熔断机制。每个系统静默失败,交给下一层接住。