Hermes 101|08|Extensions
Extensions 让 Agent 不必把所有能力写进核心。插件、MCP、平台和 provider 共同构成可扩展边界。
一个 Agent 框架如果把所有能力都写进核心,很快会变得臃肿。今天加 GitHub,明天加 Slack,后天加内部数据库,再后来要支持新的模型 provider、新的 memory backend、新的上下文管理策略。核心代码越大,升级越慢,风险也越高。
Hermes 的做法是把核心运行时和外部能力分开:Agent Loop、Session、Tool Runtime、Context Builder 保持相对稳定;外部能力通过 Extensions 接入。
这里的 Extensions 不是单一机制,而是一组扩展边界:plugins、MCP servers、provider plugins、gateway platforms、hooks、skills 等。

读完本文,你应该能回答
- 为什么 Agent 不应该把所有能力写进核心?
- 插件、MCP、provider、平台入口分别扩展什么?
- 显式启用扩展解决了哪些安全和可维护性问题?
- mini-agent-harness 应该怎样设计扩展点而不失控?
本篇在系列中的位置
上一篇讲可复用流程,本篇讲能力边界如何外接。它把核心 Runtime 和外部生态连接起来,也为后面的 Observability、Gateway、Provider Runtime 做铺垫。
贯穿案例
贯穿这个系列,可以一直带着同一个任务来读:用户说“帮我修复这个 repo 里的 failing tests”。不同章节会回答同一个任务在运行时的不同问题:入口怎样进入、上下文怎样准备、模型怎样决定下一步、工具怎样执行、状态怎样保存、失败后怎样恢复。
定义
Extension 是在不修改 Agent 核心循环的前提下,为系统增加工具、平台、模型、记忆、上下文引擎或生命周期行为的机制。
它解决的是 Agent 系统的长期演化问题。一个好的扩展系统不只是“能加功能”,还要回答:功能怎样发现、怎样授权、怎样隔离、怎样禁用、怎样调试,以及它在模型上下文中如何呈现。
Hermes 的插件系统
Hermes 的插件可以放在用户目录、项目目录、内置目录,也可以通过 pip entry point 分发。一个最小插件通常包含 manifest、注册函数、schema 和 handler。
插件在 register(ctx) 中声明能力:
可迁移伪实现:Extension Plugin
下面的伪代码是机制抽象,不对应 Hermes 的真实 API 或文件结构。
type PluginContext = {
registerTool(entry: ToolEntry): void
registerHook(event: string, callback: Hook): void
registerCommand(name: string, handler: CommandHandler): void
registerPlatform(entry: PlatformEntry): void
registerSkill(name: string, path: string): void
registerContextEngine(engine: ContextEngine): void
}
这套接口背后的思想是:扩展不应该绕过核心运行时。插件注册工具后,工具仍然进入 Tool Runtime 的过滤、schema 生成、调用和结果回填流程;注册 hook 后,hook 也在明确生命周期点执行,而不是随意劫持对话。
扩展点选择表
不是所有扩展都应该做成插件,也不是所有外部能力都应该接成 MCP。一个实用判断方式是先看它扩展的是哪一层。
| 需求 | 更适合的扩展点 | 原因 |
|---|---|---|
| 增加一个本地可执行能力 | Tool / Plugin tool | 需要进入工具 schema,由 Agent 显式调用 |
| 接入外部标准工具服务器 | MCP | 让外部工具按统一协议暴露 |
| 新增模型供应商 | Provider plugin / config | 影响模型调用路径,不应写进 Tool Runtime |
| 改变消息平台入口 | Gateway adapter | 入口事件、session key、delivery 都在平台层 |
| 在执行前后记录审计信息 | Hook | 不改变核心逻辑,只观察或拦截生命周期 |
| 给某类任务增加流程知识 | Skill | 这是经验,不是新能力 |
这个区分能避免一个常见失控:把所有东西都塞进核心 Agent Loop。Hermes 的思路是让核心循环尽量稳定,把变化放到边界上。
扩展点不是一种
Hermes 把扩展分成多类,是因为不同能力的生命周期不同。
一般插件可以添加工具、hooks、slash commands 和 CLI commands。这类插件通常是多选的,用户可以同时启用多个。
平台插件负责 gateway 通道,例如 Discord、Telegram 之外的其他消息平台。它们要处理消息接收、鉴权、投递和会话映射。
Provider 插件解决模型、图像、视频、memory、context engine 这类“底层后端”替换问题。比如 model provider 可以新增一个 OpenAI-compatible 供应商;memory provider 可以替换长期记忆后端;context engine 可以替换内置压缩器。
MCP 则是另一种连接层。它让 Hermes 可以把外部 MCP server 暴露的工具、资源和 prompts 接入工具系统,不必为每个服务都写一个内置工具。

为什么需要显式启用
扩展系统的风险在于:它运行的是代码,不只是文本。
Hermes 因此对许多第三方插件采用 opt-in 模式。用户插件可以被发现,但不会默认执行;需要加入 plugins.enabled,或通过 hermes plugins enable 显式开启。项目本地插件默认也不开启,除非用户设置允许项目插件。
这种设计把便利性和安全边界分开:系统可以展示“有哪些扩展可用”,但不会在用户没有意识到的情况下执行任意插件代码。
plugins:
enabled:
- my-tool-plugin
disabled:
- noisy-plugin
当然,也有一些基础后端需要自动发现。例如内置平台、模型 provider、memory provider、context engine backend 等,如果完全走同一层 opt-in,基础功能会很难启动。Hermes 的做法是按插件种类区分加载策略,而不是用一个开关管理所有扩展。
Hooks:扩展运行时行为
Hooks 是 Extensions 中很重要的一类。它们不是给模型调用的工具,而是在生命周期点运行的代码。
例如:
pre_tool_call可以在工具执行前做审计或阻止;post_tool_call可以记录结果或上报指标;pre_llm_call可以注入额外上下文;on_session_start/on_session_end可以做会话级初始化和清理;- gateway hook 可以在消息平台上记录、告警或触发外部 webhook。
这让扩展系统不仅能增加“动作”,也能增加“治理”。企业内部使用 Agent 时,经常需要审计、成本归因、数据边界和告警;hook 是把这些横切关注点接进运行时的方式。
MCP 和插件的关系
MCP server 与 Hermes plugin 的边界不同。
MCP 更像外部服务协议。它适合把已经存在的工具服务接进来,例如 GitHub、数据库、内部 API、浏览器自动化服务。Hermes 负责连接 server、读取工具列表、把 schema 暴露给模型,再把调用转发出去。
Plugin 更像本地扩展机制。它适合深度接入 Hermes:注册 hooks、添加 gateway 平台、打包 skills、接入新的 context engine 或 provider。
在生产系统里,两者经常并存:MCP 负责跨应用互操作,plugin 负责本地运行时集成。
小结
Extensions 的核心价值,是让 Agent 框架保持小而稳定,同时允许能力边界持续增长。Hermes 的扩展系统不是一个“大插件口”,而是一组按生命周期和风险分层的入口:工具、平台、provider、hooks、MCP、skills 各有位置。这样的设计让 Agent 能适应真实环境,而不是把每个新需求都硬塞进核心。