找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4667

积分

0

好友

645

主题
发表于 5 天前 | 查看: 43| 回复: 0

Claude Code多层记忆架构示意图

对于开发者而言,大型语言模型 固定的上下文窗口一直是个令人头疼的限制。Claude Code 默认提供 200K token 的上下文窗口(通过 [1m] 后缀可扩展到 1M),但在实际的编码任务中——阅读几个大文件、全局搜索整个仓库、再进行几轮代码编辑——很容易就会超出这个限制。

Claude Code 的解决方案并非简单地扩大窗口,而是设计了一套精妙的 7层渐进式记忆管理系统。这套系统像人类大脑一样分层管理记忆,从毫秒级的轻量清理到“做梦”般的长期记忆巩固,层层递进,堪称当前智能体(Agent)设计的教科书级工程实践。技术细节的公开,也为广大开发者在 云栈社区 等平台提供了深入的讨论与学习素材。

核心基础:Token计数与窗口管理

一切记忆管理都基于精确的 Token 计数。底层函数 tokenCountWithEstimation() 会优先使用上次 API 调用返回的精确 input_tokens 值,然后对新增的消息内容进行粗略估算(普通文本约 4 bytes/token,JSON 更省,图片或文档固定为 2000 tokens)。系统还会预留约 20K tokens 作为输出缓冲区,绝不会将上下文窗口用满,以避免在需要压缩时连压缩指令本身都塞不进去的尴尬局面。

上下文窗口的解析优先级也有讲究:模型后缀 [1m] → 查询模型能力 → Beta Header → 环境变量 → 默认 200K。

7层记忆架构详解:从最经济到最强大

这套架构如同一座防御金字塔,层级越高能力越强,但成本也越高。设计的核心思想是 “预防为主”,尽可能使用成本低的层级来解决问题,防止触发更昂贵的高层操作。

ClaudeCode七层记忆架构总览图

第1层:工具结果存储 —— “日常清洁工”

单次 grep 可能返回超过 100KB 的文本,cat 一个大文件也可能达到 50KB。如果这些内容直接塞进上下文,不仅浪费 Token,而且很快就会过时。

Claude Code 的解决方案是:每个工具调用的结果在进入上下文前,都会经过一套预算系统的审核。当结果大小超过预设阈值时,系统会执行以下操作:

  • 完整的结果被写入磁盘(路径格式:tool-results/<sessionId>/<toolUseId>.txt)。
  • 上下文中只保留前 ~2KB 的预览文本,并用 <persisted-output> 标签包裹。
  • 模型在后续如果需要查看完整内容,可以使用 Read 工具来读取。

工具结果存储限制配置表

一个关键设计在于 “内容替换状态”:一旦系统决定用预览文本来替换某个完整结果,这个决定就会被“冻结”。后续所有的 API 调用都会使用相同的预览文本,确保 Prompt 前缀的字节完全一致,从而最大化服务器端 Prompt Cache 的命中率。这个状态甚至会被持久化到会话记录中,支持会话恢复(resume)。

同时,每个工具的阈值可以通过名为 tengu_satin_quoll 的功能标志进行远程调节,这使得 Anthropic 能够在无需部署新代码的情况下,灵活调整特定工具的持久化策略。

ContentReplacementState数据结构

第2层:微压缩 —— 每轮对话前的“日常保洁”

这是最轻量级的上下文清理机制,几乎不产生额外的 API 调用成本,在每轮 API 调用前都会执行。微压缩不会总结任何内容,它仅仅清除那些不太可能被再次用到的旧工具结果。

它包含三种不同的触发机制:
a) 基于时间
如果距离上一次助手消息回复已超过预设阈值(默认为 60 分钟),鉴于服务器端 Prompt Cache 的生存时间(TTL)大约也是 1 小时,缓存很可能已过期,此时可以安全地清理旧的工具结果,将其替换为 [Old tool result content cleared],但会保留最近 N 条结果。

配置示例如下(通过 GrowthBook 的 tengu_slate_heron 标志控制):

TimeBasedMCConfig = {
  enabled: false, // Master switch
  gapThresholdMinutes: 60, // Trigger after 1h idle
  keepRecent: 5 // Keep last 5 tool results
}

b) 缓存编辑式微压缩
这是技术层面最有趣的一种机制。它利用 cache_edits 功能在服务器端删除旧的工具结果,而本地保存的消息记录保持不变,从而避免破坏客户端本地的缓存前缀。所有工具结果都会被注册到一个全局的 CachedMCState 中,当超过阈值时,系统会选择最旧的结果进行删除。

关键点:此操作只应在主线程(用户交互线程)中运行。如果由分支出的子代理(如会话内存、代理摘要等)修改了全局状态,将会破坏主线程的缓存编辑,导致缓存失效。

c) API级上下文管理
这是一种较新的服务器端方法,通过 context_management API 参数,让 API 服务端直接处理一部分清理工作。

ContextEditStrategy配置示例

第3层:会话内存压缩 —— 最具前瞻性的一层

这一层的聪明之处在于 不等上下文满了再慌张总结,而是实时维护一份结构化的会话笔记

每个会话都会在本地生成一个标记文件,路径为:
~/.claude/projects/<slug>/.claude/session-memory/<sessionId>.md
文件遵循一个结构化的模板:

会话内存Markdown模板

触发条件是:Token 数量增长达到阈值,并且满足(工具调用次数达标 或 上一轮没有工具调用)。

