🤖HermesBlog
Hermes 功能详解 · 第4篇2026/8/9· Easy Understand Hermes Agent

第4篇:持久记忆——AI 的长期记忆

Hermes 功能详解第4篇:持久记忆。AI 跨对话记住你的偏好、环境与习惯,越用越懂你。

持久记忆:两张小抄

第4篇:持久记忆——AI 的长期记忆

嘿,朋友们!👋 今天咱们来聊聊 Hermes 的“升级”和“卸载”那些事儿。别急着划走,这可不是枯燥的技术文档,而是让你的 AI 助手“越用越聪明”的秘诀!

一键升级,就是这么简单

还记得我们之前说的吗?Hermes 就像你的私人助理,但它也需要不断“充电学习”。升级只需要一条命令:

hermes update

这条命令会帮你搞定所有事情:拉取最新代码、更新依赖、还会自动检测新配置并提示你设置。是不是很贴心?

💡 小贴士:如果升级时不小心跳过了配置提示,别慌!运行 hermes config check 查看缺失项,再用 hermes config migrate 手动补上就行。

升级时发生了什么?

你可能会好奇,升级背后到底做了什么?其实就像给房子装修,Hermes 会:

  1. 先拍张“全家福” 📸 —— 自动保存当前状态(包括配对数据、定时任务、配置文件等),万一出问题还能恢复
  2. 拉取新代码 —— 从 main 分支获取最新版本
  3. 语法体检 —— 检查关键文件能否正常解析,有问题就自动回滚,保证你的终端永远能用
  4. 安装新依赖 —— 就像给房子添置新家具
  5. 配置迁移 —— 发现新选项会主动问你
  6. 重启服务 —— 让新代码立即生效,不用手动重启

进阶玩法:自定义分支

如果你是个“折腾党”,想试试测试版功能,可以用:

hermes update --branch release-candidate

这样就能体验最新特性啦!不过要提醒的是,测试版可能会有小bug,适合喜欢尝鲜的朋友。

特殊情况处理

  • 工作区有未提交的修改?Hermes 会礼貌地“罢工”,告诉你先处理完再升级
  • 不小心停在某个分支上?Hermes 会自动切回 main 分支,你的代码改动都会保留

一个 Hermes 家目录只跑一个 agent

别让两个 agent 进程共用同一个 Hermes 家目录。记忆写入是自动的,而且会在会话开始时加载回系统提示里,两个写入者共用一个家目录,会把彼此的条目叠加成谁都没写过的状态。记忆本来就是按 profile 隔离的——第二个 agent 给它自己的 profile;如果它们需要共享记忆,就用外部记忆提供方(external memory provider)。

想要更深的记忆?试试外部记忆提供方

MEMORY.md 和 USER.md 这两张小抄够用,但如果你想让它记住更多、更持久的东西,Hermes 内置了 2 个外部记忆提供方插件——RetainDB 和 ByteRover;插件目录(plugin catalog)里还有更多可选,比如 Honcho、Hindsight、Supermemory、Mem0、OpenViking、Holographic,一条命令就能装上:

hermes plugins install <name>

把 <name> 换成上面某个插件的名字就行。适合记忆量大、或者想让多个 agent 共享记忆的场景。

记忆需要“会话边界”

整套记忆系统其实是围绕会话结束那一刻设计的:MEMORY.md 和 USER.md 把要点带进下一个会话,session_search 在旧上下文消失后补上缺口。在单个会话内部,这套机制基本没机会跑——重要信息都还在实时上下文里,agent 很少去查 session_search,更多是在压缩记忆条目而不是整理它们。

这在消息平台(Telegram、Discord 等)上尤其明显:一个聊天是刻意保持的一个连续会话,能扛过重启、网关崩溃和机器重启。晚上关机不会结束会话——下一条消息会从上次停下的地方接着来。如果你一直不重置,一个聊天可以跑好几周都算一个会话:方便是方便,但会越来越贵(压缩反复在越来越长的历史上跑),而且“遗忘 → 从记忆里回忆 → 搜索过往会话”这个学习闭环几乎没机会触发。新写入的记忆条目也因为前面说的冻结快照,对正在运行的会话不可见。

做法:在自然的边界上运行 /new——任务做完、话题切换、一天开始时。每个边界都是记忆发挥作用的时候:agent 重新读取更新后的 MEMORY.md/USER.md 快照,从便宜的短上下文起步,真正需要历史时再去用 session_search。在 CLI 上这基本是自动的(每次调用都是新会话);在网关上,这个边界得你自己来划。

我说了让它记住,下个会话它却忘了?

