我用了大半年的 OpenClaw,最终迁到了 Hermes Agent。原因很简单:我不敢再信任它记住的东西了。

Reddit 和 Discord 上到处是类似的吐槽:聊了五分钟忘了上下文,中间做的架构决策突然蒸发,感觉像是内存不够用了。我以为是配置问题,折腾了 LCM 插件、调 memoryFlush 参数、换不同模型,折腾了两个星期,没解决。

后来读了 Hermes 源码,又回头看了 OpenClaw 的架构。才明白这是设计层面的差异,不是调参能救的。

先说前提:LLM 没有记忆

所有 LLM 都是无状态的。每次 API 调用,模型从空白开始,看到的只有你塞给它的 token。所谓”记忆”,全是 agent 框架在调用之间拼装的。

所以 agent 的记忆好不好,完全取决于它怎么管理和注入上下文。Google 2025 年底发的那篇 Context Engineering 白皮书把这个事说得很透:context window 里要塞六样东西——系统指令、对话历史、工具定义、长期记忆、RAG 检索结果、输出格式约束。怎么塞、塞多少、什么时候丢,这就是”context engineering”这个词的含义。

OpenClaw 的三层记忆,为什么还是会丢

OpenClaw 的记忆结构其实不差:MEMORY.md 做长期记忆,Session JSONL 存完整对话,SQLite(向量 + FTS5)做混合检索。三层,看上去够用了。

但问题出在压缩环节。

对话超过 context window 时,OpenClaw 的默认行为是把旧消息总结后删除原文。这个”总结”是有损的——你花半小时讨论的安全架构方案,里面包含的决策、推理过程、边界条件,会被压缩成”讨论了安全架构”一行字。Google 白皮书里把这种策略叫 recursive summarization,承认它保真度最低、成本最高。

ResonateOS 团队还发现过一个更隐蔽的 bug:4 个格式化函数在检索流水线中逐层剥离内容。数据库里存着完整的记忆,但 AI 实际看到的是被剥了四层之后的残片。

还有冷启动问题。每次新 session 开始,AI 只能看到 MEMORY.md 里的内容和当前 context window。之前的对话需要通过检索才能访问,而检索本身就有召回率的问题——你确定它存了,但你不一定能在需要的时候捞出来。

Hermes 怎么做的

Hermes 的思路是:不同类型的记忆用不同的时间尺度和持久化策略,别把所有东西扔进同一个管道。

冻结快照

Session 开始时,Hermes 把 MEMORY.md 和 USER.md 读进来,生成一个冻结快照,直接注入 system prompt。整个 session 期间这个快照不变。

这不是什么花哨的设计,但解决了一个实际问题:Anthropic 的 prefix cache 能命中(system prompt 不变就不用重算 attention),而且你的核心记忆永远不会被压缩挤掉。

OpenClaw 的 memory 在 context 溢出时会被压缩。Hermes 把最重要的记忆放在了永远不会被压缩的位置。就这一个区别,实际体验差异很大。

五阶段压缩:渐进丢失,不是一刀切

这部分我反复看了好几遍。

Phase 1: 工具输出裁剪(纯规则,不花 token)
    ├─ MD5 去重,保留最新
    ├─ 20+ 种工具的定制化一行摘要
    └─ 过长参数截断
         ↓
Phase 2: 边界确定
    ├─ 头部保护:前 3 条消息不动(系统提示 + 初始设定)
    └─ 尾部保护:最近对话不压缩
         ↓
Phase 3: LLM 结构化摘要(用便宜模型)
    ├─ 累积更新(多次压缩不是从零开始)
    └─ 结构化模板(Goal / Active State / Key Decisions / ...)
         ↓
Phase 4: 消息组装(角色冲突检测)
         ↓
Phase 5: 工具配对修复(孤立结果删除、缺失结果补 stub)

关键在”累积更新”:多次压缩时,_previous_summary 被传入 LLM,新信息追加到旧摘要上。即使你聊了 200 轮、压缩了 10 次,早期的关键决策仍然在摘要里。信息是渐进丢失的,像老照片慢慢褪色,而不是被一把火烧掉。

触发条件也很克制:50% 上下文窗口占用时触发,还有反抖动——连续两次压缩节省不到 10% 就停下来,提示你开新会话。

对比 OpenClaw 的做法:总结后删除原文。遇到 context 溢出,要么截断,要么报错。你的对话像一段被剪掉尾巴的录像,后面全没了。

SQLite + FTS5:正经的持久化

Hermes 把每一条对话都写进 SQLite。带事务,带全文搜索,正经的关系型数据库。

sessions (id, source, model, parent_session_id, message_count, ...)
messages (id, session_id, role, content, tool_calls, timestamp)
messages_fts USING fts5(content, content=messages, content_rowid=id)

session_search 工具让模型自己翻旧账。当你说”我们之前讨论过什么什么”,它会搜索所有过去的 session,生成摘要后注入当前上下文。用的时候能回忆起来,不用的时候不占空间。

