Section: Core Features · URL: https://hermesbible.com/docs/user-guide/features/plugins
Hermes 擁有外掛系統,可以用來新增自訂工具、鉤子和整合功能,而無需修改核心程式碼。
如果你想為自己、團隊或特定專案建立自訂工具,
這通常是最合適的路徑。開發者指南中的
新增工具 頁面是針對位於 tools/ 和 toolsets.py 中的
Hermes 核心內建工具。
→ 建立 Hermes 外掛 — 附有完整可用範例的逐步指南。
快速概覽
將目錄放入 ~/.hermes/plugins/,包含 plugin.yaml 和 Python 程式碼:
~/.hermes/plugins/my-plugin/
├── plugin.yaml # 設定檔
├── __init__.py # register() — 將 schema 繫結到處理函式
├── schemas.py # 工具 schema(LLM 所看到的)
└── tools.py # 工具處理函式(呼叫時執行程式碼)
啟動 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."""
import json
def register(ctx):
# --- Tool: 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, **kwargs):
del kwargs
name = params.get("name", "World")
return json.dumps({"success": True, "greeting": f"Hello, {name}!"})
ctx.register_tool(
name="hello_world",
toolset="hello_world",
schema=schema,
handler=handle_hello,
description="Return a friendly greeting for the given name.",
)
# --- Hook: log every tool call ---
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.* API 都可以在外掛的 register(ctx) 函式中使用。
| 功能 | 方法 |
|---|---|
| 新增工具 | ctx.register_tool(name=..., toolset=..., schema=..., handler=...) |
| 新增鉤子 | ctx.register_hook("post_tool_call", callback) |
| 新增斜線命令 | ctx.register_command(name, handler, description) — 在 CLI 和閘道器工作階段中新增 /name |
| 從命令分派工具 | ctx.dispatch_tool(name, args) — 呼叫已註冊的工具,並自動繫結父代理上下文 |
| 新增 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" |
| 繫結技能 | ctx.register_skill(name, path) — 命名空間為 plugin:skill,透過 skill_view("plugin:skill") 載入 |
| 依賴環境變數 | requires_env: [API_KEY] 於 plugin.yaml — 在 hermes plugins install 時提示 |
| 透過 pip 分發 | [project.entry-points."hermes_agent.plugins"] |
| 註冊閘道器平台(Discord、Telegram、IRC、…) | ctx.register_platform(name, label, adapter_factory, check_fn, ...) — 參見 新增平台介面卡 |
| 註冊圖片生成後端 | ctx.register_image_gen_provider(provider) — 參見 圖片生成供應商外掛 |
| 註冊影片生成後端 | ctx.register_video_gen_provider(provider) — 參見 影片生成供應商外掛 |
| 註冊上下文壓縮引擎 | ctx.register_context_engine(engine) — 參見 上下文引擎外掛 |
| 註冊記憶體後端 | 在 plugins/memory/<name>/__init.py 中繼承 MemoryProvider — 參見 記憶體供應商外掛(使用獨立的發現系統) |
| 執行宿主端的 LLM 呼叫 | ctx.llm.complete(...) / ctx.llm.complete_structured(...) — 借用使用者的啟用模型 + 認證,進行單次補全,可選用 JSON schema 驗證。參見 外掛 LLM 存取 |
| 註冊推論後端(LLM 供應商) | register_provider(ProviderProfile(...)) 於 plugins/model-providers/<name>/__init__.py — 參見 模型供應商外掛(使用獨立的發現系統) |
外掛發現
| 來源 | 路徑 | 用例 |
|---|---|---|
| 內建 | <repo>/plugins/ | 隨 Hermes 一起提供 — 參見 內建外掛 |
| 使用者 | ~/.hermes/plugins/ | 個人外掛 |
| 專案 | .hermes/plugins/ | 專案專屬外掛(需要 HERMES_ENABLE_PROJECT_PLUGINS=true) |
| pip | hermes_agent.plugins entry_points | 分發套件 |
| Nix | services.hermes-agent.extraPlugins / extraPythonPackages | NixOS 宣告式安裝 — 參見 Nix 設定 |
後面的來源會在名稱衝突時覆蓋前面的來源,因此與內建外掛同名的使用者外掛會替換它。
外掛子分類
在每個來源中,Hermes 還會識別子分類目錄,將外掛路由到專門的發現系統:
| 子目錄 | 內容 | 發現系統 |
|---|---|---|
plugins/(根目錄) | 通用外掛 — 工具、鉤子、斜線命令、CLI 命令、繫結技能 | PluginManager(類型:standalone 或 backend) |
plugins/platforms/<name>/ | 閘道器頻道介面卡(ctx.register_platform()) | PluginManager(類型:platform,再深一層) |
plugins/image_gen/<name>/ | 圖片生成後端(ctx.register_image_gen_provider()) | PluginManager(類型:backend,再深一層) |
plugins/memory/<name>/ | 記憶體供應商(繼承 MemoryProvider) | 專屬載入器 於 plugins/memory/__init__.py(類型:exclusive — 同時間僅一個啟用) |
plugins/context_engine/<name>/ | 上下文壓縮引擎(ctx.register_context_engine()) | 專屬載入器 於 plugins/context_engine/__init__.py(同時間僅一個啟用) |
plugins/model-providers/<name>/ | LLM 供應商設定檔(register_provider(ProviderProfile(...))) | 專屬載入器 於 providers/__init__.py(在首次 get_provider_profile() 呼叫時延遲掃描) |
位於 ~/.hermes/plugins/model-providers/<name>/ 和 ~/.hermes/plugins/memory/<name>/ 的使用者外掛會覆蓋同名的內建外掛 — 在 register_provider() / register_memory_provider() 中採用後寫入者勝出原則。放入目錄即可替換內建版本,無需修改儲存庫。
外掛是選擇性加入的(少數例外)
通用外掛和使用者安裝的後端預設是停用的 — 發現系統會找到它們(因此它們會出現在 hermes plugins 和 /plugins 中),但在你將外掛名稱加入 ~/.hermes/config.yaml 的 plugins.enabled 之前,帶有鉤子或工具的外掛不會載入。這可以防止未經你明確同意的第三方程式碼執行。
plugins:
enabled:
- my-tool-plugin
- disk-cleanup
disabled: # 可選的拒絕清單 — 若名稱同時出現在兩者中,則以此為準
- noisy-plugin
三種切換狀態的方式:
hermes plugins # 互動式切換(空白鍵勾選/取消勾選)
hermes plugins enable <name> # 加入允許清單
hermes plugins disable <name> # 從允許清單移除 + 加入停用清單
執行 hermes plugins install owner/repo 後,會提示 Enable 'name' now? [y/N] — 預設為否。若要在腳本安裝時跳過提示,可使用 --enable 或 --no-enable。
允許清單不涵蓋的範圍
有幾個類別的外掛會繞過 plugins.enabled — 它們是 Hermes 內建功能的一部分,若預設被閘限會導致基本功能無法運作:
| 外掛類型 | 替代啟用方式 |
|---|---|
內建平台外掛(IRC、Teams 等,位於 plugins/platforms/) | 自動載入,使每個隨附的閘道器頻道皆可用。實際頻道透過 config.yaml 中的 gateway.platforms.<name>.enabled 開啟。 |
內建後端(圖片生成供應商,位於 plugins/image_gen/,等) | 自動載入,使預設後端「開箱即用」。選擇透過 config.yaml 中的 <category>.provider 進行(例如 image_gen.provider: openai)。 |
記憶體供應商(plugins/memory/) | 全部發現;同時僅有一個啟用,由 config.yaml 中的 memory.provider 選擇。 |
上下文引擎(plugins/context_engine/) | 全部發現;一個啟用,由 config.yaml 中的 context.engine 選擇。 |
模型供應商(plugins/model-providers/) | 位於 plugins/model-providers/ 下的所有內建供應商會在首次 get_provider_profile() 呼叫時發現並註冊。使用者一次只能透過 --provider 或 config.yaml 選擇一個。 |
透過 pip 安裝的 backend 類型外掛 | 透過 plugins.enabled 選擇性加入(與通用外掛相同)。 |
使用者安裝的平台(位於 ~/.hermes/plugins/platforms/) | 透過 plugins.enabled 選擇性加入 — 第三方閘道器介面卡需要明確同意。 |
簡而言之:內建的「始終可用」基礎設施會自動載入;第三方通用外掛則是選擇性加入的。plugins.enabled 允許清單是專門用來管控使用者放入 ~/.hermes/plugins/ 中任意程式碼的閘限機制。
現有使用者的遷移
當你升級到具有選擇性加入外掛功能的 Hermes 版本(設定結構 v21+)時,任何已安裝在 ~/.hermes/plugins/ 下且尚未出現在 plugins.disabled 中的使用者外掛,都會自動被保留至 plugins.enabled。你現有的設定會繼續運作。內建的獨立外掛則不會被保留 — 即使是現有使用者也必須明確選擇加入。(內建的平台/後端外掛從不需要保留處理,因為它們從未被閘限。)
可用的鉤子
外掛可以為這些生命週期事件註冊回呼函式。詳情、回呼函式簽章和範例,請參閱**事件鉤子頁面**。
| 鉤子 | 觸發時機 |
|---|---|
pre_tool_call | 任何工具執行前 |
post_tool_call | 任何工具回傳後 |
pre_llm_call | 每回合一次,在 LLM 迴圈之前 — 可回傳 {"context": "..."} 以將上下文注入使用者訊息 |
post_llm_call | 每回合一次,在 LLM 迴圈之後(僅限成功的回合) |
on_session_start | 新工作階段建立時(僅限首次回合) |
on_session_end | 每次 run_conversation 呼叫結束 + CLI 退出處理常式 |
on_session_finalize | CLI/閘道器拆除作用中的工作階段(/new、垃圾回收、CLI 退出) |
on_session_reset | 閘道器切換新的工作階段金鑰(/new、/reset、/clear、閒置輪替) |
subagent_stop | delegate_task 完成後,每個子代理一次 |
pre_gateway_dispatch | 閘道器收到使用者訊息後,在驗證 + 分派之前。回傳 {"action": "skip" | "rewrite" | "allow", ...} 以影響流程。 |
外掛類型
Hermes 有四種外掛:
| 類型 | 功能 | 選擇方式 | 位置 |
|---|---|---|---|
| 通用外掛 | 新增工具、鉤子、斜線命令、CLI 命令 | 多選(啟用/停用) | ~/.hermes/plugins/ |
| 記憶體供應商 | 替換或增強內建記憶體 | 單選(一個啟用) | plugins/memory/ |
| 上下文引擎 | 替換內建的上下文壓縮器 | 單選(一個啟用) | plugins/context_engine/ |
| 模型供應商 | 宣告推論後端(OpenRouter、Anthropic、…) | 多重註冊,由 --provider / config.yaml 選擇 | plugins/model-providers/ |
記憶體供應商和上下文引擎是供應商外掛 — 每種類型同時只能有一個啟用。模型供應商也是外掛,但可以同時載入多個;使用者一次只能透過 --provider 或 config.yaml 選擇一個。通用外掛可以任意組合啟用。
可插拔介面 — 各功能的對應位置
上表顯示了四種外掛類別,但在「通用外掛」中,PluginContext 暴露了數個不同的擴展點 — Hermes 也接受 Python 外掛系統之外的擴展(設定驅動的後端、shell 鉤子命令、外部伺服器等)。使用此表格找到你想建立功能的正確文件:
| 想新增… | 方法 | 開發指南 |
|---|---|---|
| 一個 LLM 可以呼叫的工具 | Python 外掛 — ctx.register_tool() | 建立 Hermes 外掛 · 新增工具 |
| 一個生命週期鉤子(LLM 前/後、工作階段開始/結束、工具篩選) | Python 外掛 — ctx.register_hook() | 鉤子參考 · 建立 Hermes 外掛 |
| 一個供 CLI / 閘道器使用的斜線命令 | Python 外掛 — ctx.register_command() | 建立 Hermes 外掛 · 擴展 CLI |
一個供 hermes <thing> 使用的子命令 | Python 外掛 — ctx.register_cli_command() | 擴展 CLI |
| 你的外掛附帶的繫結技能 | Python 外掛 — ctx.register_skill() | 建立技能 |
| 一個推論後端(LLM 供應商:OpenAI 相容、Codex、Anthropic-Messages、Bedrock) | 供應商外掛 — register_provider(ProviderProfile(...)) 於 plugins/model-providers/<name>/ | 模型供應商外掛 · 新增供應商 |
| 一個閘道器頻道(Discord / Telegram / IRC / Teams / 等) | 平台外掛 — ctx.register_platform() 於 plugins/platforms/<name>/ | 新增平台介面卡 |
| 一個記憶體後端(Honcho、Mem0、Supermemory、…) | 記憶體外掛 — 在 plugins/memory/<name>/ 中繼承 MemoryProvider | 記憶體供應商外掛 |
| 一個上下文壓縮策略 | 上下文引擎外掛 — ctx.register_context_engine() | 上下文引擎外掛 |
| 一個圖片生成後端(DALL·E、SDXL、…) | 後端外掛 — ctx.register_image_gen_provider() | 圖片生成供應商外掛 |
| 一個影片生成後端(Veo、Kling、Pixverse、Grok-Imagine、Runway、…) | 後端外掛 — ctx.register_video_gen_provider() | 影片生成供應商外掛 |
| 一個 TTS 後端(任何 CLI — Piper、VoxCPM、Kokoro、xtts、語音複製腳本、…) | 設定驅動(建議) — 在 config.yaml 的 tts.providers.<name> 下宣告,使用 type: command。或 Python 後端外掛 — ctx.register_tts_provider() 用於需要比 shell 範本更多功能的 Python SDK / 串流引擎。 | TTS 設定 · Python 外掛指南 |
| 一個 STT 後端(任何 CLI — whisper.cpp、自訂 whisper 二進位檔、本地 ASR CLI) | 設定驅動(建議) — 在 config.yaml 的 stt.providers.<name> 下宣告,使用 type: command,或設定 HERMES_LOCAL_STT_COMMAND 作為舊版單命令替代方案。或 Python 後端外掛 — ctx.register_transcription_provider() 用於 Python SDK 引擎(OpenRouter、SenseAudio、Gemini-STT 等)。 | STT 設定 · Python 外掛指南 |
| 透過 MCP 的外部工具(檔案系統、GitHub、Linear、Notion、任何 MCP 伺服器) | 設定驅動 — 在 config.yaml 的 mcp_servers.<name> 下宣告,使用 command: / url:。Hermes 會自動發現伺服器的工具並將其與內建工具一起註冊。 | MCP |
| 額外的技能來源(自訂 GitHub 儲存庫、私有技能索引) | CLI — hermes skills tap add <repo> | 技能中心 · 發佈自訂 tap |
閘道器事件鉤子(在 gateway:startup、session:start、agent:end、command:* 時觸發) | 將 HOOK.yaml + handler.py 放入 ~/.hermes/hooks/<name>/ | 事件鉤子 |
| Shell 鉤子(在事件時執行 shell 命令 — 通知、稽核日誌、桌面提醒) | 設定驅動 — 在 config.yaml 的 hooks: 下宣告 | Shell 鉤子 |
注意
並非所有功能都是 Python 外掛。有些擴展表面故意使用設定驅動的 shell 命令(TTS、STT、shell 鉤子),讓你已有的任何 CLI 無需撰寫 Python 就能成為外掛。其他則是外部伺服器(MCP),代理會連線並自動註冊其工具。還有一些是直接放入的目錄(閘道器鉤子),有其專屬的設定檔格式。根據你的整合風格選擇正確的表面;上表中的每個開發指南都涵蓋了佔位符、發現機制和範例。
NixOS 宣告式外掛
在 NixOS 上,外掛可以透過模組選項以宣告式方式安裝 — 無需使用 hermes plugins install。詳情請參閱 Nix 設定指南。
services.hermes-agent = {
# 目錄外掛(包含 plugin.yaml 的原始碼樹)
extraPlugins = [ (pkgs.fetchFromGitHub { ... }) ];
# 入口點外掛(pip 套件)
extraPythonPackages = [ (pkgs.python312Packages.buildPythonPackage { ... }) ];
# 在設定中啟用
settings.plugins.enabled = [ "my-plugin" ];
};
宣告式外掛會以 nix-managed- 前綴建立符號連結 — 它們與手動安裝的外掛共存,並在從 Nix 設定中移除時自動清理。
管理外掛
hermes plugins # 統一互動式介面
hermes plugins list # 表格:已啟用 / 已停用 / 未啟用
hermes plugins install user/repo # 從 Git 安裝,然後提示 Enable? [y/N]
hermes plugins install user/repo --enable # 安裝並啟用(不提示)
hermes plugins install user/repo --no-enable # 安裝但保持停用(不提示)
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
[ ] disk-cleanup — Auto-cleanup of ephemeral files [bundled]
Provider Plugins
Memory Provider ▸ honcho
Context Engine ▸ compressor
- 通用外掛區塊 — 核取方塊,使用空白鍵切換。已勾選 = 在
plugins.enabled中,未勾選 = 在plugins.disabled中(明確關閉)。 - 供應商外掛區塊 — 顯示目前的選擇。按下 ENTER 進入單選介面,選擇一個啟用的供應商。
- 內建外掛會出現在相同清單中,帶有
[bundled]標籤。
供應商外掛的選擇會儲存到 config.yaml:
memory:
provider: "honcho" # 空字串 = 僅使用內建版本
context:
engine: "compressor" # 預設的內建壓縮器
已啟用 vs. 已停用 vs. 未啟用
外掛佔據三種狀態之一:
| 狀態 | 意義 | 在 plugins.enabled 中? | 在 plugins.disabled 中? |
|---|---|---|---|
enabled | 在下個工作階段載入 | 是 | 否 |
disabled | 明確關閉 — 即使同時在 enabled 中也不會載入 | (無關) | 是 |
not enabled | 已發現但從未選擇加入 | 否 | 否 |
新安裝或內建外掛的預設狀態是 not enabled。hermes plugins list 會顯示這三種不同的狀態,讓你分辨哪些是被明確關閉的,哪些只是等待被啟用。
在執行中的工作階段中,/plugins 會顯示目前已載入的外掛。
注入訊息
外掛可以使用 ctx.inject_message() 將訊息注入作用中的對話:
ctx.inject_message("New data arrived from the webhook", role="user")
簽章: ctx.inject_message(content: str, role: str = "user") -> bool
運作方式:
- 若代理閒置中(等待使用者輸入),訊息會被排隊為下一個輸入並開始新的回合。
- 若代理回合進行中(正在運行),訊息會中斷目前的操作 — 與使用者輸入新訊息並按下 Enter 相同。
- 對於非
"user"角色,內容會加上[role]前綴(例如[system] ...)。 - 若訊息成功排隊則回傳
True,若無可用的 CLI 參考(例如在閘道器模式下)則回傳False。
這使得遠端控制檢視器、訊息橋接器或 Webhook 接收器等外掛,可以從外部來源將訊息餵入對話中。
注意
inject_message僅在 CLI 模式下可用。在閘道器模式下,沒有 CLI 參考,方法會回傳False。
詳情請參閱**完整指南**,包含處理函式合約、schema 格式、鉤子行為、錯誤處理和常見錯誤。