为什么你的 AI Agent 总是"失忆"?OpenClaw 用两个文本文件解决了

cover

你让 OpenClaw 帮你写了一个 API,调了三轮才满意。第二天你说”昨天那个 API 还需要加个分页”——它完全不记得了。

这是 AI Agent 最大的痛点之一:没有记忆,每次对话都从零开始。

OpenClaw 的解决方案是一个叫做”双源记忆系统”的架构。两个独立的记忆源——长期记忆(MEMORY.md)和每日日志(daily logs)——协同工作,让 Agent 既能记住长期偏好,又能回忆昨天的工作细节。

这套系统在 2026 年初的 v0.5 版本中引入,3 月 7 日的 v2026.3.7-beta.1 又通过 ContextEngine 插件接口进行了重大升级。社区里有人说:**”这是 OpenClaw 和其他 Agent 框架拉开差距的关键设计。”**

今天我们从架构到代码,完整拆解这套双源记忆系统。

为什么需要”双源”:单一记忆的困境

在聊架构之前,先理解一个问题:为什么不用一个记忆源?

纯长期记忆的问题: 如果只有一个长期知识库,每次对话的临时信息——“刚才那个变量叫 userCount”、”上一轮我们决定用 PostgreSQL”——要么不存,要么全存。不存就丢失上下文,全存就把知识库变成垃圾场。

纯短期日志的问题: 如果只有逐日记录,Agent 知道你昨天做了什么,但不知道你”永远偏好 TypeScript 而不是 JavaScript”。每次都得重新告诉它你的偏好。

双源的设计哲学: 长期记忆存”你是谁、你喜欢什么、项目的核心约定”,每日日志存”今天做了什么、遇到了什么问题、决定了什么方案”。一个管身份,一个管经历。像人脑的语义记忆和情景记忆。

这不是 OpenClaw 发明的概念,但它的实现方式——纯文本文件 + 向量索引 + 混合搜索——在工程上非常优雅。

第一源:MEMORY.md——Agent 的”性格档案”

MEMORY.md 是 OpenClaw 的长期记忆文件,存在项目根目录下。它是一个纯 Markdown 文件,Agent 可以读,也可以写。

一个典型的 MEMORY.md 长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# User Preferences
- Prefers TypeScript over JavaScript
- Uses Vim keybindings
- Code style: functional, immutable, no classes

# Project Context
- Tech stack: Next.js 15 + Prisma + PostgreSQL
- Deployment: Vercel + Supabase
- Testing: Vitest, not Jest

# Working Agreements
- Always run tests before committing
- PR descriptions must include "Why" section
- Never use default exports

几个设计要点:

第一,纯文本,人类可读可编辑。 不是数据库,不是 JSON,是你用任何文本编辑器都能打开的 Markdown。这意味着你可以随时手动修改 Agent 的”记忆”——加一条偏好,删一条过时的信息。

第二,Agent 自主维护。 OpenClaw 的 Agent 在对话过程中会自动判断哪些信息值得写入 MEMORY.md。你说”以后别用 Jest 了,换成 Vitest”,它会把这条偏好追加到文件里。下次对话,它读到这条,就知道该用 Vitest。

第三,每次对话开始时自动加载。 Agent 启动时,MEMORY.md 的内容会被注入到系统提示词(system prompt)中。这相当于 Agent 的”人格初始化”——它一醒来就知道自己该怎么行事。

第四,有容量限制。 MEMORY.md 不能无限膨胀。OpenClaw 建议控制在 200 行以内,超过部分会被截断。这迫使你和 Agent 一起维护这个文件的质量——只保留真正重要的信息。

第二源:每日日志——Agent 的”工作日记”

每日日志存在 .openclaw/logs/ 目录下,文件名是日期:2026-03-19.md2026-03-18.md……

每个日志文件记录了当天的对话摘要、关键决策、遇到的问题和解决方案。格式大概是这样的:

1
2
3
4
5
6
7
8
9
10
11
# 2026-03-19

## Session 1 (09:00-10:30)
- Built user notification API with WebSocket support
- Decided to use Redis pub/sub instead of polling
- Fixed: Prisma connection pool exhaustion under load

## Session 2 (14:00-15:45)
- Refactored auth middleware to support OAuth2
- Key decision: JWT stored in httpOnly cookie, not localStorage
- TODO: Add refresh token rotation