压缩后在 SQLite 里创建子 session,通过 parent_session_id 链回原 session。跨 session 也能追溯到完整对话链。

技能按需加载

Hermes 的 Skills 系统在 system prompt 里只放一个索引:技能名 + 一句话描述。需要用到某个技能时,才通过 skill_view 加载完整内容。

不用把所有参考书都摊在桌上。一个书单就够了,用到哪本翻哪本。

Google 白皮书里管这个叫 Memory-as-a-Tool 模式。让 agent 自己决定什么时候该读记忆、什么时候该存记忆,而不是无脑把所有东西都塞进 context window。

System prompt 分层组装

身份层    SOUL.md — 人格
记忆层    MEMORY.md + USER.md — 冻结快照
技能索引  所有技能名+描述 — 按需加载
项目上下文 .hermes.md / AGENTS.md — 工作目录级别
元信息    当前时间、session ID
平台提示  针对微信/Telegram/CLI 的格式化建议

每一层独立更新,互不影响。

错误处理:偏执级别的防御

这部分不属于记忆系统,但直接关系到”会不会丢数据”。

Hermes 把 API 错误分了七级——从 Provider 特殊模式到 HTTP 状态码到错误码到消息关键词,最后一层是”我也不知道什么错,但先退避重试试看”。大部分框架做到第二层就完了。

几个值得说的细节:

429 Rate Limit 时用抖动指数退避(5s 到 120s 随机),避开固定间隔。402 余额不足时标记 Key 为 exhausted,自动冷却恢复。context_length_exceeded 时先压缩再重试,不直接报错。空响应立即 fallback 到下一个 provider,不傻等。

还有凭证池轮转——准备一池子 API Key,这个用完换那个,用完的等冷却自动恢复。对于 24/7 运行的服务来说是刚需。

最后是 Grace Call:预算快用完的时候,给模型最后一次机会,让它说一声当前进度、哪些做了哪些没做完。

llm-wiki:补上长期知识这一块

Hermes 没有内置 wiki,但这反而是个优势——它可以直接读写磁盘上的文件。

Karpathy 2026 年 4 月提出了 llm-wiki 模式。核心思路很简单:不要每次都从原始文档重新提取知识(那是 RAG 的做法),让 LLM 持续维护一个增量更新的 wiki。

三层结构:

  • raw/ — 原始资料,LLM 只读不写
  • wiki/ — LLM 生成和维护的 Markdown 文件,互相链接
  • Schema 文件(AGENTS.md)— 告诉 LLM 这个 wiki 怎么组织

在个人规模下(几百篇文章),根本不需要向量数据库。LLM 先读 index.md(几千 token),定位到相关页面,再深入阅读。Karpathy 自己说:“Obsidian 是 IDE,LLM 是程序员,wiki 是代码库。”

我用这个 wiki 维护了公理系统、投资框架、技术笔记。Hermes 需要的时候直接读文件,不需要的时候不占 context。

对比

几个关键差异:

核心记忆的位置。OpenClaw 的 MEMORY.md 在 context 溢出时可能被压缩。Hermes 的冻结快照永远在 system prompt 里,不会被挤掉。

压缩策略。OpenClaw 总结后删除原文。Hermes 保护头尾、只压中间,累积摘要,还保留了子 session 链接。

长期知识。OpenClaw 依赖检索管线质量(而且管线本身有 bug)。Hermes 直接读写文件,每一步都能打开查看。

可调试性。OpenClaw 的检索管线是个黑盒,出了问题很难排查。Hermes 每一步都是文件操作,出问题打开文件看就行。

知识复利。RAG 每次从原始文档重新提取。llm-wiki 增量更新,编译一次持续维护。

运行时稳定性。OpenClaw 一个 Key 用完了就死了。Hermes 凭证池轮转 + 七级错误分类 + 空响应立即 fallback。对于 24/7 运行来说,这是”能用”和”敢用”的区别。

我现在的配置

  • Hermes Agent 24/7 跑在服务器上,Telegram + 微信双通道
  • llm-wiki 在 Obsidian vault 里维护结构化知识
  • MEMORY.md 控制在 2000 字以内,只放跨 session 有用的核心事实
  • 把重复操作固化为 Skills(日报生成、博客部署之类)

从 OpenClaw 迁过来最大的感受:它的记忆架构让我不敢信任它记住的东西。一个你不敢信任其记忆的助手,用起来永远在反复确认和重复说明。

Hermes 的方案谈不上多复杂——冻结快照、分层压缩、文件直读、FTS5 搜索,都是工程上扎实的方案。但因为它每一步都可以被打开查看、被 git 追踪、被直接编辑,你才敢把重要的事情交给它。

我后来想明白了这件事:agent 的记忆系统和你选什么模型一样重要。模型决定了它能多聪明,记忆架构决定了你能多信任它。一个够聪明但不稳定的助手,和一个没那么聪明但靠谱的助手,在长期使用中后者更有用。