跳转到内容

04 - 插件系统与扩展点

学习目标

本章聚焦 Hermes Agent 的插件系统实现。你将了解:

  • PluginManager 的四种插件发现来源
  • 三个插件表面的职责划分
  • 生命周期钩子的注册与调用链
  • 插件策略:禁止修改核心文件的约束

前置知识

无特定前置知识。


项目实践

PluginManager 发现机制

hermes_cli/plugins.py(1807 行)实现了插件管理器:

四种插件来源(按优先级从低到高):

来源路径说明
Bundled<repo>/plugins/项目内置插件
User~/.hermes/plugins/用户安装的插件
Project./.hermes/plugins/项目本地插件(需 HERMES_ENABLE_PROJECT_PLUGINS=1
Pip Entry Pointshermes_agent.plugins entry pointspip 包注册的插件

五种植插件类型:standalone、backend、exclusive、platform、model-provider。

三表面插件发现

Hermes 有三个独立的插件发现表面:

表面发现路径注册方式
通用插件~/.hermes/plugins/ + pip entry pointsctx.register_tool()ctx.register_cli_command()
记忆提供者plugins/memory/<name>/register_provider() 到 MemoryManager
模型提供者plugins/model-providers/<name>/register_provider() 到 ProviderProfile 注册

PluginContext 提供的注册能力

插件通过 PluginContext 对象注册扩展:

ctx.register_tool(name, handler) # 注册工具
ctx.register_cli_command(name, handler) # 注册 CLI 命令
ctx.register_hook(hook_name, handler) # 注册生命周期钩子
ctx.register_command(name, handler) # 注册命令
ctx.register_context_engine(...) # 注册上下文引擎
ctx.register_image_gen_provider(...) # 注册图像生成提供者
ctx.register_browser_provider(...) # 注册浏览器提供者
ctx.register_tts_provider(...) # 注册 TTS 提供者
ctx.register_platform(...) # 注册消息平台适配器
ctx.register_auxiliary_task(...) # 注册辅助任务
ctx.register_skill(...) # 注册技能

生命周期钩子

VALID_HOOKS(插件可挂钩的生命周期点):

钩子触发时机
pre_tool_call工具调用前
post_tool_call工具调用后
transform_terminal_output终端输出转换时
transform_tool_result工具结果转换时
transform_llm_outputLLM 输出转换时
pre_llm_callLLM 调用前(可注入上下文)
post_llm_callLLM 调用后
pre_api_requestAPI 请求前
post_api_requestAPI 请求后
on_session_start会话开始时
on_session_end会话结束时
on_session_finalize会话最终化时
on_session_reset会话重置时
subagent_stop子代理停止时
pre_gateway_dispatch网关分发前
pre_approval_request审批请求前
post_approval_response审批响应后

策略约束

核心规则:插件禁止修改核心文件(run_agent.pycli.py 等),必须通过扩展点。

启用控制

  • plugins.enabled 配置节控制哪些插件启用
  • HERMES_ENABLE_PROJECT_PLUGINS 环境变量控制项目本地插件

问题与规避

插件依赖缺失

问题:插件依赖的第三方库未安装,导致 import 失败。

对策:插件加载使用 try/except 包裹,单个插件失败不影响其他插件。缺失依赖的插件以 WARNING 级别记录日志。

插件钩子的性能影响

问题pre_llm_call 钩子如果执行耗时操作,会阻塞 LLM 调用。

对策:钩子应轻量执行。耗时操作(如网络请求)应异步执行或使用后台线程。


设计取舍

三表面插件发现 vs 统一注册表

方案优势代价
三表面(Hermes)每类插件有专用的发现路径和生命周期插件作者需要理解三种注册方式
统一注册表单一入口、学习成本低通用性受限、需要适配层

Hermes 选择三表面是因为记忆提供者和模型提供者有独特的生命周期(独立于通用插件的钩子系统),通用插件的注册机制不适用于它们。


参考来源

  • 源码验证:hermes_cli/plugins.pyAGENTS.md 插件章节