和 MEMORY.md 不同,每日日志有几个独特特性:

第一,自动生成,无需手动维护。 每轮对话结束时,Agent 会自动把关键信息压缩成摘要,追加到当天的日志文件里。你不需要操心。

第二,有时间维度。 你可以问 Agent:”上周三我们做了什么?”它会去查 2026-03-12.md,给你一个精确的回答。这是 MEMORY.md 做不到的——长期记忆没有时间概念。

第三,天然支持渐进式遗忘。 越早的日志,被检索到的概率越低。OpenClaw 的搜索算法会给近期日志更高的权重。这模拟了人类记忆的”近因效应”——昨天的事比上个月的事记得更清楚。

核心引擎:混合搜索

两个记忆源存了数据,但怎么找到需要的信息?这就是 OpenClaw 混合搜索引擎的工作。

当 Agent 需要回忆某些信息时,它调用内置的 memorySearch 工具。这个工具同时执行两种搜索:

向量搜索(Vector Search): 把查询文本转成嵌入向量,和记忆库中的向量做余弦相似度比较。适合语义匹配——你问”之前怎么处理认证的”,它能匹配到”JWT stored in httpOnly cookie”,即使两句话没有任何相同的词。

关键词搜索(BM25): 传统的全文检索。适合精确匹配——你问”Prisma 连接池”,它能直接找到包含这两个词的日志条目。

两种搜索的结果会被合并、去重、排序,返回最相关的记忆片段。

技术实现上:

存储层:SQLite + 向量扩展。 OpenClaw 用 SQLite 作为本地向量数据库。每条记忆被切分成约 400 Token 的 chunk,80 Token 重叠,用 SHA-256 做去重。这意味着同一段信息不会被重复索引。

嵌入模型:可插拔。 默认使用 OpenAI 的 text-embedding-3-small,但也支持 Gemini、Voyage、甚至本地模型。你可以在 settings.json 里配置:

1
2
3
4
5
6
7
8
9
{
"memory": {
"embedding": {
"provider": "openai",
"model": "text-embedding-3-small",
"dimensions": 1536
}
}
}

搜索权重:可调节。 向量搜索和 BM25 的权重比默认是 0.7:0.3。如果你的使用场景更偏精确查找(比如代码片段检索),可以把 BM25 的权重调高。

关键机制:Pre-Compaction Flush

双源记忆系统里最精巧的设计,是 pre-compaction flush(压缩前刷写)机制。

什么是 compaction?当对话上下文太长时,OpenClaw 会对早期消息做摘要压缩,释放上下文窗口空间。这个过程叫 compaction。

问题来了:如果一段重要的对话在 compaction 时被压缩了,细节就丢失了。摘要只保留大意,不保留具体的代码片段、参数值、配置项。

Pre-compaction flush 的解决方案: 在 compaction 执行之前,先把即将被压缩的对话内容写入记忆系统。具体流程是:

  1. 检测到上下文即将溢出,触发 compaction
  2. 暂停压缩,先执行 flush
  3. 把即将被压缩的消息中的关键信息提取出来
  4. 写入每日日志(短期)和/或 MEMORY.md(长期)
  5. 建立向量索引
  6. 恢复压缩,对原始消息做摘要

这样,即使对话被压缩了,关键信息已经安全地存到了记忆系统里。Agent 以后可以通过 memorySearch 检索到这些信息。

社区的评价是:**”这个 flush-before-discard 模式解决了所有 Agent 框架都面临的上下文丢失问题。”**

ContextEngine:插件化的记忆架构

2026 年 3 月 7 日,OpenClaw v2026.3.7-beta.1 引入了 ContextEngine 插件接口。这是双源记忆系统的一次重大升级。

ContextEngine 定义了五个生命周期钩子:

钩子 触发时机 用途
bootstrap Agent 启动时 加载初始记忆、建立索引
ingest 新消息到达时 提取信息、判断是否值得记忆
assemble 构建上下文时 决定哪些记忆注入到当前对话
compact 上下文压缩时 执行 pre-compaction flush
afterTurn 每轮对话结束后 更新日志、维护索引

这意味着你可以写自定义的 ContextEngine 插件,完全改变 Agent 的记忆行为。

