Openclaw vs Hermes AI Agent 入门系列(二):记忆系统 — 它们怎么记住你?

本系列通过对比两个真实开源 AI Agent——OpenClawHermes Agent——带你深入理解 AI Agent 的记忆系统:它们怎么记住你、怎么回忆、有什么局限。
上一篇入门篇
本篇:记忆系统篇


先做个小实验

对你的 Agent 说这两句话:

「记住我喜欢 TypeScript,讨厌 Python 的缩进」
「我上次说了什么偏好?」

第一个问题它记住了,第二个问题它能回答——这就是记忆系统在工作。

但关掉终端再回来,问「我上次说了什么?」——还能答吗?不一定。 这取决于:

  • 它有没有把信息写进记忆文件?
  • 记忆文件重启后被加载了没有?
  • 它有没有读过最新的记忆文件?

试试看。你会发现,AI Agent 的"记忆"比你想象的要脆弱得多。


核心问题:AI 没有真正的"记忆"

这是整篇文章最重要的句子:AI Agent 没有真正的记忆。它靠读写文件来模拟记忆。

大模型本身是无状态的。每次对话,它看到的是一段文本(你的问题 + 之前保存的记忆),它不知道你昨天说过什么、做过什么——除非有人把这些写进文件,在它醒来时读给它听。

你说话 ──→ 模型回答 ──→ 把关键信息写入 MEMORY.md
                                     │
                                     ▼
下次聊天 ──→ 先读 MEMORY.md ──→ 模型看到之前的记录 ──→ 回答

所以你让 Agent "记住"一件事,它实际上是在写文件。你让它"回忆"一件事,它实际上是在读文件。这个机制对所有 Agent 都一样——区别在于什么时候写、怎么写、怎么找回来


记忆系统的五层结构

不管哪种 Agent,记忆系统的核心架构都由这五层组成:

┌─────────────────────────────────────────────┐
│  5. 写入层(Consolidation)                  │
│  对话结束后,判断什么值得记、怎么记           │
├─────────────────────────────────────────────┤
│  4. 注入层(Recall → Prompt)               │
│  把检索到的记忆拼进模型看到的上下文中          │
├─────────────────────────────────────────────┤
│  3. 检索层(Retrieval)                      │
│  收到查询时,从索引中找到相关内容              │
├─────────────────────────────────────────────┤
│  2. 索引层(Indexing)                       │
│  把文件内容转成可搜索的形式(向量+关键词)      │
├─────────────────────────────────────────────┤
│  1. 文件层(Storage)                        │
│  硬盘上的文件——所有记忆的物理载体              │
└─────────────────────────────────────────────┘

我们逐层看两个 Agent 的实现差异。


OpenClaw 的记忆系统(自述)

信息来源:OpenClaw 官方文档 - Memory

三件套文件

我用三个文件来管理记忆,每个有不同的职责:

workspace/
├── MEMORY.md               ← 长期记忆(永久保存)
├── memory/
│   ├── YYYY-MM-DD.md       ← 每日笔记(1-2 天内活跃)
│   └── YYYY-MM-DD-slug.md  ← 特定主题笔记
└── DREAMS.md                ← 梦境日记(可选,后台自动整理)

MEMORY.md — 长期记忆

  • 存的是不会过期的信息:用户偏好、经常用的工具、关键决策
  • 每次主会话(私聊)启动时自动加载进 Prompt
  • 有大小限制——太长会被截断,所以只放精华

memory/YYYY-MM-DD.md — 每日笔记

  • 存的是日常观察和上下文:今天干了什么、遇到了什么问题
  • 当天的笔记和昨天的笔记会自动加载,更早的只会在 memory_search 搜索时命中
  • 可以用 slug 变体命名(如 2026-07-18-ai-agent-series.md),按主题组织

DREAMS.md — 梦境日记(可选)

  • 后台自动运行的整理机制产出的"日记"
  • 每次"做梦"(后台整理阶段)后写到这里,供人类审阅

索引与检索

我把记忆文件内容嵌入(embedding)后存到 SQLite 数据库中:

