第4篇:持久记忆——AI 的长期记忆
Hermes 功能详解第4篇:持久记忆。AI 跨对话记住你的偏好、环境与习惯,越用越懂你。
第4篇:持久记忆——AI 的长期记忆
嘿,朋友们!👋 今天咱们来聊聊 Hermes 的“升级”和“卸载”那些事儿。别急着划走,这可不是枯燥的技术文档,而是让你的 AI 助手“越用越聪明”的秘诀!
一键升级,就是这么简单
还记得我们之前说的吗?Hermes 就像你的私人助理,但它也需要不断“充电学习”。升级只需要一条命令:
hermes update
这条命令会帮你搞定所有事情:拉取最新代码、更新依赖、还会自动检测新配置并提示你设置。是不是很贴心?
💡 小贴士:如果升级时不小心跳过了配置提示,别慌!运行
hermes config check查看缺失项,再用hermes config migrate手动补上就行。
升级时发生了什么?
你可能会好奇,升级背后到底做了什么?其实就像给房子装修,Hermes 会:
- 先拍张“全家福” 📸 —— 自动保存当前状态(包括配对数据、定时任务、配置文件等),万一出问题还能恢复
- 拉取新代码 —— 从
main分支获取最新版本 - 语法体检 —— 检查关键文件能否正常解析,有问题就自动回滚,保证你的终端永远能用
- 安装新依赖 —— 就像给房子添置新家具
- 配置迁移 —— 发现新选项会主动问你
- 重启服务 —— 让新代码立即生效,不用手动重启
进阶玩法:自定义分支
如果你是个“折腾党”,想试试测试版功能,可以用:
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 仓库、一个项目目录、一台服务器),它回答“好的,我记住了”,结果新会话完全不知道你在说什么。按下面的顺序排查——第一条就能解释绝大多数情况。
-
先确认写入到底有没有发生。 记忆只有在模型调用
memory工具时才会持久化;一句“我已经把它加进记忆了”只是文本而已。打开文件看看条目在不在:cat ~/.hermes/memories/MEMORY.md cat ~/.hermes/memories/USER.md如果事实不在里面,那就是模型声称保存了、实际根本没写。小参数本地模型(大约 30B 以下)和工具调用能力弱的模型经常这样——它们会给出确认,却没有真正发起工具调用。明确要求它(“用
memory工具保存仓库路径/srv/vault”),并确认条目真的落到了文件里。如果一直这样,解决办法是换一个更强的模型来做设置,而不是加更多指令;条目一旦存在,小模型读起来完全没问题,因为它们会随系统提示一起送达。 -
确认写入没有被暂存。 当
write_approval: true时,交互式 CLI 之外的写入会被挂起等待审核,在批准之前永远不会落到文件里——运行/memory pending和/memory approve all。参见控制记忆写入。 -
确认你读的和写的是同一份记忆。 记忆是按 profile 隔离的:
hermes -p work(或work chat/work gateway start)读的是~/.hermes/profiles/work/memories/,而不是~/.hermes/memories/。默认 profile 里的 CLI 会话和另一个 profile 上的 Telegram 机器人不共享笔记。hermes profile list可以看有哪些 profile。 -
确认记忆是开启的。
memory.memory_enabled: false(或agent.disabled_toolsets里的memory)会直接移除这个工具——模型不管说什么都存不了东西。参见配置。 -
记住快照在会话开始时就被冻结了。 当前会话保存的事实对下一个会话可见,对另一个已经在运行的会话不可见。写入之后开个新会话(
/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