当自动压缩被触发时,系统首先尝试 trySessionMemoryCompaction()

  1. 检查会话内存文件是否有实际内容(而非空模板)。
  2. 将会话内存文件的内容直接用作压缩摘要——无需调用 API
  3. 计算需要保留哪些最近的消息(通常从最后一个已总结的消息ID向后扩展,以满足最低保留要求)。
  4. 返回一个压缩结果,包含“会话内存摘要” + “保留的近期消息”。

SessionMemoryCompactConfig配置

当需要压缩时,直接注入这份现成的总结,实现零额外API调用,成本极低

第4层:全压缩 —— 上下文快满时的“紧急刹车”

tokenCountWithEstimation() 超过自动压缩阈值(有效窗口大小减去 13K),且会话内存不可用时,将触发此层。

全压缩的流程非常严谨:

  1. 预处理:执行用户的 PreCompact 钩子函数,移除图片、技能附件等非核心内容。
  2. 生成摘要:系统会 fork 出一个专门的摘要代理,并给出详细提示,要求生成一个包含 9个部分 的结构化摘要。代理会先撰写 <analysis> 草稿进行思考,再输出 <summary> 正文(草稿部分在最终返回时会被剥离,不占用上下文 Token)。

全压缩的9部分摘要结构

  1. 压缩后修复:将最近读取的文件内容、技能内容、计划附件等关键上下文重新注入压缩后的对话中。
  2. 插入标记:插入一条 SystemCompactBoundaryMessage 消息来标记压缩边界。

压缩元数据结构示例

系统还设计了只压缩部分消息的机制,以及当提示本身过长时的恢复机制(分组丢弃最旧的消息,最多重试3次)。

第5层:自动记忆提取 —— 构建跨会话的长期知识库

在每个任务(查询)结束时,系统会自动提取那些具有跨会话持久价值的知识,并将其存储到 ~/.claude/projects/.../memory/ 目录下。

记忆分为四种类型,每种都有特定的触发条件和格式:

四种记忆类型及其描述

记忆条目具体示例

所有提取的记忆会被汇总到一个 MEMORY.md 索引文件中。这个文件是关键,它被设计为最多 200 行或 25KB,超出部分会自动截断。每个条目应尽量控制在一行内,低于约150个字符,以确保索引的简洁和高效。

第6层:做梦机制 —— 进行跨会话记忆巩固

这可能是整个系统中最令人惊艳的部分。它会在后台累积足够多的会话后触发,其原理类似于人脑在睡眠时巩固记忆:回顾过去的所有会话日志,组织、整合、清理长期记忆。

其门控序列设计得非常聪明,从最便宜的检查开始,大部分情况下会早早退出,避免不必要的开销:

做梦机制门控检查表

系统使用锁文件(.consolidate-lock)实现互斥,文件中包含 PID 和时间戳,支持崩溃恢复和过期检测。

做梦过程分为四个阶段:

  1. 第一阶段:标定。扫描 memory 目录,读取 MEMORY.md,避免处理重复内容。
  2. 第二阶段:收集。仅 grep 那些疑似重要的文本片段,并检查是否存在矛盾的记忆。
  3. 第三阶段:合并。将新信号合并到现有记忆文件中,删除相互矛盾的事实,并将相对的日期描述(如“两天前”)转换为绝对日期。
  4. 第四阶段:整理与索引。更新 MEMORY.md 索引文件,删除过时的条目,解决不同文件间的矛盾。

做梦代理(Dream Agent)的工具权限受到严格限制:Bash 工具为只读模式,Edit/Write 工具仅允许在 memory 目录下操作。

第7层:跨代理通信 —— 多Agent协作的基础

几乎所有后台操作(会话内存维护、做梦等)都基于 分支代理模式。该模式实现了状态隔离(克隆 LRU 缓存、abortController 等),但通过 CacheSafeParams 和相同的 Prompt 前缀来共享 Prompt Cache,从而实现高效与安全的平衡。

CacheSafeParams数据结构

  • 代理工具支持多种生成模式,SendMessage 工具实现了代理间的实时通信(支持广播、跨会话等)。
  • 代理摘要:每 30 秒使用最经济的 Haiku 模型生成一个 3-5 词的进度快照,用于多代理间的协调。

代理生成模式与缓存策略

代理可以在三个不同范围内维持持久内存,方便知识在不同粒度间共享:

代理记忆的三种作用范围

总结:精妙的系统工程

这套 7 层记忆架构之所以出色,不仅在于清晰的分层,更在于无处不在的工程细节:

  1. 分层防御,成本优先:每一层都旨在防止触发成本更高的下一层。
  2. 极致缓存优化:几乎每一个设计决策都考虑了 Prompt Cache 的影响。
  3. 隔离但共享:分支代理获得克隆的可变状态以防交叉污染,但共享 Prompt 缓存前缀以防成本爆炸。
  4. 鲁棒性设计:包含失败自动阻断、锁文件 PID 检测、互斥检查等,防止小问题演变成大灾难。
  5. 灵活的远程控制:几乎所有核心参数都通过 GrowthBook 功能标志控制,便于随时进行远程调整或回滚,展现了极高的工程成熟度。

通过深入分析 ClaudeCode 的源码和设计,我们可以清晰地看到,它已不再是一个简单的代码补全工具,而更像一个会思考、会记忆、甚至需要通过“睡眠”来巩固知识的真正编程伙伴。其解决 LLM 上下文限制的思路,为整个 Agent 和 RAG 领域提供了极具价值的参考范式。




上一篇:AI变现新路径:从OpenAI广告合作看行业商业模式演进
下一篇:拆解一台2017年的27寸AOC显示器,看看老牌厂商的内部做工与电路设计
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-7 20:19 , Processed in 1.152425 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表