第十二章:插件开发、研究功能与最佳实践
最后一章面向工程师与研究者。我们会讲 Hermes 的 插件系统(Plugin、Memory Provider、Context Engine)、Hooks(Gateway / Plugin / Shell 三套)、贡献开发流程、批量轨迹与 RL 训练、安全与运维清单。学完之后,你不只是在”用 Hermes”,而是可以”扩展、改造、研究 Hermes”。
12.1 插件系统总览
Hermes 的插件接口分三类(hermes_cli/plugins.py):
| 类型 | 解决什么 | 注册形式 |
|---|---|---|
| General Plugin | 加新工具、注册 hook、贴自定义命令 | plugins/<name>/plugin.py 暴露 register(ctx) |
| Memory Provider Plugin | 替换或扩展记忆后端(典型:Honcho、ByteRover、Mem0、Hindsight…) | 实现 MemoryProvider ABC |
| Context Engine Plugin | 替换默认的”上下文压缩 / 窗口管理” 策略 | 实现 ContextEngine ABC |
插件目录默认在:
- 内置:
hermes-agent/plugins/ - 用户:
~/.hermes/plugins/<name>/
启用:
hermes plugins list
hermes plugins enable my-plugin
hermes plugins disable my-plugin
hermes plugins reload my-plugin
或在 config.yaml:
plugins:
enabled:
- memory:honcho
- context:summarizer-v2
- my-plugin
12.2 写一个 General Plugin
最小目录:
~/.hermes/plugins/my-plugin/
├── plugin.yaml
└── plugin.py
plugin.yaml:
name: my-plugin
description: Demo plugin that adds a fortune tool and a hook
version: 0.1.0
entry: plugin:register
requires:
hermes_agent: ">=0.10.0"
plugin.py:
from hermes_cli.plugins import PluginContext
def register(ctx: PluginContext):
@ctx.tool(name="fortune", description="返回一句箴言")
def fortune(category: str = "default") -> str:
return random.choice(...)
@ctx.hook("agent:end")
async def log_end(event_type, context):
ctx.logger.info(f"agent done in {context['duration_ms']}ms")
PluginContext 提供:
ctx.tool(...):注册工具;ctx.hook(event):注册 hook;ctx.command(...):注册斜杠命令;ctx.config:访问config.yaml;ctx.profile、ctx.home_dir、ctx.logger、ctx.aux_llm()等便利。
启用后即生效:
hermes plugins enable my-plugin
hermes
> /fortune
12.3 写一个 Memory Provider Plugin
继承 agent.memory_provider.MemoryProvider:
from agent.memory_provider import MemoryProvider, MemoryEntry
class MyKVMemory(MemoryProvider):
def __init__(self, ctx):
self.kv = SomeKV("...")
async def load(self, target: str) -> list[MemoryEntry]:
return [MemoryEntry(**e) for e in await self.kv.list(target)]
async def add(self, target, content): ...
async def replace(self, target, old_text, content): ...
async def remove(self, target, old_text): ...
async def render_for_prompt(self, target) -> str:
...
注册:
def register(ctx):
ctx.register_memory_provider("my-kv", MyKVMemory(ctx))
启用:hermes plugins enable memory:my-kv,然后 hermes config set memory.provider my-kv。
Hermes 仓库里 plugins/memory/honcho/ 是 Honcho 的标准实现,可以作为最完整的范例。
12.4 写一个 Context Engine Plugin
agent.context_engine.ContextEngine ABC 决定:
- 系统提示如何拼装;
- 何时压缩、压缩什么;
- 输入/输出 token 估算策略。
默认实现是 agent.context_compressor.DefaultContextEngine(有损摘要)。如果你想接 retrieval、滑窗、长上下文压缩等:
class RetrievalAugContextEngine(ContextEngine):
def assemble_system_prompt(self, ctx): ...
def compress(self, history, target_tokens): ...
def estimate_tokens(self, msgs): ...
注册并 hermes config set context.engine my-engine 即可。这是研究者把自己的 idea 嵌进 Hermes 的最佳入口。
12.5 三种 Hook 体系
Hermes 同时存在三套 hook,分工明确:
| 系统 | 注册位置 | 跑在哪 | 典型用途 |
|---|---|---|---|
| Gateway Hooks | ~/.hermes/hooks/<name>/HOOK.yaml + handler.py |
仅 Gateway | 平台日志、告警、Webhook 转发 |
| Plugin Hooks | 插件中 ctx.register_hook() |
CLI + Gateway | 工具拦截、指标采集、护栏 |
| Shell Hooks | ~/.hermes/config.yaml 的 hooks: 块 |
CLI + Gateway | 一行脚本搞定(替代写 plugin) |
事件清单(节选):
agent:start、agent:step、agent:end、message:in、message:out、command:<name>、tool:before、tool:after、tool:approval、memory:write、memory:flush、compress:start、compress:done、pairing:created、session:create、session:end 等。
Shell Hook 最简例
hooks:
pre_tool_terminal: ~/.hermes/hooks/redact-secrets.sh
post_message_out: ~/.hermes/hooks/log-out.sh
脚本通过 stdin 拿 JSON event,stdout 返回的 JSON 可以拒绝({"deny": true, "reason": "..."})或修改输出。详细见 user-guide/features/hooks.md。
12.6 自定义平台 Adapter
如果某个 IM 平台还没在 gateway/platforms/ 中:
- 实现
PlatformAdapter抽象类(gateway/platforms/base.py); - 提供
start()、stop()、send(message)、on_event(callback)等钩子; - 注册到
gateway/platforms/__init__.py; - 写一份
user-guide/messaging/<name>.md。
详见 developer-guide/adding-platform-adapter.md(或在 developer-guide/contributing.md 找入口)。
12.7 自定义 Provider
hermes_cli/auth.py + hermes_cli/runtime_provider.py 是 Provider 的核心。新增一个 OpenAI 兼容 Provider 几乎只要:
PROVIDER_REGISTRY["my-provider"] = ProviderSpec(
label="My Provider",
api_mode="chat_completions",
base_url="https://api.my.example/v1",
api_key_env="MY_API_KEY",
list_models=lambda: ["my/model-1", "my/model-2"],
)
然后 hermes model 就会列出来。详细见 developer-guide/adding-providers.md。
12.8 自定义工具(贡献到 Hermes 主线)
绝大多数情况不需要——MCP / Plugin 已能覆盖。但若你想贡献:
- 在
tools/加一个my_tool.py,导出函数 + 描述 + JSON schema; - 在
tools/registry.py注册; - 在
toolsets.py加入合适分组; - 加测试到
tests/tools/。
详见 developer-guide/adding-tools.md 与 creating-skills.md(用于”先沉淀技能再升级成工具”)。
12.9 贡献流程
仓库 developer-guide/contributing.md:
- Fork、clone;
./setup-hermes.sh建 venv;- 写代码;遵循
pyproject.toml中 ruff/black/pytest 配置; - 跑
scripts/run_tests.sh; - 提 PR,附
hermes doctor输出与变更说明; - 大改请先开 issue 讨论。
代码风格:
- Python 3.11+;
- 类型注解尽量完整;
- 工具函数返回值用 dict 而非自定义 dataclass,便于通过 LLM 工具调用;
- 任何新功能必须有 docstring + 单测。
12.10 批量轨迹(Batch)与训练数据生成
batch_runner.py 是 Hermes 把”日常对话/工具调用”转成训练数据的入口。
hermes batch run \
--prompts ./prompts.jsonl \
--model anthropic/claude-opus-4.6 \
--concurrency 8 \
--toolsets web,terminal,file \
--output ./trajectories.jsonl
输出每行一份 ShareGPT-format 轨迹(含 system / user / assistant / tool 完整序列)。可以直接喂给 LoRA / SFT 训练。
user-guide/features/batch-processing.md 给了详尽参数。
12.11 Atropos / RL 训练
Hermes 与 Atropos 同源,在 environments/ 内提供若干 RL 兼容环境,让你能用 Hermes 真实跑出来的 trajectory 训练新一代工具调用模型。
user-guide/features/rl-training.md 介绍:
- 把 Hermes 当作 trajectory 生成器;
- 把 Hermes 当作 evaluator(rl_* 工具);
- 与 Atropos 训练循环对接(
tinker-atropos、mini_swe_runner.py等脚手架)。
如果你只是日常用户,可以忽略本节。但对模型团队,这是 Hermes 一个重要的”研究价值”。
12.12 安全与运维清单(Production Checklist)
把 Hermes 推到生产 / 团队前,过一遍下面的清单:
12.12.1 基础
- 用专用 Linux 用户跑(非 root);
~/.hermes/.env权限 600;- 备份
~/.hermes/{memories,skills,SOUL.md,config.yaml}到 git 仓库或异地; hermes update频率:每周一次或固定 release 跟随。
12.12.2 模型与凭据
- Provider API Key 全部过
.env,不进 shell history; - 启用 credential pool;多 Key 轮询;
- 设月度预算/告警(OpenRouter、Anthropic 都有);
- Fallback 模型至少 2 家。
12.12.3 沙箱
- 终端后端 =
docker(团队/生产)或daytona(serverless); - Docker 容器:
read_only: true、cap_drop: [ALL]、非 root user; - 仅 bind 必要目录;敏感目录禁止 mount;
- 网络限制(
network_mode: bridge+ 防火墙)。
12.12.4 命令审批
approval.always_deny至少含rm -rf /、mkfs、dd of=/dev;approval.require_confirmation含^sudo、^docker (rm|kill)、^kubectl delete、^terraform apply;- Gateway 端启用 DM Pairing;
- IM 平台默认收紧 toolset,不开 terminal/code_execution。
12.12.5 自动化
- cron job 设
max_runtime_seconds、max_iterations; - webhook secret 必填;
- webhook 入口走 Cloudflare Tunnel / 反向代理 + 签名校验;
- 关键 cron 失败时自动告警到 IM。
12.12.6 数据隐私
- 评估 Provider 数据保留策略(OpenAI/Anthropic 都有”不训练”开关,请显式打开);
- 公司机密默认走 自托管模型 / 国内供应商;
- 评审 MCP server 行为(特别是远程 HTTP,避免 SSRF);
- 关键操作写 audit hook,落到独立日志库。
12.12.7 可观测性
- systemd / docker 跑 Gateway,日志接 ELK / Loki / Sentry;
- 一个 plugin 把
agent:end事件写到 OLAP(ClickHouse 等)便于分析; - Web Dashboard 给团队管理员;
- 定期
hermes sessions vacuum释放空间。
12.12.8 升级前
hermes config check;git -C ~/.hermes/hermes-agent log --oneline -20看更新内容;- 在 staging profile 先跑一遍。
12.13 排错总集(Troubleshooting Playbook)
| 现象 | 怀疑 | 操作 |
|---|---|---|
| 启动慢 | MCP server 被 npx 拉拽 | 预装包;分服务延迟启动 |
| 频繁重新压缩 | 上下文阈值太低 | 调高 context.compress_threshold |
| 子代理超时 | iteration_budget 不够 | 加 delegation.iteration_budget_per_subagent |
| Provider 反复 fallback | 主家长期挂 | 重排 fallback 优先级;考虑切主家 |
| 工具 schema 报错 | 自定义 plugin 写错 | HERMES_LOG_LEVEL=debug hermes;看 plugin loader 输出 |
| Telegram 一直 “Conflict” | 多个进程登录同一 bot | 用 hermes gateway status;关其它实例 |
| Cron 漂移 | 时区错 / 系统时间没同步 | 配 cron.timezone;装 chrony/systemd-timesyncd |
| 浏览器 hang | chromium-local 在 headless 服务器没 X |
切 browserbase;或 Xvfb |
| Voice STT 慢 | OpenAI Whisper 跨海延迟 | 切 Groq;或本地 whisper.cpp |
12.14 一份”两年内的 Hermes 工作流”
把所有章节融合,一份工程师/研究者实际推荐的长期工作流:
- Day 0:装、
hermes setup、选 OpenRouter + Anthropic 做主,DeepSeek 做 aux;启用 docker 后端;启用 Telegram + 邮件;写 SOUL.md。 - Week 1:把日常项目根目录都加
AGENTS.md;让 Agent 把你的环境/偏好写进 MEMORY/USER;开 Honcho。 - Week 2:从 Skills Hub 装 5 个常用技能;让 Agent 自己沉淀第一条 SKILL(你重复做的事情)。
- Month 1:上线 cron:日报、PR Review、服务巡检、知识库整理;上 Webhook:GitHub PR、Stripe 事件。
- Month 2:上 Kanban,建 dispatcher / researcher / writer / reviewer 几个 profile;把团队复杂工作流接进来。
- Month 3:写第一个 plugin(你只在用的小工具);写第一个 Memory Provider(如果你需要把记忆持久到团队 KV)。
- Month 6:用
hermes batch run生成训练数据;用 Atropos 跑 RL 训练你自己的模型。 - Year 1:把
~/.hermes/{memories,skills,SOUL.md}同步进 dotfiles,跨设备无缝;个性化技能包成 hub 给同事用。 - Year 2:贡献回 Hermes 主线 1-2 个 PR;把这套 Agent 平台作为一个团队级”AI ops 操作系统”。
到这里,Hermes 不再是”一个工具”,它是你 AI 工作方式的 底盘。
12.15 本章小结
- Hermes 提供 三类插件接口(General / Memory Provider / Context Engine),让你能在不动主线代码的前提下把任何外部能力嵌入;
- 三套 Hook(Gateway / Plugin / Shell)覆盖一切生命周期事件;
- 新平台 / 新 Provider / 新工具 都有清晰的扩展点;
- Batch 与 Atropos RL 让 Hermes 也能作为研究/训练平台;
- 上线前请走完 生产清单,特别是沙箱、审批、凭据、cron 上限、可观测性。
至此 12 章教程结束。Hermes Agent 不只是一个 Agent 框架——它是一份对”长期共生型 AI 助理”应该是什么样子的工程化答卷。 把它跑起来、用起来、调起来、扩起来,你会越来越体会到这套架构的诚意。Happy hacking ☤