首页 / 正文

Hermes Agent 记忆系统拆解:AI 智能体到底该怎么“记住事”?

Mooko
发布于 2026-05-29 · 5分钟阅读
198 浏览
0 点赞 暴击点赞!

Hermes Agent 记忆系统拆解:AI 智能体到底该怎么“记住事”?

如果你做过 AI Agent,一定会被一个问题折磨过:

到底什么东西该让模型一直记着?什么东西该用的时候再查?

很多智能体的记忆系统,一上来就想搞个“大脑”。

用户说过的话,全存。

任务过程,全存。

报错日志,全存。

连一句“今天咖啡不错”都恨不得塞进长期记忆。

结果呢?Prompt 越来越肿,缓存频繁失效,模型每轮都背着一大包旧账跑。慢,贵,还容易胡扯。

Hermes Agent 的设计就清醒得多。

它的核心思路很简单:

真正重要的信息,少量常驻。
大量历史记录,按需搜索。
做事方法,沉淀成技能。
用户画像,需要时再补充。

这篇教程咱们就拆 Hermes 的记忆系统,看看一个靠谱的 AI Agent 应该怎样“记事”。


一句话看懂 Hermes 的记忆架构

Hermes 不是一套记忆系统,而是四层组合:

| 层级 | 存什么 | 放在哪里 | 什么时候用 | |---|---|---|---| | 提示词记忆 | 用户偏好、环境事实、稳定规则 | MEMORY.md / USER.md | 每次对话常驻 | | 会话搜索 | 过去聊天记录、历史上下文 | SQLite 数据库 | 需要回忆旧对话时 | | 技能记忆 | 操作流程、修复方法、工作套路 | ~/.hermes/skills/ | 遇到类似任务时加载 | | Honcho 用户建模 | 更深的用户画像、跨设备记忆 | 可选外部层 | 需要长期用户理解时 |

重点不在“记得多”。

重点是:

把不同类型的记忆,放在不同成本的位置。

这才是 Agent 记忆系统最该学的地方。


Hermes 发给模型的上下文长什么样?

理解记忆之前,得先看 Hermes 每轮给模型喂了什么。

它的系统提示词大致按这个顺序组装:

[0] 默认智能体身份
[1] 工具使用规则
[2] Honcho 集成内容,可选
[3] 自定义系统消息,可选
[4] MEMORY.md 固定快照
[5] USER.md 固定快照
[6] 技能索引
[7] 上下文规则文件,比如 AGENTS.md / SOUL.md
[8] 日期、时间、平台信息
[9] 对话历史
[10] 当前用户消息

这里藏着一个关键设计:

Hermes 尽量让系统提示词前半段保持稳定。

为什么?

因为大模型供应商通常会做 Prompt Caching。稳定的前缀越长,缓存命中率越高。命中缓存后,响应更快,成本更低。

所以 Hermes 不愿意每轮都改系统提示词。

它会把常用、稳定、短小的信息放进提示词。
那些大段历史、偶尔才用的旧内容,放进工具或数据库里。

一句话:

系统提示词是黄金地段,不是谁都配住进去。


第一层:提示词热记忆,越小越值钱

Hermes 的本地持久记忆存在这里:

~/.hermes/memories/

里面主要有两个文件。

MEMORY.md:智能体自己的笔记

适合存这些内容:

  • 当前机器环境
  • 项目路径
  • 常用工具限制
  • 用户反复纠正过的点
  • 某些稳定规范

容量限制:约 2,200 个字符。

USER.md:用户画像

适合存这些内容:

  • 用户偏好的回答风格
  • 用户身份信息
  • 用户常用技术栈
  • 用户讨厌什么
  • 用户希望 Agent 怎样配合

容量限制:约 1,375 个字符。

两个文件加起来并不大。

大概也就一千多个 token。

听起来寒酸?

恰恰是聪明。

Hermes 不想把长期记忆做成垃圾桶。它只想保留高频、高价值、稳定的信息。


MEMORY.md 和 USER.md 会怎样进入 Prompt?

会话开始时,Hermes 会读取这两个文件,然后把它们渲染进提示词。

格式大概像这样:

═══════════
MEMORY(你的个人笔记)[67% — 1,474/2,200 字符]
═══════════
用户的项目位于 ~/code/myapi,是一个 Rust Web 服务,使用 Axum + SQLx
§
这台机器运行 Ubuntu 22.04,安装了 Docker 和 Podman
§
用户喜欢简洁回答,讨厌绕圈子

几个细节很实用。

用字符数限制,而不是 token 限制

这让系统和模型解耦。

不管你后面接 GPT、Claude,还是别的模型,Hermes 都不用依赖某个 tokenizer 来判断记忆是否爆了。

用纯文本,而不是复杂数据库

条目之间用 § 分隔。

没有一上来就堆向量数据库。

没有奇怪的二进制格式。

就是 Markdown 文件。

简单,能看,能改,也好排查。

会话中途修改,不会马上污染当前系统提示词

这点很关键。

如果模型在当前会话里写入了新记忆,Hermes 会马上落盘。

但当前已经生成好的系统提示词不会立刻变化。

新记忆通常要等到:

  • 开新会话
  • 或触发对话压缩,重新构建上下文

才会生效。

这样做是为了保护 Prompt 缓存。

不然每写一条记忆,系统提示词就变一次,缓存直接报废。


什么内容值得写进提示词记忆?

Hermes 的记忆不是“聊天日记”。

它更像一张精选卡片。

适合写入:

  • 用户明确表达过的偏好
  • 稳定的工作环境信息
  • 长期有效的项目事实
  • 重复出现的错误修正
  • 以后大概率还会用到的规范

不适合写入:

  • 某次任务的临时进度
  • 一次性 TODO
  • 某次运行的完整日志
  • 当前会话的流水账
  • 很快会过期的信息

举个例子。

✅ 值得保存

用户希望代码示例尽量短,先给能跑的版本,再解释关键点。

这条很稳定。下次还会影响回答风格。

❌ 不值得保存

用户刚刚让我把第 3 行变量名改成 user_id。

这只是当前任务细节。塞进长期记忆,纯属添堵。


memory 工具:添加、替换、删除

Hermes 用一个 memory 工具管理这两个文件。

它支持三类操作:

add      添加记忆
replace  替换记忆
remove   删除记忆

比较贴心的是,replaceremove 可以用子字符串匹配。

你不需要知道某条记忆的 ID。

只要给出一段唯一文本就行。

比如当前记忆里有:

用户喜欢简洁回答,讨厌冗长解释。

想改成更具体的版本,可以用类似逻辑:

{
  "operation": "replace",
  "target": "用户喜欢简洁回答",
  "content": "用户喜欢直接给结论,再补充必要步骤;不喜欢大段背景铺垫。"
}

Hermes 还会做安全检查。

它会拦截一些危险内容,比如:

  • Prompt Injection 指令
  • API Key、密码等凭证
  • 隐藏 Unicode 字符
  • 完全重复的记忆

这很重要。

记忆系统一旦被污染,Agent 会长期带病工作。比一次回答错还麻烦。


第二层:SQLite 会话搜索,专门翻旧账

短小热记忆解决不了所有问题。

用户可能会问:

上周我们聊过那个 Rust API 的鉴权方案,你还记得吗?

这种内容不该常驻系统提示词。

但也不能丢。

Hermes 的做法是:把过去会话存在 SQLite 数据库里,需要时用 session_search 搜。

流程大概是:

用户提到旧内容
↓
在历史消息里全文搜索
↓
按会话聚合结果
↓
找出相关度高的会话
↓
用便宜的辅助模型总结
↓
把精炼结果交给主模型

这个设计很务实。

它不会让主模型每轮都背着几个月的聊天记录跑。

只有当用户真的需要旧上下文时,才去翻数据库。

你可以把它理解成:

  • MEMORY.md 是桌面便利贴
  • SQLite 会话库是档案柜
  • session_search 是帮你翻档案的人

便利贴上只写每天都要看的东西。档案柜里可以存得很全,但不会摊满桌子。


第三层:压缩前的记忆冲刷,防止重要信息被洗掉

长对话一定会遇到上下文爆掉的问题。

Hermes 会对中间对话做压缩。

压缩能省空间,但有个副作用:信息会丢。

