Плагины
Hermes имеет систему плагинов для добавления пользовательских инструментов, хуков и интеграций без изменения основного кода.
Если вы хотите создать пользовательский инструмент для себя, своей команды или одного проекта,
это обычно правильный путь. Страница
Adding Tools руководства разработчика предназначена для встроенных
основных инструментов Hermes, которые находятся в tools/ и toolsets.py.
→ Build a Hermes Plugin — пошаговое руководство с полным рабочим примером.
Краткий обзор
Поместите каталог с plugin.yaml и Python-кодом в ~/.hermes/plugins/:
~/.hermes/plugins/my-plugin/
├── plugin.yaml # manifest
├── __init__.py # register() — wires schemas to handlers
├── schemas.py # tool schemas (what the LLM sees)
└── tools.py # tool handlers (what runs when called)
Запустите Hermes — ваши инструменты появятся рядом со встроенными. Модель сможет вызывать их сразу.
Минимальный рабочий пример
Вот полный плагин, который добавляет инструмент hello_world и логирует каждый вызов инструмента через hook.
~/.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. Hook будет выводить строку лога после каждого вызова инструмента.
Локальные плагины проекта в ./.hermes/plugins/ отключены по умолчанию. Включайте их только для доверенных репозиториев, установив HERMES_ENABLE_PROJECT_PLUGINS=true перед запуском Hermes.
Что могут делать плагины
Каждый API ctx.* ниже доступен внутри функции register(ctx) плагина.
| Возможность | Как |
|---|---|
| Добавление инструментов | ctx.register_tool(name=..., toolset=..., schema=..., handler=...) |
| Добавление хуков | ctx.register_hook("post_tool_call", callback) |
| Добавление слеш-команд | ctx.register_command(name, handler, description) — добавляет /name в CLI и gateway-сессиях |
| Запуск инструментов из команд | 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") — см. Injecting Messages |
| Поставка файлов данных | 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"] |
| Регистрация gateway-платформы (Discord, Telegram, IRC, …) | ctx.register_platform(name, label, adapter_factory, check_fn, ...) — см. Adding Platform Adapters |
| Регистрация бэкенда генерации изображений | ctx.register_image_gen_provider(provider) — см. Image Generation Provider Plugins |
| Регистрация движка сжатия контекста | ctx.register_context_engine(engine) — см. Context Engine Plugins |
| Регистрация бэкенда памяти | Подкласс MemoryProvider в plugins/memory/<name>/__init__.py — см. Memory Provider Plugins (использует отдельную систему обнаружения) |
| Выполнение LLM-вызова от хоста | ctx.llm.complete(...) / ctx.llm.complete_structured(...) — использует активную модель пользователя + аутентификацию для однократного completion с опциональной JSON-схемой валидации. См. Plugin LLM Access |
| Регистрация инференс-бэкенда (LLM-провайдера) | register_provider(ProviderProfile(...)) в plugins/model-providers/<name>/__init__.py — см. Model Provider Plugins (использует отдельную систему обнаружения) |
Обнаружение плагинов
| Источник | Путь | Назначение |
|---|---|---|
| Встроенные | <repo>/plugins/ |
Поставляются с Hermes — см. Built-in Plugins |
| Пользовательские | ~/.hermes/plugins/ |
Личные плагины |
| Проектные | .hermes/plugins/ |
Плагины для конкретного проекта (требуется HERMES_ENABLE_PROJECT_PLUGINS=true) |
| pip | hermes_agent.plugins entry_points |
Распространяемые пакеты |
| Nix | services.hermes-agent.extraPlugins / extraPythonPackages |
Декларативные установки NixOS — см. Nix Setup |
Более поздние источники переопределяют более ранние при совпадении имён, поэтому пользовательский плагин с тем же именем, что и встроенный, заменяет его.
Подкатегории плагинов
Внутри каждого источника Hermes также распознаёт подкатегории каталогов, которые направляют плагины в специализированные системы обнаружения:
| Подкаталог | Содержимое | Система обнаружения |
|---|---|---|
plugins/ (root) |
Обычные плагины — инструменты, хуки, слеш-команды, CLI-команды, встроенные навыки | PluginManager (kind: standalone or backend) |
plugins/platforms/<name>/ |
Адаптеры gateway-каналов (ctx.register_platform()) |
PluginManager (kind: platform, one level deeper) |
plugins/image_gen/<name>/ |
Бэкенды генерации изображений (ctx.register_image_gen_provider()) |
PluginManager (kind: backend, one level deeper) |
plugins/memory/<name>/ |
Провайдеры памяти (подкласс MemoryProvider) |
Собственный загрузчик в plugins/memory/__init__.py (kind: 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), но ни один из них с хуками или инструментами не загружается, пока вы не добавите имя плагина в plugins.enabled в ~/.hermes/config.yaml. Это предотвращает выполнение стороннего кода без вашего явного согласия.
plugins:
enabled:
- my-tool-plugin
- disk-cleanup
disabled: # optional deny-list — always wins if a name appears in both
- noisy-plugin
Три способа изменить состояние:
hermes plugins # interactive toggle (space to check/uncheck)
hermes plugins enable <name> # add to allow-list
hermes plugins disable <name> # remove from allow-list + add to disabled
После hermes plugins install owner/repo вас спросят Enable 'name' now? [y/N] — по умолчанию нет. Пропустите запрос для скриптовых установок с помощью --enable или --no-enable.
Что не контролирует список разрешений
Некоторые категории плагинов обходят plugins.enabled — они являются частью встроенной поверхности Hermes, и базовая функциональность была бы нарушена, если бы они были отключены по умолчанию:
| Тип плагина | Как активируется вместо этого |
|---|---|
Встроенные platform-плагины (IRC, Teams и т.д. в plugins/platforms/) |
Автоматически загружаются, чтобы каждый поставляемый gateway-канал был доступен. Фактический канал включается через gateway.platforms.<name>.enabled в config.yaml. |
Встроенные бэкенды (image-gen провайдеры в plugins/image_gen/ и т.д.) |
Автоматически загружаются, чтобы бэкенд по умолчанию «просто работал». Выбор происходит через <category>.provider в config.yaml (например, image_gen.provider: openai). |
Memory providers (plugins/memory/) |
Все обнаружены; активен ровно один, выбранный через memory.provider в config.yaml. |
Context engines (plugins/context_engine/) |
Все обнаружены; активен один, выбранный через context.engine в config.yaml. |
Model providers (plugins/model-providers/) |
Все встроенные провайдеры в plugins/model-providers/ обнаруживаются и регистрируются при первом вызове get_provider_profile(). Пользователь выбирает один из них через --provider или config.yaml. |
Pip-installed backend plugins |
Подключаются через plugins.enabled (как обычные плагины). |
Установленные пользователем платформы (в ~/.hermes/plugins/platforms/) |
Подключаются через plugins.enabled — сторонние gateway-адаптеры требуют явного согласия. |
Коротко: встроенная инфраструктура загружается автоматически; сторонние обычные плагины подключаются добровольно. Список разрешений plugins.enabled — это шлюз специально для произвольного кода, который пользователь помещает в ~/.hermes/plugins/.
Миграция для существующих пользователей
Когда вы обновляетесь до версии Hermes с добровольным подключением плагинов (схема конфигурации v21+), все пользовательские плагины, уже установленные в ~/.hermes/plugins/ и не находившиеся в plugins.disabled, автоматически переносятся в plugins.enabled. Ваша существующая настройка продолжает работать. Встроенные отдельные плагины НЕ переносятся — даже существующие пользователи должны явно подключить их. (Встроенным platform/backend-плагинам перенос никогда не требовался, поскольку они никогда не были заблокированы.)
Доступные хуки
Плагины могут регистрировать обратные вызовы для этих событий жизненного цикла. Подробную информацию, сигнатуры обратных вызовов и примеры см. на странице Event Hooks.
| Hook | Срабатывает когда |
|---|---|
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/gateway завершает активную сессию (/new, GC, выход из CLI) |
on_session_reset |
Gateway заменяет ключ сессии (/new, /reset, /clear, ротация при простое) |
subagent_stop |
Один раз для каждого дочернего агента после завершения delegate_task |
pre_gateway_dispatch |
Gateway получил сообщение пользователя, перед аутентификацией + отправкой. Верните {"action": "skip" | "rewrite" | "allow", ...} для влияния на поток. |
Типы плагинов
Hermes имеет четыре типа плагинов:
| Тип | Что делает | Выбор | Расположение |
|---|---|---|---|
| Обычные плагины | Добавление инструментов, хуков, слеш-команд, CLI-команд | Множественный (включить/отключить) | ~/.hermes/plugins/ |
| Memory providers | Замена или расширение встроенной памяти | Одиночный (один активный) | plugins/memory/ |
| Context engines | Замена встроенного компрессора контекста | Одиночный (один активный) | plugins/context_engine/ |
| Model providers | Объявление инференс-бэкенда (OpenRouter, Anthropic, …) | Множественная регистрация, выбор через --provider / config.yaml |
plugins/model-providers/ |
Memory providers и Context engines — это provider-плагины — только один каждого типа может быть активен одновременно. Model providers также являются плагинами, но загружаются одновременно; пользователь выбирает один из них через --provider или config.yaml. Обычные плагины можно включать в любой комбинации.
Подключаемые интерфейсы — куда обратиться для каждого
Таблица выше показывает четыре категории плагинов, но внутри «Обычных плагинов» PluginContext предоставляет несколько различных точек расширения — и Hermes также принимает расширения вне системы Python-плагинов (бэкенды на основе конфигурации, команды с shell-хуками, внешние серверы и т.д.). Используйте эту таблицу, чтобы найти правильную документацию для того, что вы хотите создать:
| Хотите добавить… | Как | Руководство |
|---|---|---|
| Инструмент, который может вызывать LLM | Python plugin — ctx.register_tool() |
Build a Hermes Plugin · Adding Tools |
| Lifecycle-хук (pre/post LLM, начало/конец сессии, фильтр инструментов) | Python plugin — ctx.register_hook() |
Hooks reference · Build a Hermes Plugin |
| Слеш-команду для CLI / gateway | Python plugin — ctx.register_command() |
Build a Hermes Plugin · Extending the CLI |
Подкоманду для hermes <thing> |
Python plugin — ctx.register_cli_command() |
Extending the CLI |
| Навык, который поставляется с вашим плагином | Python plugin — ctx.register_skill() |
Creating Skills |
| Инференс-бэкенд (LLM-провайдер: OpenAI-compat, Codex, Anthropic-Messages, Bedrock) | Provider plugin — register_provider(ProviderProfile(...)) в plugins/model-providers/<name>/ |
Model Provider Plugins · Adding Providers |
| Gateway-канал (Discord / Telegram / IRC / Teams / и т.д.) | Platform plugin — ctx.register_platform() в plugins/platforms/<name>/ |
Adding Platform Adapters |
| Бэкенд памяти (Honcho, Mem0, Supermemory, …) | Memory plugin — подкласс MemoryProvider в plugins/memory/<name>/ |
Memory Provider Plugins |
| Стратегию сжатия контекста | Context-engine plugin — ctx.register_context_engine() |
Context Engine Plugins |
| Бэкенд генерации изображений (DALL·E, SDXL, …) | Backend plugin — ctx.register_image_gen_provider() |
Image Generation Provider Plugins |
| TTS-бэкенд (любая CLI — Piper, VoxCPM, Kokoro, xtts, скрипты клонирования голоса, …) | На основе конфигурации — объявите в tts.providers.<name> с type: command в config.yaml |
TTS setup |
| STT-бэкенд (пользовательский whisper binary, локальная ASR CLI) | На основе конфигурации — установите переменную окружения HERMES_LOCAL_STT_COMMAND как shell-шаблон |
Voice Message Transcription (STT) |
| Внешние инструменты через MCP (файловая система, GitHub, Linear, Notion, любой MCP-сервер) | На основе конфигурации — объявите mcp_servers.<name> с command: / url: в config.yaml. Hermes автоматически обнаруживает инструменты сервера и регистрирует их вместе со встроенными. |
MCP |
| Дополнительные источники навыков (пользовательские GitHub-репозитории, частные индексы навыков) | CLI — hermes skills tap add <repo> |
Skills Hub · Publishing a custom tap |
Gateway event hooks (срабатывают на gateway:startup, session:start, agent:end, command:*) |
Поместите HOOK.yaml + handler.py в ~/.hermes/hooks/<name>/ |
Event Hooks |
| Shell-хуки (выполнение shell-команды при событиях — уведомления, журналы аудита, оповещения рабочего стола) | На основе конфигурации — объявите в hooks: в config.yaml |
Shell Hooks |
Декларативные плагины NixOS
На NixOS плагины можно установить декларативно через опции модуля — без hermes plugins install. Подробности см. в Nix Setup guide.
services.hermes-agent = {
# Directory plugin (source tree with plugin.yaml)
extraPlugins = [ (pkgs.fetchFromGitHub { ... }) ];
# Entry-point plugin (pip package)
extraPythonPackages = [ (pkgs.python312Packages.buildPythonPackage { ... }) ];
# Enable in config
settings.plugins.enabled = [ "my-plugin" ];
};
Декларативные плагины добавляются с префиксом nix-managed- — они сосуществуют с плагинами, установленными вручную, и автоматически удаляются при исключении из конфигурации Nix.
Управление плагинами
hermes plugins # unified interactive UI
hermes plugins list # table: enabled / disabled / not enabled
hermes plugins install user/repo # install from Git, then prompt Enable? [y/N]
hermes plugins install user/repo --enable # install AND enable (no prompt)
hermes plugins install user/repo --no-enable # install but leave disabled (no prompt)
hermes plugins update my-plugin # pull latest
hermes plugins remove my-plugin # uninstall
hermes plugins enable my-plugin # add to allow-list
hermes plugins disable my-plugin # remove from allow-list + add to disabled
Интерактивный интерфейс
Запуск 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
-
Раздел General Plugins — флажки, переключение пробелом. Отмечено = в
plugins.enabled, не отмечено = вplugins.disabled(явное отключение). -
Раздел Provider Plugins — показывает текущий выбор. Нажмите ENTER, чтобы войти в переключатель, где вы выбираете одного активного провайдера.
-
Встроенные плагины отображаются в том же списке с пометкой
[bundled].
Выбор provider-плагинов сохраняется в config.yaml:
memory:
provider: "honcho" # empty string = built-in only
context:
engine: "compressor" # default built-in compressor
Включено, отключено или не выбрано
Плагины находятся в одном из трёх состояний:
| Состояние | Значение | В 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")
Signature: ctx.inject_message(content: str, role: str = "user") -> bool
Как это работает:
-
Если агент бездействует (ожидает ввода пользователя), сообщение помещается в очередь как следующий ввод и начинает новый ход.
-
Если агент в процессе хода (активно работает), сообщение прерывает текущую операцию — так же, как если бы пользователь ввёл новое сообщение и нажал Enter.
-
Для ролей, отличных от
"user", содержимое дополняется префиксом[role](например,[system] ...). -
Возвращает
True, если сообщение было успешно поставлено в очередь, иFalse, если нет доступной CLI-ссылки (например, в gateway-режиме).
Это позволяет таким плагинам, как пульты дистанционного управления, мосты обмена сообщениями или приёмники webhook, передавать сообщения в беседу из внешних источников.
См. полное руководство для ознакомления с контрактами обработчиков, форматом схемы, поведением хуков, обработкой ошибок и типичными ошибками.