这是最常见的反馈:你告诉 agent 某个东西放在哪(一个 Obsidian 仓库、一个项目目录、一台服务器),它回答“好的,我记住了”,结果新会话完全不知道你在说什么。按下面的顺序排查——第一条就能解释绝大多数情况。

  1. 先确认写入到底有没有发生。 记忆只有在模型调用 memory 工具时才会持久化;一句“我已经把它加进记忆了”只是文本而已。打开文件看看条目在不在:

    cat ~/.hermes/memories/MEMORY.md
    cat ~/.hermes/memories/USER.md

    如果事实不在里面,那就是模型声称保存了、实际根本没写。小参数本地模型(大约 30B 以下)和工具调用能力弱的模型经常这样——它们会给出确认,却没有真正发起工具调用。明确要求它(“用 memory 工具保存仓库路径 /srv/vault”),并确认条目真的落到了文件里。如果一直这样,解决办法是换一个更强的模型来做设置,而不是加更多指令;条目一旦存在,小模型读起来完全没问题,因为它们会随系统提示一起送达。

  2. 确认写入没有被暂存。 当 write_approval: true 时,交互式 CLI 之外的写入会被挂起等待审核,在批准之前永远不会落到文件里——运行 /memory pending 和 /memory approve all。参见控制记忆写入。

  3. 确认你读的和写的是同一份记忆。 记忆是按 profile 隔离的:hermes -p work(或 work chat / work gateway start)读的是 ~/.hermes/profiles/work/memories/,而不是 ~/.hermes/memories/。默认 profile 里的 CLI 会话和另一个 profile 上的 Telegram 机器人不共享笔记。hermes profile list 可以看有哪些 profile。

  4. 确认记忆是开启的。 memory.memory_enabled: false(或 agent.disabled_toolsets 里的 memory)会直接移除这个工具——模型不管说什么都存不了东西。参见配置。

  5. 记住快照在会话开始时就被冻结了。 当前会话保存的事实对下一个会话可见,对另一个已经在运行的会话不可见。写入之后开个新会话(/new,或重新调用一次 CLI)。

有两样东西不会让 agent 记住:.env 里的变量(那些是凭据和设置,不是记忆),以及随口提到、没要求保存的事实。对于某个在重复任务里每次都要用到的位置,技能(skill)往往比记忆条目更合适——它只在相关时加载,也不占用那 2,200 字符的预算。

记忆满了怎么办?

记忆有严格的字符上限,写满了不会自动压缩。当你添加的条目会超限时,工具会直接报错,比如:

{
  "success": false,
  "error": "Memory at 2,100/2,200 chars; adding this entry (250 chars) would exceed the limit by 153 chars. Retry as ONE 'operations' batch that removes or shortens (replace) stale entries from current_entries below to free at least 153 chars AND adds this entry — the limit is checked only on the batch result.",
  "current_entries": ["..."],
  "usage": "2,100/2,200"
}

接着 agent 会重新发一个 operations 批次:先腾出错误里说的那么多字符(删掉,或者用 patch 把条目改短),再加上新条目——上限只在批次的最终结果上检查。如果 patch/remove 的 old_text 匹配不到任何条目,也会以同样的方式失败,并在 closest_entries 里列出最像的几条。注意 patch 同样受上限约束:把条目改长也可能溢出,所以新文本必须缩短(或者删掉另一条)才放得下。

每次工具调用都要带一个顶层 target:"memory" 表示 agent 笔记,"user" 表示用户画像。一个批次里所有操作共用这个 target:

{"target": "user", "operations": [{"action": "add", "content": "User prefers metric units"}]}

缺少 target、target 为 null,或者某个操作里的 target 和顶层不一致,都会在写入或暂存审批之前直接报错。改好 payload 再重试;要同时更新两个存储,就分开发起调用。

最佳实践:当记忆用量超过 80%(系统提示头部能看到)时,先合并再新增。比如把三条零散的“项目用了 X”合并成一条完整的项目描述。

外部记忆的召回体积

外部记忆提供方默认会返回完整的预取上下文,安全上限是 hooks.output_spill.max_chars 的 10 倍(至少 100,000 字符);超过这个量仍然会溢出,免得某个失控的提供方把上下文窗口撑爆。

memory.prefetch_spill_enabled: true 可以让当前 profile 把超大召回替换成头尾预览加一个文件路径。这能减少重放的上下文,但按相关性排序的中间部分就不再对模型立即可见了。如果提供方自己有召回预算,优先用它的。

这个开关复用共享的 hooks.output_spill 阈值、预览长度和目录;hooks.output_spill.enabled: false 依然会把它关掉。普通插件钩子默认继续溢出,和记忆这个开关互不影响。设置是在提供方注册时捕获的:改完要重启 Hermes。配置细节见超大预取结果。

卸载:好聚好散

虽然舍不得,但如果你确实想卸载 Hermes,直接删除安装目录和 ~/.hermes 配置文件夹就行。不过说真的,用了这么久,你确定舍得吗?😉

写在最后

升级就像给 AI 助手“换新装”,让它越来越懂你。记住,定期升级才能享受最新功能和安全修复。下次遇到问题,先试试 hermes update,说不定就解决了呢!

有什么问题随时在评论区留言,咱们下期见!👋

📖 官方文档

本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/features/memory