这是一份面向学习和借鉴的设计笔记。它说明 OpenClaw 如何让 AI Agent 记住长期信息、查找历史细节、在上下文压缩前保存重要内容,并把零散记录逐步整理成可靠的长期记忆。

OpenClaw 的核心思路可以概括为一句话:把记忆当作可治理的数据生命周期,而不是把它藏在模型或向量数据库里。 人能看到和编辑关键记忆;模型只能通过明确的文件、工具和运行时能力读取或写入记忆;索引负责帮模型找到内容,但原始文件仍然是事实来源。

一页读懂

如果不用工程术语,可以把 OpenClaw 的记忆系统理解成三件东西:

  1. 一本精简的人设和长期档案MEMORY.md,只放长期稳定、反复有用的信息。
  2. 一套按天保存的工作日志memory/YYYY-MM-DD.md,记录当天发生的细节、任务、决策和观察。
  3. 一个图书馆目录:SQLite、全文检索和向量索引,帮助 agent 在需要时找到旧内容。

这三件事分工不同:

  • MEMORY.md 像简历或个人资料,短、准、长期有效。
  • memory/ 像工作笔记,详细、可追加、可回看。
  • 搜索索引像目录卡片,可以重建,不应该成为唯一真相。

OpenClaw 不会把所有历史都塞进 prompt。它只把启动时真正需要的高信号内容放进上下文,详细历史通过 memory_searchmemory_get 按需读取。这样既保留了长期连续性,又控制了 token 成本和隐私风险。

这套设计解决什么问题

长期运行的 Agent 会遇到四类记忆问题:

  • 记不住:跨天、跨会话后,用户偏好和项目约定丢失。
  • 记太多:把完整聊天历史塞进 prompt,成本高、速度慢、还容易污染回答。
  • 记不准:模型凭印象回答,把临时结论当成事实。
  • 记不安全:私聊内容、群组内容、后台任务内容混在一起,边界不清。

OpenClaw 的答案不是单靠 RAG,也不是单靠 prompt summary,而是组合出一条完整路径:

会话内容
  -> 需要保存的短期事实写入 memory/
  -> 搜索索引让旧内容可被找回
  -> 多次被使用的内容进入 dreaming 整理
  -> 高价值候选再进入 MEMORY.md
  -> 启动和回答时按需加载

这条路径的重点是分层:详细内容留在文件里,常用结论进入长期记忆,检索工具负责连接两者。

关键设计原则

1. 文件是事实来源

OpenClaw 把长期记忆和工作记忆放在普通文件里,主要是 Markdown。这样做的好处是直接:

  • 人可以打开、搜索、编辑、删除。
  • Git 可以 diff、review、回滚。
  • 索引损坏时可以从文件重建。
  • 模型不能拥有一份看不见的隐藏记忆。

这并不表示系统里只有 Markdown。OpenClaw 仍会使用 SQLite、JSONL、embedding、plugin 后端等辅助数据结构。但这些结构承担的是索引、状态、缓存或外部服务连接,不应该取代人类可审查的事实来源。

2. prompt 只放必要内容

Agent 的上下文窗口是有限资源。OpenClaw 不把 daily memory 或完整 transcript 默认塞进每轮 prompt,而是区分:

  • 启动时需要知道的内容:从 bootstrap files 和有限 startup context 注入。
  • 回答时临时需要的历史:通过记忆工具检索。
  • 长期稳定事实:放入精简的 MEMORY.md

这个原则让记忆系统更像 “先查资料再回答”,而不是 “把所有资料背下来再回答”。

3. 压缩前先落盘

长对话接近上下文上限时,系统会压缩旧消息。压缩可以保留主线,但可能丢失细节。OpenClaw 在压缩前安排一次受限的静默写入,把当前窗口中值得保留的事实追加到 daily memory。

这一步很关键:它让重要信息先变成可检索文件,再离开上下文窗口。

4. 长期记忆需要晋升,不是随手写入