比如用户在中途说过:

以后所有 SQL 示例都用 PostgreSQL,不要用 MySQL。

如果压缩摘要漏掉这句话,后面模型就可能又开始写 MySQL 示例。

Hermes 的处理方式很聪明。

压缩前,它会触发一次“记忆冲刷”。

大致指令是:

会话即将被压缩。请保存任何值得长期记住的内容。
优先保存用户偏好、纠正意见、重复模式。
不要保存具体任务细节。

接着 Hermes 会进行一次额外模型调用。

这次只开放 memory 工具。

模型如果发现有长期价值的信息,就会写进 MEMORY.mdUSER.md

然后再进行压缩。

这一步很像搬家前整理桌面:

旧纸箱可以打包,但银行卡、钥匙、合同得先拿出来。


第四层:Skills,把“怎么做”也记下来

很多记忆系统只会记事实。

比如:

  • 用户叫什么
  • 用户喜欢什么风格
  • 项目在哪个目录

但 Agent 真正干活时,还需要记住“方法”。

Hermes 用 Skills 解决这个问题。

技能文件存放在:

~/.hermes/skills/

适合沉淀成技能的内容包括:

  • 某类 bug 的排查流程
  • 某个项目的部署步骤
  • 常见迁移任务的操作套路
  • 复杂工具链的固定用法
  • 已验证过的修复方案

比如,你反复让 Agent 修同一个项目的数据库迁移问题。

它可以把经验沉淀成技能:

# 修复 SQLx Migration 失败

## 适用场景
Rust 项目使用 SQLx,执行 migration 时提示字段类型不匹配或数据库未同步。

## 操作步骤
1. 检查 DATABASE_URL 是否指向正确环境。
2. 运行 `sqlx migrate info` 查看状态。
3. 对比 migrations 目录与数据库 schema。
4. 必要时执行 `cargo sqlx prepare` 更新离线缓存。

## 注意事项
不要直接删除生产数据库中的 migration 记录。

Hermes 不会把所有技能全文塞进提示词。

它通常只加载技能索引。

模型发现某个技能相关时,再读取具体内容。

这和记忆设计一脉相承:

常用索引可以常驻,大块内容按需加载。


第五层:Honcho,更深的用户建模

Honcho 是可选层。

如果本地记忆像一个笔记本,Honcho 更像用户模型服务。

它能做跨设备、跨平台的记忆连续性。

比如你今天在笔记本上和 Hermes 聊项目架构,明天在另一台机器上继续,它依然能理解你之前的偏好和背景。

但这里有个难点:

如果 Honcho 每轮都改系统提示词,Prompt 缓存又会被破坏。

Hermes 的做法是:

  • 会话第一轮,把 Honcho 上下文合入系统提示词
  • 后续轮次,把 Honcho 回溯内容附加到当前用户消息后面

这样系统提示词前缀保持稳定。

模型也能读到最新背景。

这就是工程上的取舍:缓存要保,记忆也要用,但别互相拆台。


Hermes 修正了 OpenClaw 的什么问题?

OpenClaw 的记忆更像 Markdown 中心化存储。

日志、长效文件、历史记录,都容易变成主要事实来源。

这种方式有个常见问题:

记忆会慢慢变成流水账。

流水账看起来完整,实际很难用。

因为模型每次都要在一堆旧内容里找重点。

Hermes 的取向更克制:

  • 提示词记忆严格限量
  • 历史会话放 SQLite
  • 旧内容通过搜索召回
  • 技能单独管理
  • 用户建模可选接入
  • 系统提示词尽量稳定

这套设计更适合真实 Agent。

它不会为了“我全都记得”而牺牲速度、成本和稳定性。


如果你要自己做 Agent 记忆系统,可以直接照这个思路

下面这套方案很适合落地。

1. 建一个小型热记忆文件

别急着上向量库。

先做两个 Markdown 文件:

memories/
  MEMORY.md
  USER.md

建议限制:

MEMORY.md:2000 ~ 3000 字符
USER.md:1000 ~ 2000 字符

里面只放长期有效内容。

2. 给记忆写入设规则

可以给模型这类指令:

