跳到主要内容

插件

Hermes 提供了插件系统,可在不修改核心代码的情况下添加自定义工具、钩子和集成。

构建一个 Hermes 插件 — 带有完整可运行示例的逐步指南。

快速概览

将一个目录放入 ~/.hermes/plugins/,并包含一个 plugin.yaml 文件和 Python 代码:

~/.hermes/plugins/my-plugin/
├── plugin.yaml # 显现
├── __init__.py # register() — 将模式连接到处理程序
├── schemas.py # tool 架构(LLM 看到的内容)
└── tools.py # tool 处理程序(调用时运行的内容)

启动 Hermes — 您的工具将与内置工具一同出现。模型可立即调用它们。

最小可运行示例

以下是一个完整的插件示例,它添加了一个 hello_world 工具,并通过钩子记录每次工具调用。

~/.hermes/plugins/hello-world/plugin.yaml

name: hello-world
version: "1.0"
description: A minimal example plugin

~/.hermes/plugins/hello-world/__init__.py

"""Minimal Hermes plugin — registers a tool and a hook."""


def register(ctx):
# --- 工具:hello_world ---
schema = {
"name": "hello_world",
"description": "Returns a friendly greeting for the given name.",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name to greet",
}
},
"required": ["name"],
},
}

def handle_hello(params):
name = params.get("name", "World")
return f"Hello, {name}! 👋 (from the hello-world plugin)"

ctx.register_tool("hello_world", schema, handle_hello)

# --- 挂钩:记录每个 tool 调用 ---
def on_tool_call(tool_name, params, result):
print(f"[hello-world] tool called: {tool_name}")

ctx.register_hook("post_tool_call", on_tool_call)

将这两个文件放入 ~/.hermes/plugins/hello-world/,重启 Hermes,模型即可立即调用 hello_world。该钩子会在每次工具调用后打印一条日志。

位于 ./.hermes/plugins/ 的项目本地插件默认被禁用。仅在信任的仓库中,通过在启动 Hermes 前设置 HERMES_ENABLE_PROJECT_PLUGINS=true 来启用它们。

插件可实现的功能

功能实现方式
添加工具ctx.register_tool(name, schema, handler)
添加钩子ctx.register_hook("post_tool_call", callback)
添加 CLI 命令ctx.register_cli_command(name, help, setup_fn, handler_fn) — 添加 hermes <plugin> <subcommand>
注入消息ctx.inject_message(content, role="user") — 参见 注入消息
发布数据文件Path(__file__).parent / "data" / "file.yaml"
打包技能在加载时将 skill.md 复制到 ~/.hermes/skills/
基于环境变量控制启用requires_env: [API_KEY]plugin.yaml 中 — 在 hermes plugins install 时提示输入
通过 pip 分发[project.entry-points."hermes_agent.plugins"]

插件发现机制

来源路径使用场景
用户~/.hermes/plugins/个人插件
项目.hermes/plugins/项目专用插件(需设置 HERMES_ENABLE_PROJECT_PLUGINS=true
piphermes_agent.plugins entry_points分发的包

可用钩子

插件可注册回调以响应以下生命周期事件。完整细节、回调签名和示例请参见 事件钩子页面

钩子触发时机
pre_tool_call任何工具执行前
post_tool_call任何工具返回后
pre_llm_call每轮对话开始前(仅一次),可返回 {"context": "..."}将上下文注入用户消息
post_llm_call每轮对话结束后(仅成功轮次)
on_session_start新会话创建时(仅第一轮)
on_session_end每次 run_conversation 调用结束 + CLI 退出处理器

插件类型

Hermes 有三种类型的插件:

类型功能选择方式位置
通用插件添加工具、钩子、CLI 命令多选(可启用/禁用)~/.hermes/plugins/
记忆提供者替换或增强内置记忆单选(仅一个激活)plugins/memory/
上下文引擎替换内置上下文压缩器单选(仅一个激活)plugins/context_engine/

记忆提供者和上下文引擎是 提供者插件 —— 每种类型在同一时间只能有一个激活。通用插件可任意组合启用。

管理插件

hermes plugins                  # 统一交互界面
hermes plugins list # 具有启用/disabled状态的表视图
hermes plugins install user/repo # 从 Git 安装
hermes plugins update my-plugin # 拉最新的
hermes plugins remove my-plugin # 卸载
hermes plugins enable my-plugin # 重新启用已禁用的插件
hermes plugins disable my-plugin # 禁用而不删除

交互式界面

运行 hermes plugins 且不带参数时,将打开一个复合交互界面:

Plugins
↑↓ navigate SPACE toggle ENTER configure/confirm ESC done

General Plugins
→ [✓] my-tool-plugin — Custom search tool
[ ] webhook-notifier — Event hooks

Provider Plugins
Memory Provider ▸ honcho
Context Engine ▸ compressor
  • 通用插件部分 —— 复选框,使用空格键切换
  • 提供者插件部分 —— 显示当前选择。按回车键进入单选选择器,从中选择一个激活的提供者。

提供者插件的选择将保存至 config.yaml

memory:
provider: "honcho" # 空字符串 = 仅内置

context:
engine: "compressor" # 默认内置压缩机

禁用通用插件

禁用的插件仍保留在系统中,但在加载时会被跳过。禁用列表存储在 config.yamlplugins.disabled 下:

plugins:
disabled:
- my-noisy-plugin

在运行会话中,输入 /plugins 可查看当前已加载的插件。

注入消息

插件可使用 ctx.inject_message() 向当前对话注入消息:

ctx.inject_message("New data arrived from the webhook", role="user")

签名: ctx.inject_message(content: str, role: str = "user") -> bool

工作原理:

  • 如果 Agent 处于 空闲 状态(等待用户输入),则消息将被排队为下一个输入,并启动一个新回合。
  • 如果 Agent 处于 回合中(正在运行),则消息会中断当前操作——与用户输入新消息并按 Enter 键的效果相同。
  • 对于非 "user" 角色的消息,内容前会加上 [role] 前缀(例如 [system] ...)。
  • 如果消息成功排队,返回 True;如果无法获取 CLI 引用(例如在网关模式下),则返回 False

这使得远程控制查看器、消息桥接器或 Webhook 接收器等插件能够从外部源向对话中注入消息。

备注

inject_message 仅在 CLI 模式下可用。在网关模式下,没有 CLI 引用,该方法将返回 False

有关处理器合约、模式格式、钩子行为、错误处理和常见错误的完整指南,请参阅 完整指南