记忆插件搬出核心之后:升级时它自己装回来了


早上你跑完 hermes update,重启 agent,随口问了句「昨天那个重构做到哪了」。它安静了两秒,回你一句「我没有关于这件事的任何记录」。你打开 config.yaml —— memory.provider: honcho 明明还在,memory.honcho 那一整段配置也一条没少。唯一没了的是代码:provider 已经搬出核心仓库了,而你的升级只换了核心那一半。

这不是数据丢了,是「配置还在、实现不在了」这种最难排查的中间态。PR #114569(2026 年 9 月 18 日合入 main)就是为这个中间态准备的:它让 Hermes 在升级时、以及在 agent 启动时,发现自己配置的记忆 provider 不在本地了,就按插件目录里审核过的版本把它装回来。这篇讲清楚它怎么判断、装的时候走哪条路、装不上会怎样,以及你现在要不要做什么。

先说不变的部分:名字、配置、数据都留着

这次迁移最让人安心的设计是只换代码住址,不动其它任何东西。一个原本内置的 plugins/memory/<name> 变成独立插件之后:

  • provider 名字不变(配置里还是 memory.provider: honcho);
  • 配置段落不变(memory.<name> 下那一堆键值原样保留);
  • 数据目录不变(你积累的记忆还在原来的位置);
  • 工具名不变(agent 记忆里那些「怎么用记忆」的说明不用重学)。

变化只有一条:代码从核心树里搬到了 HERMES_HOME/plugins/<name>。所以整件事被你察觉的方式,本该只是一次安静的重新安装 —— 而这次 PR 就是补齐「本该」。

两个钩子:hermes update 与 agent 启动

新模块 hermes_cli/memory_provider_migration.py 里的 migrate_home() 是唯一的执行入口。它做三件事:读出这台 home 的 memory.provider;检查这个名字在 Hermes 所有查找路径里还存不存在(内置目录、该 home 的用户插件目录、entry point);如果哪都找不到,就去插件目录里查有没有同名条目。三个条件都命中,才走安装。

调用它的地方有两处,覆盖两种升级习惯:

  • hermes update:升级流程里,对共享同一个虚拟环境的每个 profile home 都跑一次。选在这里是因为升级本来就要重建依赖,顺手把插件依赖按核心的版本约束再装一遍;
  • agent 启动:当 load_memory_provider 返回 None(即 provider 根本加载不起来)时补一次,每个进程、每个名字只尝试一次。这一条是给桌面版用户的 —— 他们通过 App 更新,从来不手动跑 hermes update。

安装走的是普通插件安装路径:目录条目审核过的版本号、kill list 校验、依赖约束、安装后启用。换句话说,它不会因为「自动」就绕开安全审查去拉一个自定义源。

还有一个开关要注意:因为这一步在装代码,它受 security.allow_lazy_installs 约束(默认开启)。如果你出于安全考虑把它关掉了,自动迁移就不会发生 —— 日志里会写清楚原因,而不是静静地把记忆功能留在宕机状态。

装不上会怎样:一句明确的命令,而不是静默失忆

这是这次改动里最值得学的工程习惯:失败要能被看见,而且能立刻被处理。

三种失败路径各自有明确输出:

情况 行为
插件目录里没有这个 provider 打印一条警告,给出准确的 hermes plugins install <source>,或建议改 memory.provider
目录里有、安装失败(网络、uv、kill list) 打印安装返回的错误原文,并给出同一条命令
security.allow_lazy_installs 被关掉 写日志说明是配置导致没有自动安装

而在此之前的真实体验是:只在 DEBUG 级别留一行,正常日志里什么都看不到 —— 用户看到的现象就是「agent 突然什么都不记得了」。同一个函数里还有一条很克制的约定:它永远不会抛异常。注释写得很直白:记忆功能坏掉,不该把升级或者 agent 一起带下去。

顺手修好的安装语法:owner/repo#subdir

这次还改了一个小但很实用的问题:hermes plugins install owner/repo#subdir 现在能正确解析了。之前 # 会被粘进 clone URL 里,导致装在子目录里的插件装不上。

这个语法不是纸上需求:Honcho 的插件就放在主仓库的子目录里,迁移后的标准来源是 plastic-labs/honcho#hermes-plugin-honcho,supermemory 则是 supermemoryai/hermes-supermemory。PR 里做的是真机验证 —— 把内置的 honcho/supermemory 从探针 checkout 里删掉、配置 memory.provider: honcho、再跑真实的 AIAgent():它按目录里的版本装好了 plugins/honcho,依赖(honcho-ai、httpx)在核心的版本约束内装上,加载成功;桌面版的 honcho 配置面板照旧渲染出 33 个字段,hermes honcho 命令也照旧可用;第二次启动则是一次 no-op,不会重复安装。

现在要做什么:三步自查

这次 PR 是铺垫,它没有从核心删掉任何东西。但这套机制真正的价值会在接下来几个月显现 —— 官方已经把内置记忆 provider 的迁移方向公开了(和 Hindsight、Honcho、Supermemory 的维护者讨论过)。所以现在花五分钟把状态摸清楚是值得的:

  1. 看你用的是哪个 provider:hermes config get memory.provider。如果是内置的那几个(honcho / supermemory / mem0 等),记下这个名字。
  2. 看一眼本地插件列表里它是内置的还是独立插件:hermes plugins list。以后升级完,如果它显示为从维护者仓库安装的版本,说明迁移已经发生,属正常现象。
  3. 万一某次升级后 agent 突然「失忆」,先按日志里的那条 hermes plugins install 命令处理;确认记忆恢复后,再检查 hermes doctor,看 WAL 与状态库是否健康 —— 这类问题我们之前在 诊断大 WAL 的那篇里讲过。

想先了解插件目录本身的工作方式,可以看插件目录指南和 hermes plugins 命令参考;用 Honcho 做会话/工作区路由的读者,那篇路由指南里的配置在迁移后依然适用。

什么时候能用上

这组提交 9 月 18 日合入 main,而当前最新的 tag 是 v0.21.3(tag 名 v2026.9.14,9 月 14 日发布),所以它还没进正式 tag。跑 hermes update 从 git 安装的用户已经在用了;只用 Docker 镜像或云端的用户,要等下一个 tag。看看你现在是什么版本:

hermes --version
hermes update

顺带说一句,v0.21.3 的发布说明里提到过,这一大段窗口(v0.21.0 之后)的完整精选说明会随 v0.22.0 一起发。记忆 provider 的搬迁,大概率就是那批说明里需要重点读的一段。

小结

这件事的教训不在「自动安装」本身,而在它暴露的一类故障:当一份配置引用的实现被搬到别处,用户看到的不是报错,而是能力静默消失。修法有三条值得记住:把「找不到实现」当成一等状态去检测;自动修复走已经审核过的正常路径,而不是抄近路;修不了就给出一条能照着敲的命令,并保证这段代码永远不会把升级或者 agent 拖垮。