比如,你可以写一个插件,让 Agent 把记忆存到 Notion 而不是本地文件。或者写一个插件,让 Agent 根据项目的 Git 历史自动构建上下文——谁改了什么文件、什么时候改的、commit message 写了什么。

36 氪的评价是:**”ContextEngine 把 OpenClaw 从一个’带记忆的 Agent’变成了一个’记忆架构可编程的 Agent 平台’。”**

实战:怎么用好双源记忆

理解了架构,来聊聊实战中怎么用好这套系统。

技巧 1:主动维护 MEMORY.md。 不要完全依赖 Agent 自动写入。定期检查 MEMORY.md,删掉过时的信息,补充遗漏的偏好。一个干净的 MEMORY.md 比一个臃肿的 MEMORY.md 效果好 10 倍。

技巧 2:用 memorySearch 调试记忆。 如果 Agent 的行为不符合预期,直接问它:”搜索你的记忆,关于 X 你记得什么?”看看返回的结果是否正确。很多时候问题不是 Agent 笨,而是记忆库里存了错误的信息。

技巧 3:利用日志做复盘。 每日日志不只是给 Agent 用的,你自己也可以看。cat .openclaw/logs/2026-03-19.md 就能看到今天所有的对话摘要。这是一个天然的工作日报。

技巧 4:为团队项目配置共享记忆。 把 MEMORY.md 提交到 Git 仓库里。团队成员的 Agent 都能读到同样的项目约定。这比口头传达”我们项目用 Vitest 不用 Jest”高效得多。

和其他 Agent 框架的记忆方案对比

OpenClaw 不是唯一做记忆系统的。简单对比:

框架 记忆方案 特点
OpenClaw 双源(MEMORY.md + 日志) 纯文本、人类可编辑、混合搜索
Claude Code 文件记忆(~/.claude/memory/) 结构化文件、MEMORY.md 索引、项目隔离
Cursor 对话摘要 + .cursorrules 无持久化日志,依赖规则文件
AutoGPT 向量数据库(Pinecone/Weaviate) 纯向量,无人类可读层
LangChain Memory ConversationBufferMemory 内存级,进程退出即丢失

OpenClaw 的独特之处在于两层都是人类可读的纯文本。你不需要数据库客户端就能查看和修改 Agent 的全部记忆。这在调试和审计时价值巨大。

AutoGPT 的纯向量方案搜索能力更强,但你无法直接阅读”Agent 到底记住了什么”。LangChain 的内存方案最简单,但不支持跨会话持久化。

局限和未来方向

诚实说,双源记忆系统也有局限。

第一,记忆质量依赖 Agent 的判断。 Agent 决定”什么值得记住”。如果它判断失误——把重要信息忘了,或者把噪音当成知识存下来——记忆库的质量就会下降。目前没有自动清理过时记忆的机制。

第二,向量搜索有成本。 每次 memorySearch 都要调用嵌入模型 API。如果记忆库很大(数百条记录),每次搜索的 Token 消耗不可忽略。

第三,多 Agent 协作场景不够成熟。 当多个 Agent 同时读写同一个 MEMORY.md 时,可能出现冲突。ContextEngine 的 ingest 钩子没有提供锁机制。

社区里讨论最多的下一步是记忆的自动衰减和整理——让 Agent 定期回顾自己的记忆,合并重复项,淘汰过时信息。就像人脑在睡眠时整理白天的记忆一样。

写在最后

记忆是 AI Agent 从”工具”变成”助手”的分水岭。

没有记忆的 Agent,每次对话都是初次见面。有了记忆,它知道你的偏好、你的项目、你昨天做了什么、你上周为什么改变了方案。

OpenClaw 的双源记忆系统不是最复杂的方案,但可能是最务实的——纯文本文件保证了透明和可控,混合搜索保证了检索质量,pre-compaction flush 保证了信息不丢失,ContextEngine 保证了可扩展性。

当你的 Agent 开始记住你的名字、你的代码风格、你昨天犯的那个 bug——你和 AI 的关系就变了。 它不再是一个你每次都需要从头教的工具,而是一个越用越懂你的搭档。

这才是 Agent 时代真正让人兴奋的地方。


你在用 OpenClaw 的记忆系统吗?MEMORY.md 里你都写了什么?你觉得 AI Agent 应该记住你的哪些信息?欢迎在评论区聊聊你的记忆管理经验。