不是所有信息都应该进入 MEMORY.md。一次性任务、临时猜测、失败尝试和完整日志应该留在 memory/。只有多次被使用、被确认、跨会话有价值的信息,才适合晋升为长期记忆。

OpenClaw 用 dreaming 机制做后台整理和候选晋升,避免普通回答轮次随意污染长期记忆。

5. 读取和写入权限分开

读历史和写记忆是两种风险等级。OpenClaw 的工具设计明显更谨慎地限制写入,例如 pre-compaction flush 默认只能追加到当天 daily file,不能改写 MEMORY.mdDREAMS.md 或 bootstrap files。

这对其他项目很重要:记忆系统的安全性主要来自数据边界和权限边界,不只来自检索算法。

存储层:记忆放在哪里

MEMORY.md:长期记忆档案

MEMORY.md 是根目录下的 canonical memory file,用来保存长期有效、跨会话有价值的信息。

适合放入 MEMORY.md

  • 用户稳定偏好,例如回复语言、测试偏好、沟通方式。
  • 项目级约定,例如发布流程、验证方式、代码边界。
  • 长期任务状态,例如某个迁移计划的当前阶段。
  • 已确认的经验教训,例如反复出现的问题和解决方式。

不适合放入 MEMORY.md

  • 一次性聊天细节。
  • 大段日志、命令输出、完整 diff。
  • 未确认的模型猜测。
  • token、手机号、凭证、私密配置。

OpenClaw 会把 MEMORY.md 作为 bootstrap files 的一部分处理,并受字符预算限制:单个 bootstrap 文件默认最多注入 12000 字符,总 bootstrap 注入默认最多 60000 字符。源码中 canonical 文件名是大写 MEMORY.md;小写 memory.md 只作为 legacy repair 输入,不是正常注入路径。

memory/:日常工作记忆

memory/ 目录保存详细工作记录。常见形态包括:

  • memory/YYYY-MM-DD.md:当天的 daily memory。
  • memory/YYYY-MM-DD-HHMM.md:session-memory hook 在 /new/reset 时保存的近期会话摘要。
  • 其他 Markdown 文件:可以通过配置纳入检索。

这些文件的定位是 “详细历史”,不是 “每次启动全量注入”。普通回答时,agent 应通过 memory_searchmemory_get 查找其中的内容。

startup context 是一个例外。它会在 /new/reset 等重启类流程需要模型继续运行时读取最近 daily memory。默认窗口是最近 2 天,单文件最多读取 16 KiB、注入 1200 字符,总计最多 2800 字符;配置上限是最多 14 天、单文件 64 KiB/10000 字符、总计 50000 字符。每天最多额外带入 4 个 slugged daily files。裸 /new/reset 只会被确认,不会为了加载 startup memory 单独调用模型。

DREAMS.mdmemory/.dreams/:整理区

Dreaming 是后台整理机制。它会把工作记忆里的高价值内容变成候选摘要,并记录整理状态。

  • DREAMS.md 面向人,便于查看 dreaming 结果、历史回填和候选记忆。
  • memory/.dreams/ 面向机器,保存 recall、promotion、session corpus、phase signal 等状态。

只有更严格的 deep dreaming 流程才会写入 MEMORY.md。这把 “候选整理” 和 “长期记忆写入” 分开,降低长期记忆被污染的概率。

session transcript:完整历史,但不是默认记忆

OpenClaw 的完整会话历史会作为 session transcript 保存。它不是自动等同于长期记忆,也不应该无条件进入检索语料。

当配置允许时,session 内容可以被清洗、转换并索引到 sessions corpus。这个路径有可见性过滤,会跳过 checkpoint、backup 等不适合作为普通记忆结果的内容。这样可以在需要时搜索旧会话,同时避免把所有原始聊天噪声都当成记忆。

读取流程:Agent 如何想起旧事

OpenClaw 把 “启动时注入” 和 “运行中检索” 分开。

