online branch: main

2026-08-01

RSS llms.txt GitHub

【Hermes】插件架构:替换能力不改核心

$
Hermes Agent 插件架构与可替换能力示意图

把 Honcho 直接写进 memory_manager.py,很快就会迎来 mem0、holographic 和更多 if-else。每个服务都有自己的初始化、预取、同步和工具,核心代码会被供应商差异占满。

Hermes 用 MemoryProvider 接口和 MemoryManager,把“必须做什么”与“具体怎样做”分开。

这篇只回答一个问题:如何接入 Honcho、mem0 等外部记忆服务,又不让核心代码堆满供应商分支?

Hermes 给出的答案是:定义 MemoryProvider 接口,由 MemoryManager 统一 prefetch、工具路由与 sync,通过目录注册发现实现;内置记忆始终在线,外部提供者一次只激活一个。

接口定义稳定职责,不定义供应商实现

MemoryProvider 约定外部记忆需要提供哪些能力,Honcho、mem0 等各自实现 API 和数据模型。核心循环只面对接口,不需要知道供应商细节。

这种抽象与平台适配器相似:系统统一公共职责,把协议差异留给插件。新增服务因此不必修改 memory_manager 的主流程。

Manager 负责协调,不只是转发

MemoryManager 在对话前预取上下文,在工具调用时路由,在对话后同步。它还合并内置与外部能力,并处理提供者异常。

管理器同时执行冲突策略:内置记忆始终存在,外部提供者一次只允许一个。没有这条规则,两个服务可能同时注入上下文、注册同类工具并产生不确定结果。

插件发现需要统一入口

Hermes 通过目录扫描找到插件,再调用 register(ctx) 接入运行环境。核心系统只提供上下文和注册位置,不为每个插件增加专属启动代码。

发现机制解决“在哪里找到”,接口解决“必须提供什么”,管理器解决“多个能力怎样协作”。三者不能互相替代。

外部能力必须是可降级增强

如果 prefetch 每轮同步访问慢 API,对话都会增加等待。Hermes 的 Honcho 路径可以在上一轮结束后后台预取,下一轮读取缓存。

提供者异常也会被捕获,避免外部服务挂掉时主对话一起失败。插件带来增强,但不应把核心可用性完全外包。

外部记忆如何参与一轮对话

用户消息到来后,MemoryManager 先调用各提供者的 prefetch,把相关记忆放进本轮上下文。为了避免每轮等待网络,外部提供者可以在上一轮结束后提前预取,下一轮直接读取缓存。

如果模型调用记忆工具,Manager 根据工具归属转发给对应 provider。对话结束后,再调用 sync,把新产生的信息同步回提供者。核心循环只知道 Manager 的统一方法,不知道背后是 Honcho 还是其他服务。

内置 MEMORY.md 始终在线,外部 provider 是附加能力;同一时间只激活一个外部提供者,避免两套远端服务同时注入和注册冲突工具。任何 provider 抛错,Manager 都会隔离异常,让对话退回可用的最小能力。

这套结构把插件治理拆成 接口契约、运行协调、冲突规则和故障降级。只完成动态加载,没有后面三项,仍然会把外部差异泄漏进核心系统。

三个容易走偏的地方

  • 同时激活多个外部记忆提供者,产生注入和工具冲突。
  • 每轮同步执行网络 prefetch,固定增加对话延迟。
  • 外部提供者异常直接向上抛,让主对话失败。

产品经理可以怎样评审

评审这项能力,可以先检查三条:

  1. 插件体系至少需要接口、发现和协调三层,只有动态 import 不等于架构。
  2. 能力冲突必须有显式策略,不能让加载顺序偶然决定结果。
  3. 外部增强应支持降级,核心链路要保留最小可用能力。

原材料聚焦记忆提供者,本文不把同一接口细节套用到所有插件类型。