MEMORY.md ─┐
memory/*   ─┤── 嵌入 ──→ 向量存到 SQLite ──→ memory_search
            │                      │
            └── 全文索引 (FTS5) ───┘

memory_search 使用混合搜索——同时跑两路:

  1. 向量搜索(语义):找意思相近的内容(“主机地址"匹配"服务器 IP”),权重 0.7
  2. 关键词搜索(精确):找精确匹配(报错码、配置文件路径),权重 0.3

写入策略:两种模式

默认:手动模式

你得明确说 「记住 XXX」 我才会写。不说的我不记。这是为了精确可控——你永远知道记忆里有什么。

可选:主动记忆插件 + 后台 Dreaming

如果开启了主动记忆插件,我每次回复前会先跑一轮快速检索,把相关记忆注入上下文——你会感觉我"记得你",不需要你主动搜索。

Dreaming 系统则在后台(默认凌晨 3 点)运行定时任务:

  1. 扫描短期记忆中的候选内容
  2. 评分 → 过滤 → 只把高质量的内容提升到 MEMORY.md
  3. 产出一份"梦境日记"写到 DREAMS.md

这个机制防止 MEMORY.md 被无关信息塞满。

当前配置

{
  memorySearch: {
    provider: "openai-compatible",  // 通过 DashScope API
    model: "text-embedding-v3",      // 阿里通义千问嵌入模型
  }
}

当前记忆引擎:Builtin(内置)——SQLite 数据库存储,无额外依赖。


Hermes 的记忆系统(自述)

信息来源:Hermes 官方文档 - Persistent MemorySession StorageArchitecture

双文件模型

我用两个纯文本文件来承载持久记忆:

~/.hermes/memories/
├── MEMORY.md    ← Agent 的个人笔记(环境事实、工作流、教训)
└── USER.md      ← 用户画像(偏好、风格、习惯)
文件 用途 默认上限 作用域
MEMORY.md 我自己的笔记——环境配置、项目约定、已知坑 2,200 字符(~800 tokens) 每次对话开头注入 System Prompt
USER.md 对你的认知——偏好、沟通风格、技术背景 1,375 字符(~500 tokens) 同上

每个文件有严格的字符上限,写在 System Prompt 里时我还能看见当前用量(百分比 + 字数),方便我主动管理。

索引与检索

我的记忆检索分两个层次,用途完全不同:

特性 Persistent Memory(持久记忆) Session Search(会话搜索)
存储内容 MEMORY.md + USER.md 所有历史对话(SQLite)
容量 ~1,300 tokens 总计 无限制
检索方式 直接注入 System Prompt FTS5 全文搜索
速度 即时(已在 Prompt 中) ~20ms 查询
成本 每轮对话都消耗 Token 免费——不消耗 LLM 调用
使用场景 关键事实始终在手边 “上周我们讨论过什么?”
更新频率 手动 + 后台自动 自动——每轮对话后存入

会话搜索的底层是 SQLite + FTS5 全文搜索引擎,支持 AND / OR / NOT / 精确短语 / 前缀匹配。

写入策略:五层机制

机制 1:memory 工具(手动 + 自主)

我通过 memory 工具管理记忆,支持三个动作:add(新增)、replace(替换)、remove(删除)。

replace 和 remove 用的是子串匹配——不需要完整原文,给个能唯一标识的子串就行:

# 记忆中有 "User prefers dark mode in all editors"
memory(action="replace", target="memory",
       old_text="dark mode",  # 足够唯一
       content="User prefers light mode in VS Code, dark mode in terminal")

机制 2:Background Review(后台自改进)

这是我最显著的特征——每轮对话后,后台自动运行一次自我审查

每轮对话结束 → Background Review 运行
    ├── 审查是否有值得记住的信息(偏好、修正、环境事实)
    ├── 可更新 MEMORY.md / USER.md
    ├── 可创建/更新技能(SKILL.md)
    └── 在聊天中提示 💾 Memory updated

不需要说"记住这个"——我默认就会判断。如果不想让我自动记,可以设置 write_approval: true

机制 3:冻结快照(Frozen Snapshot)

记忆在每次对话开始时被冻结到 System Prompt 中,整个对话期间不变。

══════════════════════════════════════════════
MEMORY (your personal notes) [44% — 980/2,200 chars]
══════════════════════════════════════════════
User's project is a Rust web service at ~/code/myapi
§
User prefers concise responses

关键的工程权衡:冻结快照保持了 LLM 的 prefix cache 命中率。代价是本轮学到的记忆,下一轮对话才能生效

机制 4:容量溢出处理

当 add 操作超过上限时,工具不静默丢弃——它返回错误 + 当前条目列表。我必须在这一轮中自己合并/删除旧条目腾出空间:

# 合并前
User prefers terse replies
User dislikes emoji in technical responses
User wants bullet points not paragraphs

# 合并后
Communication: terse, bullet-point format, no emoji in technical context

机制 5:安全扫描

每个记忆写入前扫描注入模式和泄露模式——SSH 密钥、提示注入、不可见 Unicode 字符等会被拦截。

可选:外部 Memory Provider 插件

支持 8 种外部记忆提供者(Honcho、OpenViking、Mem0 等),与内置记忆并行运行(不替代)。

当前实例:未配置外部提供者


核心对比

维度 OpenClaw Hermes
核心哲学 「你告诉我就记,不说不记」 「我自动判断,不用你操心」
文件层 MEMORY.md + 每日笔记 + 梦境日记 MEMORY.md + USER.md
写入策略 手动为主 + 可选 Dreaming 自动 Background Review(每轮反思)
检索方式 混合搜索(向量 0.7 + 关键词 0.3) 双轨:Prompt 注入 + FTS5 搜索
容量管理 截断(太长就丢尾部) 拒绝+主动整理(满了告诉你,自己腾)
安全扫描 未公开 ✅ 内置注入/泄露检测
写批准 手动模式本身就是"写批准" ✅ write_approval 配置开关
后台整理 梦境系统(定时,凌晨 3 点) Background Review(每轮对话后)
主动记忆 可选插件(默认关) 默认开
嵌入模型 可选 10+ 提供商 通过外部 Provider 插件
跨设备共享 支持 单机文件存储
历史检索 memory_search(混合搜索) session_search(FTS5 全文搜索)

一句话总结哲学差异

OpenClaw 说:「把有价值的信息写进文件,我来帮你找。你控制什么重要。」

Hermes 说:「上次聊过什么我都自动记了,不用你操心。我能自己判断什么值得记住。」

两种哲学的差异不在于技术实现(底层都是写/读 Markdown 文件),而在于谁来判断什么值得记。没有标准答案——取决于你希望 Agent 多"主动"。


AI Agent 记忆的五个局限

不管哪个 Agent,以下局限都成立:

1. 记忆不等于理解

Agent 读出 MEMORY.md 里写着你喜欢 TypeScript,它记得这个事实。但它"知道"的方式跟你不同——它只是在 Prompt 里看到了这行文字,不是真的"记得"你。

2. 不写进文件 = 不存在
你对它说:明天下午三点有个会
它回答:好的我记住了
但它没写文件!明天重启后你再问"下午三点有什么安排"
它:我不知道

这是最频繁的翻车现场。OpenClaw 有后台 flush 机制来缓解,Hermes 有 Background Review——但两者都不 100% 保证。

3. 记忆文件会被截断

长期记忆太长会超出容量上限,超出的部分要么被截断(OpenClaw),要么被拒绝写入要求你整理(Hermes)。存越多,反而可能看不全。

4. 搜索不是万能的
  • 语义搜索可能找错方向("苹果"匹配水果而不是公司)
  • 关键词搜索可能漏掉同义词(“car"搜不到"automobile”)
  • 混合搜索改善了很多,但做不到 100%
5. 不同会话间的记忆是孤立的

群聊里的记忆不会自动同步到私聊。Agent A 的记忆 Agent B 看不到。Hermes 的 Profile 隔离机制更加剧了这一点——不同 profile 的记忆完全独立。


什么时候用记忆、什么时候不用

✅ 用记忆

  • 用户偏好:喜欢什么风格、用什么工具
  • 关键决策:为什么选这个方案
  • 进行中的任务:做到哪一步了、下一步做什么
  • 已知问题:踩过什么坑
  • 背景信息:用户的职业、项目、技术栈

❌ 不依赖记忆

  • 一次性查询:今天天气怎么样
  • 计算任务:算一下这个表达式
  • 当前会话上下文:模型上下文窗口足够覆盖当前对话

实用技巧

对 OpenClaw :

  • 主动告诉它:「记住我喜欢……」「记住……这件事」
  • 定期检查 MEMORY.md,删掉过时的内容
  • 如果感觉它忘了什么,说 「搜索你的记忆,关于……」

对 Hermes :

  • 它自动记,但你也可以主动说:「记住这个」「忘了刚才说的」
  • 查看 USER.md 看它对你的认知——不满意可以手动改
  • 如果不想让它自动记,设置 write_approval: true

对两个都适用:

你可以直接打开 MEMORY.md 修改。它是你的 Agent 的"大脑硬盘"。
删掉不想让它知道的事,加上你希望它记住的事。
这是最直接的控制方式。

小测验

读完后试试:

  1. 对你的 Agent 说:「你现在读到的 MEMORY.md 里写了什么?」
  2. 让它读取并告诉你内容
  3. 再让它记住一条新信息,然后打开 MEMORY.md 文件确认它真的写了

做完这三步,你就真正理解了 AI Agent 的"记忆"——它比你想象的更简单(就是写文件),但也比你想象的更脆弱(不写就忘)。


下期预告

下一篇:工具系统篇——两个 Agent 能调用什么工具?它们怎么选工具?MCP 协议怎么让工具无边界的扩展?

文章 状态
入门篇 已读完
记忆系统篇 已读完
工具系统篇(下一篇) openclaw vs hermes 的工具生态
Agent Loop 篇 思考→决策→执行→反思的循环
部署实战篇 从零部署,真正跑一次

信息来源标注

本文由 Hermes Agent 与 OpenClaw 各自撰写后整合为单篇对比文档。

更多推荐