启动时,agent workspace 会加载一组 bootstrap files,例如:

  • AGENTS.md
  • SOUL.md
  • TOOLS.md
  • IDENTITY.md
  • USER.md
  • HEARTBEAT.md
  • BOOTSTRAP.md
  • MEMORY.md

这些文件进入 Project Context,并受预算限制。子 agent、cron 等特殊会话还会有额外过滤。

运行中,memory-core plugin 会把记忆工具暴露给模型:

  • memory_search:按 query 搜索 memorysessionswikiall corpus。
  • memory_get:根据搜索结果读取更完整的文件片段。

系统提示会引导模型在回答 “以前做过什么”“用户偏好是什么”“某个项目状态是什么” 这类问题前先使用记忆工具,而不是凭空回忆。

OpenClaw 还支持 active memory:一个可选的轻量 agent 可以在后台提前召回可能相关的记忆。它适合直接聊天和明确配置的 agent,不应被理解为所有 channel 默认共享一份私有记忆。

搜索流程:为什么既要关键词也要向量

默认 builtin memory 使用本地 SQLite 管理文件、chunk 和全文索引。memory host 默认扫描 canonical root memory 与 memory/ 目录,也可以纳入可配置 extra paths。Markdown 会被拆成 chunk,默认估算 400 tokens 一段、80 tokens overlap。索引会跳过 symlink,并在启用时支持 multimodal metadata。

搜索分成两类:

  • 关键词搜索:基于 SQLite FTS5/BM25,适合查函数名、错误码、文件名、命令、issue 编号。
  • 向量搜索:基于 embedding,适合查意思相近但措辞不同的内容。

只做向量搜索会漏掉很多精确符号;只做关键词搜索又不擅长语义相似问题。OpenClaw 选择 hybrid search,把两类结果合并。

当前实现会取向量结果和文本结果的 union,然后按 chunk id 合并分数。默认参数包括:

  • vectorWeight = 0.7
  • textWeight = 0.3
  • maxResults = 6
  • minScore = 0.35
  • candidateMultiplier = 4
  • maxCandidates = 200

核心公式是:

finalScore = vectorWeight * vectorScore + textWeight * textScore

之后还可以叠加:

  • temporal decay:时间衰减,默认关闭,half-life 默认 30 天。
  • MMR:多样性重排,默认关闭,lambda 默认 0.7。
  • strict fallback relaxation:严格阈值下无结果但关键词召回存在时,对关键词支撑的结果放宽阈值。

embedding provider 的自动选择大致按已注册 provider 的 autoSelectPriority 排序。当前常见顺序是 local、GitHub Copilot、OpenAI、Gemini、Voyage、Mistral、DeepInfra、Bedrock。ollama 支持配置,但不是当前自动选择链路的一部分。

如果向量能力不可用,OpenClaw 可以退化为 FTS-only 搜索。向量查询优先使用 sqlite-vec KNN;sqlite-vec 不可用时,会退回到进程内 cosine scan。

写入流程:什么时候把内容变成记忆

OpenClaw 的写入路径可以分成三种。

人或 agent 明确写入 daily memory

普通工作中,适合把临时但有价值的内容写入 memory/YYYY-MM-DD.md。例如:

  • 今天做过哪些验证。
  • 某个 bug 的复现条件。
  • 一个尚未完全确认的设计判断。
  • 后续要继续跟进的任务。

这类内容详细但不一定长期稳定,所以先进入 daily memory,而不是直接进入 MEMORY.md

会话重启时保存近期上下文

session-memory hook 会在 /new/reset 时异步保存近期会话上下文,默认取最近 15 条消息,并可配置 LLM slug。它的作用是让会话切换后仍能找到刚刚发生的上下文。

压缩前静默 flush

当上下文预计接近上限时,OpenClaw 会在 compaction 前触发 pre-compaction memory flush。触发判断可以简化理解为:

预计 token >= 上下文窗口 - 保留区 - 软阈值

源码中的判断形态是:

