扒完 Claude Code 源码里的记忆系统,我重新审视了 OpenClaw 的设计

0 / 4

上篇文章我扒了 Claude Code 泄露的 4756 个文件,里面有个叫 Auto Dream 的功能——AI 超过 24 小时没人用,自己在后台翻聊天记录整理记忆,跟人睡觉做梦一样。

说实话,看到那段代码的时候我挺受刺激的。

因为记忆这个事,是所有 AI 助手最头疼的问题。你跟它聊了半小时,它忘了开头你说的需求。重启一下对话,偏好又得从头讲。上周定好的方案?"什么方案?"

气人吧?但这真不是模型笨。问题出在上下文管理上——大模型的工作记忆就那么大一个窗口,对话越聊越长,最早的话就被挤掉了。往杯子里倒水,杯子就那么大。

Claude Code 在源码层面给出了一套完整的答案。OpenClaw 在产品层面也有自己的解法。

今天把两边拉在一起看看。


先说 Claude Code 源码里的记忆架构

从泄露的代码来看,Claude Code 的记忆系统主要有这几块:

memdir:8 个文件,管记忆的核心模块

源码里有个 memdir/ 目录,8 个文件:

memdir/findRelevantMemories.ts  → 找相关记忆
memdir/memdir.ts                → 主入口
memdir/memoryAge.ts             → 记忆老化
memdir/memoryScan.ts            → 扫描记忆
memdir/memoryTypes.ts           → 记忆类型定义
memdir/paths.ts                 → 路径管理
memdir/teamMemPaths.ts          → 团队记忆路径
memdir/teamMemPrompts.ts        → 团队记忆提示词

几个有意思的点。

memoryAge.ts 说明 Claude Code 给记忆做了时间衰减——老记忆权重会慢慢降下来。teamMemPaths.tsteamMemPrompts.ts 说明它已经在做团队级记忆了,不只是个人用户。findRelevantMemories.ts 说明它有记忆检索机制,不是每次把所有记忆全塞进去。

SessionMemory:会话记忆服务

services/SessionMemory/ 下面 3 个文件:


services/SessionMemory/prompts.ts
services/SessionMemory/sessionMemory.ts
services/SessionMemory/sessionMemoryUtils.ts

从命名看,这一层管的是单次会话内的记忆。它和 memdir 的关系大概是:SessionMemory 管短期,memdir 管长期。

agentMemory:Agent 专属记忆

工具列表里还有两个文件:


tools/AgentTool/agentMemory.ts
tools/AgentTool/agentMemorySnapshot.ts

这是给多 Agent 协作用的。当一队 AI 一起干活的时候,每个 Agent 有自己的记忆快照。这在我上篇文章提到的 Team 系统(TeamCreateTool、TaskCreateTool)里能用上——协调器给每个 Agent 分任务,每个 Agent 有独立记忆空间。

配置开关

在 Rust 重写的源码里,我找到了两个配置项:

"autoMemoryEnabled" => ConfigSettingSpec {
    scope: ConfigScope::Settings,
    kind: ConfigKind::Boolean,
    path: &["autoMemoryEnabled"],
},
"autoDreamEnabled" => ConfigSettingSpec {
    scope: ConfigScope::Settings,
    kind: ConfigKind::Boolean,
    path: &["autoDreamEnabled"],
},

autoMemoryEnabled 控制的是自动记忆——AI 在对话中自动把重要信息存下来,不用你手动让它记。

autoDreamEnabled 就是我上篇说的那个 Auto Dream——AI 空闲时自己整理记忆。

还有个 remember 技能藏在 skills/bundled/remember.ts 里,八成是让用户主动告诉 AI "记住这个"的功能。

Compaction:Rust 重写里的压缩逻辑

这个是最有料的部分,因为完整的 Rust 源码暴露了压缩的全部实现。

pub struct CompactionConfig {
    pub preserve_recent_messages: usize,  // 保留最近几条消息
    pub max_estimated_tokens: usize,      // 超过多少 token 触发压缩
}

默认保留最近 4 条消息,最大估算 10000 token。

压缩生成的摘要包含:

  • 被压缩了多少条消息(user/assistant/tool 分别多少)
  • 用过哪些工具
  • 最近 3 条用户请求
  • 待办事项(通过关键词 todo/next/pending/remaining 自动识别)
  • 关键文件列表(从消息里自动提取文件路径)
  • 当前正在做什么
  • 完整时间线

我觉得这个设计相当周全。不是简单地"把旧消息总结成一句话",而是结构化地保留了各种维度的上下文。

自动压缩的触发条件也找到了——累计输入 token 超过 20 万就自动压:

const DEFAULT_AUTO_COMPACTION_INPUT_TOKENS_THRESHOLD: u32 = 200_000;

还能通过环境变量 CLAUDE_CODE_AUTO_COMPACT_INPUT_TOKENS 调整。

/memory 命令

命令列表里有 /memory/compact 两个命令。/memory 用来查看和管理记忆文件,/compact 手动触发压缩。灰度中的 Auto Dream 大概率也是通过 /memory 入口开启。


再来看 OpenClaw 的记忆系统

OpenClaw 的解法用一句话说就是:文件就是记忆

需要记的东西,全写进 Markdown 文件。磁盘上写了什么,模型就"记得"什么。没写的?不存在。

土是土了点。但你会发现,它覆盖了 Claude Code 源码里记忆系统的主要能力层,而且有些地方更灵活。

三层记忆

跟 Claude Code 对应起来看:

第一层:工作记忆 — 当前对话的 context window。跟 Claude Code 的 SessionMemory 对应。

第二层:短期记忆(Compaction) — 对话快满了自动压缩。跟 Claude Code 的 Compaction 逻辑对应。Claude Code 默认 20 万 token 触发,保留最近 4 条。OpenClaw 在压缩前还会通知 Agent "快压缩了,赶紧存重要信息",这个比 Claude Code 多了一步。

第三层:长期记忆 — 磁盘上的 Markdown 文件。跟 Claude Code 的 memdir 对应。

文件结构

~/.openclaw/workspace/
├── MEMORY.md          # 长期记忆(相当于 Claude Code 的 memdir)
├── memory/
│   ├── 2026-04-01.md  # 今天的日志
│   └── 2026-03-31.md  # 昨天的日志
├── AGENTS.md          # 行为规范(相当于 CLAUDE.md)
├── SOUL.md            # 人格设定
├── USER.md            # 用户信息
└── HEARTBEAT.md       # 心跳任务(对标 KAIROS 的定时能力)

MEMORY.md 相当于 Claude Code memdir 里的长期存储。但 OpenClaw 多了一层设计:只在私聊加载。群组对话不会注入这些文件,隐私上多了一层保护。

memory/日期.md 是按天的日志,Agent 启动时读今天和昨天的。这个在 Claude Code 里没有直接对应,它的 SessionMemory 更偏会话级别。

记忆检索

Claude Code 有 findRelevantMemories.ts 做记忆检索。OpenClaw 给了两个工具:

memory_search — 语义搜索。同时用向量搜索和 BM25 关键词搜索:

最终分数 = 0.7 × 向量分数 + 0.3 × 关键词分数

向量搜索擅长处理同义不同词的情况("Mac 主机"匹配"跑 gateway 的那台机器"),BM25 擅长精确匹配(commit hash、配置项名字)。两个一起用,互补。

memory_get — 精确读取。先 search 定位,再 get 取全文。

从 Claude Code 的 findRelevantMemories.ts 命名看,它大概率也是做类似的相关性检索。但具体算法不清楚——TypeScript 源码没在这次泄露里完整暴露,只有 Rust 重写的部分和文件名列表。

时间衰减

Claude Code 有 memoryAge.ts。OpenClaw 也有时间衰减。30 天半衰期的话:

  • 今天的笔记:100%
  • 一周前的:84%
  • 一个月前的:50%
  • 三个月前的:12.5%

旧的记忆自然被压下去,但 MEMORY.md 这种永久文件不受影响。

两边思路一样:不是删记忆,而是降权重

压缩前抢救 vs 自动存储

Claude Code 有 autoMemoryEnabled,AI 对话中自动把重要信息存下来。

OpenClaw 有个不同但有意思的设计:压缩前通知。Context 快满了要压缩之前,系统会偷偷给 Agent 发一条消息——"快压缩了,赶紧把重要的东西存一下。" Agent 收到后会把关键信息写到 memory 文件里,然后静默回复。用户全程无感。

一个是日常自动存,一个是危急时刻抢救。说实话两个都需要。


核心差异:Claude Code 有、OpenClaw 缺的

看完源码,有几个 Claude Code 的能力让我觉得 OpenClaw 值得学习。

Auto Dream — 离线记忆整理

Claude Code 的 autoDream 在用户 24 小时不用的时候自动启动,翻历史对话提炼有用信息写进长期记忆。

OpenClaw 的 Heartbeat 机制能模拟一部分——你可以在 HEARTBEAT.md 里写"定期回顾日志更新 MEMORY.md"。但这本质是用户主动配置的,不是系统自动做的。

差距在于:Claude Code 的 Dream 是内建的自动化机制,有锁、有回滚、有四阶段 Prompt。OpenClaw 的是用户自助

团队记忆