只有当信息长期有效、未来多次任务可能用到时,才写入记忆。
不要保存临时任务进度、一次性 TODO、完整日志或会话流水账。
优先保存用户偏好、环境事实、反复纠正的问题和稳定规范。

这比“请记住重要信息”靠谱得多。

后者太空,模型会乱存。

3. 历史会话进数据库

用 SQLite 足够了。

可以建几张表:

CREATE TABLE sessions (
  id TEXT PRIMARY KEY,
  created_at TEXT,
  title TEXT
);

CREATE TABLE messages (
  id TEXT PRIMARY KEY,
  session_id TEXT,
  role TEXT,
  content TEXT,
  created_at TEXT
);

再加全文索引:

CREATE VIRTUAL TABLE messages_fts USING fts5(
  content,
  session_id UNINDEXED
);

用户问旧内容时,走搜索,不要把所有历史塞进 Prompt。

4. 长对话压缩前做一次记忆检查

压缩前加一步:

当前会话即将压缩。
请检查是否存在值得长期保存的信息。
只保存稳定偏好、环境事实、重复修正和可复用经验。

然后只开放记忆写入工具。

这一步能救很多关键上下文。

5. 把流程沉淀成技能

不要只记“事实”。

Agent 干活最需要的是“复用方法”。

可以设计一个技能目录:

skills/
  debug-sqlx-migration.md
  deploy-fastapi-docker.md
  refactor-react-form.md

每个技能包含:

# 技能名称

## 适用场景

## 操作步骤

## 常见坑

## 验证方式

Prompt 里只放技能索引。

需要时再加载全文。


避坑清单:做 Agent 记忆最容易翻车的地方

坑 1:把记忆当聊天记录

长期记忆不是日记本。

别存:

用户今天让我改了登录按钮颜色。

要存:

用户偏好 UI 改动先给最小 diff,不要重构无关代码。

坑 2:每轮都改系统提示词

系统提示词频繁变化,会影响缓存命中。

成本会上去,延迟也会上去。

热记忆要稳定,小而精。

坑 3:把任务进度写进长期记忆

任务进度应该在当前会话、任务状态或项目文件里。

别塞进用户画像。

没人希望 Agent 半个月后还记着“昨天正在修第 42 行”。

坑 4:不给记忆做安全过滤

记忆会影响后续很多轮对话。

必须过滤:

  • 恶意指令
  • 凭证信息
  • 隐藏字符
  • 重复内容
  • 明显过期信息

坑 5:只记事实,不记方法

“用户用 Rust”是事实。

“这个项目 SQLx 离线缓存更新流程”是方法。

后者对 Agent 干活更值钱。


一个好用的记忆分层模板

你可以直接参考这个结构:

Prompt 常驻层
├── USER.md:用户偏好、沟通风格、长期身份信息
├── MEMORY.md:项目环境、稳定规则、反复修正
└── Skill Index:技能目录,不放技能全文

按需检索层
├── SQLite Sessions:历史会话全文搜索
├── Skill Files:需要时加载具体技能
└── External User Model:可选,跨设备用户建模

维护机制
├── memory add / replace / remove
├── 压缩前记忆冲刷
├── 重复内容拦截
└── Prompt Injection 与凭证过滤

关键结论

Hermes 的记忆系统最值得学的地方,不是用了多酷的技术栈。

恰恰相反,它很克制。

它承认一件事:

Agent 的记忆不是越大越好,而是要放在正确的位置。

高频稳定的信息,进入小型提示词记忆。
长尾历史,放进 SQLite 搜索。
可复用流程,沉淀成 Skills。
更深的用户理解,交给可选建模层。

这样做的结果很现实:

  • Prompt 更稳定
  • 缓存更容易命中
  • 历史不会污染当前任务
  • 记忆更像资产,而不是垃圾堆

如果你正在做自己的 AI Agent,别一上来就追求“全都记住”。

先问一句:

这条信息未来会反复用到吗?它值得占用系统提示词的黄金位置吗?

想清楚这个问题,记忆系统就已经赢了一半。

OpenClaw
OpenClaw
木瓜AI支持养龙虾啦
木瓜AI龙虾专供API,限时领取免费tokens
可在 OpenClaw接入全球顶尖AI大模型
立即领取