projectedTokens >= contextWindow - reserveTokensFloor - softThresholdTokens

关键默认值和约束:

  • softThresholdTokens 默认 4000。
  • transcript 超过 2 MiB 时可强制 flush。
  • 每个 compaction cycle 最多 flush 一次。
  • 默认目标是 memory/YYYY-MM-DD.md
  • MEMORY.mdDREAMS.md 和 bootstrap files 在这个阶段是 read-only。
  • 写入工具只允许对目标 daily file 做 append-only write。
  • 静默轮次以 NO_REPLY 结束,不向用户发送常规回答。
  • heartbeat、CLI、read-only sandbox 等场景会跳过或收敛该行为。

这一步的产品含义很简单:在模型即将失去细节上下文前,先把值得保留的信息变成文件。

Dreaming:从工作笔记提炼长期记忆

Dreaming 可以理解成 “后台整理”。它不只是摘要,而是把分散在 daily memory、session corpus 和 recall 记录里的信息整理成更稳定的候选记忆。

它包含几类动作:

  • recall tracking:记录哪些短期记忆被搜索命中、被使用。
  • short-term promotion:根据多种信号评分,判断是否值得晋升。
  • consolidation:把多个相关片段合并成更简洁的候选知识。
  • grounded backfill:用已有文件作为依据补齐或修正候选,不凭空生成。

short-term promotion 不是简单的 “出现 3 次就晋升”。源码中使用加权信号,例如:

  • frequency:0.24
  • relevance:0.30
  • diversity:0.15
  • recency:0.15
  • consolidation:0.10
  • conceptual:0.06

默认晋升门槛还会考虑最小分数、召回次数、唯一 query 数等条件。深度 dreaming 的条件更严格,例如更高 minScore、更多 unique queries、recency half-life 和 max age 限制。

对其他项目而言,最值得借鉴的是这个边界:工作记忆可以宽松记录,长期记忆必须谨慎晋升。

plugin 后端与可替换性

OpenClaw 的 core 不应该知道某个具体记忆服务的私有策略。它通过 memory capability、工具、host SDK 和 plugin runtime 把记忆实现挂接进来。

当前源码和文档中可以确认的记忆相关实现包括:

  • builtin memory:默认本地 SQLite、FTS5、embedding hybrid search。
  • QMD:基于 Markdown/sidecar 的记忆后端,强调文件可移植性。
  • Honcho:外部记忆服务集成。
  • memory-lancedb plugin:基于 LanceDB 的外部记忆 plugin。
  • memory-wiki plugin:作为 companion plugin 提供 wiki 型资料检索。

设计边界上要注意:

  • active memory slot 通常只有一个 owner,避免多个后端同时主动注入互相竞争的上下文。
  • wiki 这类 companion 检索可以和主 memory backend 并存,但要通过 corpus、工具描述和权限边界区分。
  • core 应依赖通用 capability 和工具契约,不应写死某个具体 plugin 的内部策略。

给其他项目的复用方案

如果要在另一个 Agent 项目里复用这套思想,可以从五层开始:

  1. 长期档案:一个小型、人工可审查的 MEMORY.md,只放长期稳定事实。
  2. 工作日志:按天或按任务追加写入 memory/,保留细节但不直接注入 prompt。
  3. 混合检索索引:对工作日志做关键词 + embedding 检索,结果通过工具按需读取。
  4. 压缩前保存:上下文压缩前先把高价值细节写入 work log,写入范围受限。
  5. 后台整理:根据多次召回、相关性、时间和人工审查,把工作记忆提纯到长期记忆。

一个最小目录结构可以是:

project/
  MEMORY.md                  # 精选长期事实
  memory/
    2026-05-24.md            # 当天追加式工作日志
    .dreams/                 # 可选:机器整理状态
  index.sqlite               # 可重建的检索索引