Claude Code 有 teamMemPaths.tsteamMemPrompts.ts,多个 Agent 协作时共享记忆。

OpenClaw 目前是单 Agent 思路,每个 workspace 独立。如果要做多 Agent 协作(OpenClaw 的 subagent 功能),记忆是隔离的。

Agent 记忆快照

agentMemorySnapshot.ts 让每个 Agent 在执行完任务后保存一份记忆快照。这对于恢复、回溯很有用。

OpenClaw 的 memory 文件虽然能手动管理,但没有自动快照机制。

结构化压缩

Claude Code 的 Rust 源码里,压缩摘要是结构化的——工具列表、待办事项、关键文件、时间线,分门别类。

OpenClaw 的 Compaction 信息不太透明,用户更多依赖 /compact 命令手动控制。


反过来,OpenClaw 有、Claude Code 缺的

也别光捧 Claude Code。OpenClaw 有些设计思路反而更实用。

隐私隔离

MEMORY.md 只在私聊加载,群组对话不会暴露。Claude Code 的源码里没看到类似的场景区分——它本来就是个人工具,没有群聊场景。但 OpenClaw 跑在 Signal、Telegram、WhatsApp 上,这个隔离就很必要了。

记忆完全用户可控

OpenClaw 的记忆就是 Markdown 文件。你能直接用编辑器打开看、改、删。不喜欢?删掉就行。想加?新建一个 .md 文件。

Claude Code 的记忆存在 .claude/ 目录下的内部格式里,对用户不太透明。

混合检索

向量 + BM25 的混合检索在 OpenClaw 里是开箱即用的。Claude Code 的 findRelevantMemories.ts 具体算法没暴露,无法确认它是否也用了类似方案。但从文件名看,大概率是做了相关性检索。

Heartbeat 自主节奏

每 30 分钟 Agent 看一眼 HEARTBEAT.md,有活干就干。这比 Claude Code 的 KAIROS 更轻量——KAIROS 需要后台常驻进程,Heartbeat 只要配个定时检查。


实操建议

聊了这么多架构,落到实操。

怎么让你的 OpenClaw 记忆系统更好用

开混合检索,确保搜得准:

{
  "memorySearch": {
    "query": {
      "hybrid": {
        "enabled": true,
        "vectorWeight": 0.7,
        "textWeight": 0.3
      }
    }
  }
}

开时间衰减,让新记忆优先:

{
  "temporalDecay": {
    "enabled": true,
    "halfLifeDays": 30
  }
}

用 HEARTBEAT.md 模拟 Auto Dream

# 每周日回顾
- 读这周的 memory/YYYY-MM-DD.md 文件
- 把值得保留的信息更新到 MEMORY.md
- 删除过时内容

分清该写哪里

  • MEMORY.md:偏好、长期决策、踩坑记录
  • memory/日期.md:今天干了啥、临时决定
  • 不要放:密码、API key(用环境变量)

一句话:想让 Agent 下次还记得的,写文件。没写的,就是没有。

遇到问题排查

搜不准:开混合检索。中文用户确认嵌入模型支持多语言。

Context 满了:跑 /context detail 看哪块占得多。一般是 TOOLS.md 太长或工具太多。

Agent 忘事:信息是不是只存在 context 里没写文件?群组对话里不加载 MEMORY.md,切到私聊看看。


最后说两句

Claude Code 泄露的源码告诉我们一件事:Anthropic 在记忆这个方向上押了很大的注。8 个文件的 memdir 模块、会话记忆服务、Agent 记忆快照、Auto Dream、团队记忆——这些加在一起,描绘的是一个有持续记忆的 AI 同事,不是一个用完就忘的聊天框。

OpenClaw 用 Markdown 文件走了一条更朴素的路。没有 Auto Dream 那么炫,但用户对记忆有完全控制权。你知道它记了什么,你能改,你能删。

两条路各有取舍。要自动化还是要透明度?要智能还是要可控?

我觉得最终的答案是两个都要。OpenClaw 如果能加上自动记忆整理(类似 Auto Dream)和结构化压缩摘要,同时保留现有的文件级透明度——那就是最好的组合。

目前来看,OpenClaw 的记忆系统基础很扎实。把混合检索和时间衰减配好,用 Heartbeat 补上一部分自动化,已经能解决 80% 的"AI 失忆"问题。

剩下的 20%?等 OpenClaw 把 Auto Dream 借鉴过来吧。


来源:Claude Code v2.1.88 源码分析 + GitHub instructkr/claw-code Rust 重写 + OpenClaw 官方文档

上篇 → Claude Code 源码全泄露,我扒了 4756 个文件,给你们划重点

有用的话点个关注 ✍️

阅读全文