推荐从这些规则开始:

  • 启动时只注入 MEMORY.md 的高信号片段,不注入完整历史。
  • daily memory 通过 search/get 工具读取,不每轮自动加载。
  • 每次压缩前要求模型追加值得保留的事实、决策、待办和约束。
  • 长期记忆写入需要更高门槛,最好带来源和人工 review。
  • 定期运行 consolidation,把重复日志变成简洁、可维护的长期条目。

常见反模式

迁移这套机制时应避免:

  • 把完整聊天历史直接注入 prompt,导致成本和隐私风险失控。
  • 把向量数据库当作唯一事实来源,导致无法人工检查、无法 diff、无法回滚。
  • 让模型在普通回答轮次中随意重写长期记忆。
  • 不区分私聊、群组、后台任务、subagent 的记忆可见性。
  • 只做 “记住这个” 的显式写入,不做压缩前 flush 和后台 consolidation。
  • 只做相似度搜索,不支持关键词、文件名、错误码等精确检索。
  • 把 daily memory 当成长期档案,长期不整理,最后变成无法维护的日志堆。

安全与隐私边界

记忆系统最容易出问题的地方不是算法,而是边界。

需要特别注意:

  • 私有长期记忆和共享 channel 不能默认混用。群组、公开频道、cron、subagent 都需要单独的加载规则。
  • 原始 transcript 不应无条件进入长期记忆或共享检索语料。
  • 写入权限要比读取权限更窄。pre-compaction flush 只能 append 到 daily file,是一个值得复用的约束。
  • MEMORY.md 要保持小而准;越像垃圾场,越会损害 prompt 质量和隐私边界。
  • embedding/vector index 不是事实来源,系统应能从原始文件重建索引。

技术读者关注点

如果要进一步看源码,可以从这些入口开始:

  • root memory 文件名和 legacy repair:src/memory/root-memory-files.ts
  • bootstrap file 加载:src/agents/workspace.ts
  • system prompt 和 Project Context:src/agents/system-prompt.ts
  • memory search 配置默认值:src/agents/memory-search.ts
  • startup daily memory:src/auto-reply/reply/startup-context.ts
  • pre-compaction flush:src/auto-reply/reply/memory-flush.ts
  • flush 工具权限:src/agents/pi-tools.ts
  • session-memory hook:src/hooks/bundled/session-memory/handler.ts
  • memory host 扫描和 chunk:packages/memory-host-sdk/src/host/internal.ts
  • SQLite schema:packages/memory-host-sdk/src/host/memory-schema.ts
  • session corpus:packages/memory-host-sdk/src/host/session-files.ts
  • memory-core capability:extensions/memory-core/index.ts
  • memory tools:extensions/memory-core/src/tools.ts
  • prompt guidance:extensions/memory-core/src/prompt-section.ts
  • search manager:extensions/memory-core/src/memory/manager.ts
  • vector/keyword search:extensions/memory-core/src/memory/manager-search.ts
  • hybrid scoring:extensions/memory-core/src/memory/hybrid.ts
  • flush plan:extensions/memory-core/src/flush-plan.ts
  • short-term promotion:extensions/memory-core/src/short-term-promotion.ts

相关文档入口:

  • docs/concepts/memory.md
  • docs/concepts/memory-search.md
  • docs/concepts/memory-builtin.md
  • docs/concepts/dreaming.md
  • docs/concepts/active-memory.md
  • docs/concepts/compaction.md
  • docs/reference/memory-config.md
  • docs/reference/session-management-compaction.md
  • docs/reference/token-use.md
  • docs/plugins/memory-lancedb.md
  • docs/plugins/memory-wiki.md

最后总结

OpenClaw 记忆机制最值得学习的不是某个单点算法,而是整体治理方式:长期记忆是小而准的人工可审查档案,工作记忆是可追加的详细日志,搜索索引负责召回,压缩前先保存关键事实,后台整理再把高价值内容晋升为长期记忆。

这种设计适合长期运行、需要跨会话连续性、又必须控制隐私和上下文成本的 Agent 系统。