Плагины
В системе Hermes имеются плагины для добавления дополнительных инструментов, хуков и интеграций без изменения базового кода.
Если вы хотите создать пользовательский инструмент для себя, своей команды или одного проекта,
обычно это правильный путь. Страница руководства разработчика
Добавление инструментов созданы для встроенных основных инструментов
Hermes, который находится в tools/ и toolsets.py.
→ Создайте плагин Hermes — пошаговое руководство с полной версией сборки.
Краткий обзор
Поместите каталог в ~/.hermes/plugins/ с plugin.yaml и кодом Python:
~/.hermes/plugins/my-plugin/
├── plugin.yaml # манифест
├── __init__.py # register() — связывает схемы с обработчиками
├── schemas.py # схемы инструментов (что видит LLM)
└── tools.py # обработчики инструментов (что выполняется при вызове)
Запустите Гермес — ваши инструменты появятся рядом с блоками. Модель может немедленно изменить их.
Минимальный рабочий пример
Вот полный плагин, который добавляет инструмент hello_world и регистрирует каждый вызов инструмента через хук.
~/.hermes/plugins/hello-world/plugin.yaml
name: hello-world
version: "1.0"
description: Пример минимального плагина
~/.hermes/plugins/hello-world/__init__.py
"""Минимальный плагин Hermes — регистрирует инструмент и хук."""
import json
def register(ctx):
# --- Инструмент: hello_world ---
schema = {
"name": "hello_world",
"description": "Возвращает дружеское приветствие для указанного имени.",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Имя для приветствия",
}
},
"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="Возвращает дружеское приветствие для указанного имени.",
)
# --- Хук: регистрировать каждый вызов инструмента ---
def on_tool_call(tool_name, params, result):
print(f"[hello-world] вызван инструмент: {tool_name}")
ctx.register_hook("post_tool_call", on_tool_call)
Поместите оба файла в ~/.hermes/plugins/hello-world/, перезапустите Hermes, и модель сможет немедленно вызывать hello_world. Хук выводит строку лога после каждого вызова инструмента.
Локальные плагины проекта в ./.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 и шлюзовые сессии |
| Отправлять инструменты из команд | 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) — см. Плагины контекстных движков |
| Регистрировать бэкенд памяти | Подкласс MemoryProvider в plugins/memory/<name>/__init__.py — см. Плагины провайдеров памяти (использует отдельную систему обнаружения) |
| Выполнять LLM-вызов от хоста | ctx.llm.complete(...) / ctx.llm.complete_structured(...) — использует активную модель + аутентификацию пользователя для одноразового завершения с опциональной валидацией JSON-схемы. См. Доступ к 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 (kind: standalone или backend) |
plugins/platforms/<name>/ |
Адаптеры шлюзовых каналов (ctx.register_platform()) |
PluginManager (kind: platform, на один уровень глубже) |
plugins/image_gen/<name>/ |
Бэкенды генерации изображений (ctx.register_image_gen_provider()) |
PluginManager (kind: backend, на один уровень глубже) |
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(). Поместите каталог, и он заменит встроенный без каких-либо изменений в репозитории.
Плагины — opt-in (с несколькими исключениями)
Общие плагины и установленные пользователем бэкенды по умолчанию отключены — обнаружение находит их (поэтому они отображаются в hermes plugins и /plugins), но ничего с хуками или инструментами не загружается, пока вы не добавите имя плагина в plugins.enabled в ~/.hermes/config.yaml. Это предотвращает выполнение стороннего кода без вашего явного согласия.
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 выводится запрос Включить 'name' сейчас? [y/N] — по умолчанию нет. Пропустите запрос для скриптовых установок с помощью --enable или --no-enable.
Что НЕ блокирует белый список
Несколько категорий плагинов обходят plugins.enabled — они являются частью встроенной поверхности Hermes и сломали бы базовую функциональность, если бы были отключены по умолчанию:
| Тип плагина | Как активируется вместо этого |
|---|---|
Встроенные плагины платформ (IRC, Teams и т.д. в plugins/platforms/) |
Автоматически загружаются, чтобы каждый поставляемый шлюзовой канал был доступен. Фактический канал включается через gateway.platforms.<name>.enabled в config.yaml. |
Встроенные бэкенды (провайдеры генерации изображений в plugins/image_gen/ и т.д.) |
Автоматически загружаются, чтобы бэкенд по умолчанию «просто работал». Выбор происходит через <category>.provider в config.yaml (например, image_gen.provider: openai). |
Провайдеры памяти (plugins/memory/) |
Все обнаружены; активен ровно один, выбирается через memory.provider в config.yaml. |
Контекстные движки (plugins/context_engine/) |
Все обнаружены; активен один, выбирается через context.engine в config.yaml. |
Провайдеры моделей (plugins/model-providers/) |
Все встроенные провайдеры в plugins/model-providers/ обнаруживаются и регистрируются при первом вызове get_provider_profile(). Пользователь выбирает один за раз через --provider или config.yaml. |
Плагины backend, установленные через pip |
Opt-in через plugins.enabled (как и общие плагины). |
Установленные пользователем платформы (в ~/.hermes/plugins/platforms/) |
Opt-in через plugins.enabled — сторонние адаптеры шлюзов требуют явного согласия. |
Кратко: встроенная инфраструктура «всегда работает» загружается автоматически; сторонние общие плагины — opt-in. Белый список plugins.enabled является шлюзом специально для произвольного кода, который пользователь помещает в ~/.hermes/plugins/.
Миграция для существующих пользователей
Когда вы обновляетесь до версии Hermes с opt-in плагинами (схема конфига 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, GC, выход 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-плагинов (конфигурационные бэкенды, команды, подключённые через оболочку, внешние серверы и т.д.). Используйте эту таблицу, чтобы найти правильную документацию для того, что вы хотите создать:
| Хотите добавить… | Как | Руководство по созданию |
|---|---|---|
| Инструмент, который может вызывать 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, …) | Плагин памяти — подкласс MemoryProvider в plugins/memory/<name>/ |
Плагины провайдеров памяти |
| Стратегия сжатия контекста | Плагин контекстного движка — 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, скрипты клонирования голоса, …) | Конфигурационный — объявите в tts.providers.<name> с type: command в config.yaml |
Настройка TTS |
| STT-бэкенд (пользовательский бинарник whisper, локальный ASR CLI) | Конфигурационный — установите переменную окружения HERMES_LOCAL_STT_COMMAND в шаблон оболочки |
Транскрипция голосовых сообщений (STT) |
| Внешние инструменты через MCP (файловая система, GitHub, Linear, Notion, любой MCP-сервер) | Конфигурационный — объявите mcp_servers.<name> с command: / url: в config.yaml. Hermes автоматически обнаруживает инструменты сервера и регистрирует их вместе со встроенными. |
MCP |
| Дополнительные источники навыков (пользовательские GitHub-репозитории, частные индексы навыков) | CLI — hermes skills tap add <repo> |
Хаб навыков · Публикация пользовательского tap |
Событийные хуки шлюза (срабатывают на gateway:startup, session:start, agent:end, command:*) |
Поместите HOOK.yaml + handler.py в ~/.hermes/hooks/<name>/ |
Событийные хуки |
| Хуки оболочки (выполняют команду оболочки при событиях — уведомления, аудит, оповещения на рабочем столе) | Конфигурационный — объявите в hooks: в config.yaml |
Хуки оболочки |
| Не всё является Python-плагином. Некоторые поверхности расширения намеренно используют конфигурационные команды оболочки (TTS, STT, хуки оболочки), чтобы любой существующий CLI стал плагином без написания Python. Другие — это внешние серверы (MCP), к которым агент подключается и автоматически регистрирует инструменты. А некоторые — это каталоги для размещения (хуки шлюза) со своим собственным форматом манифеста. Выберите правильную поверхность для стиля интеграции, который подходит вашему варианту использования; руководства по созданию в таблице выше охватывают заполнители, обнаружение и примеры. | ||
| ## Декларативные плагины NixOS |
На NixOS плагины могут быть установлены декларативно через опции модуля — без необходимости hermes plugins install. См. Руководство по установке Nix для получения полной информации.
services.hermes-agent = {
# Плагин-каталог (дерево исходников с plugin.yaml)
extraPlugins = [ (pkgs.fetchFromGitHub {... }) ];
# Плагин entry-point (pip-пакет)
extraPythonPackages = [ (pkgs.python312Packages.buildPythonPackage {... }) ];
# Включить в конфиге
settings.plugins.enabled = [ "my-plugin" ];
};
Декларативные плагины связывают символические ссылки с префиксом nix-managed- — они сосуществуют с плагинами, установленными вручную, и автоматически удаляются при удалении из конфигурации Nix.
Управление плагинами
hermes plugins # единый интерактивный интерфейс
hermes plugins list # таблица: включено / отключено / не включено
hermes plugins install user/repo # установить из Git, затем запрос Включить? [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 плагинов без аргументов создаёт составной интерактивный экран:
Плагины
↑↓ навигация ПРОБЕЛ переключить ВВОД настроить/подтвердить ESC готово
Общие плагины
→ [✓] my-tool-plugin — Пользовательский инструмент поиска
[ ] webhook-notifier — Событийные хуки
[ ] disk-cleanup — Автоматическая очистка временных файлов [встроенный]
Плагины провайдеров
Провайдер памяти ▸ honcho
Контекстный движок ▸ compressor
- Раздел встроенных плагинов — флажки, переключение пробела. Отмечено = в
plugins.enabled, не отмечено = вplugins.disabled(явное выключение). - Раздел плагинов провайдеров — показывает данный выбор. Нажмите ВВОД, чтобы перейти к радиокнопкам, где вы выбираете одного активного провайдера.
- Встроенные плагины приводятся в том же списке с тегом
[встроенный].
Выбор плагинов провайдеров сохраняется в config.yaml:
memory:
provider: "honcho" # пустая строка = только встроенный
context:
engine: "compressor" # встроенный компрессор по умолчанию
Включено vs отключено vs ни то, ничего другого
Плагины находятся в одном из трёх состояний:
| Состояние | Значение | В plugins.enabled? |
В plugins.disabled? |
|---|---|---|---|
включено |
Загружен на нынешнем заседании | Да | Нет |
инвалид |
Явно выключен — не загружается, даже если также включен | (неважно) | Да |
не включен |
На открытом воздухе, но никогда не включен | Нет | Нет |
По умолчанию для нового установленного или встроенного плагина — «не включено». Список плагинов Гермеса показывает все три различных состояния, чтобы вы могли видеть, что было явно выключено, а что просто ожидает включения.
В запущенной сессии /plugins показаны какие плагины в данный момент загружены.
Вставка сообщений
Плагины могут отправлять сообщения в активный разговор с помощью ctx.inject_message():
ctx.inject_message("Новые данные поступили от вебхука", role="user")
Сигнатура: ctx.inject_message(content: str, role: str = "user") -> bool
Как это работает:
- Если агент без стула (ожидает ввода пользователя), сообщение вставляется по очереди, как вводится ввод и начинается новый шаг.
- Если агент в середине шага (активно работает), сообщение прерывает текущую операцию — так же, как если бы пользователь ввёл новое сообщение и нажал Enter.
- Для ролей, отличных от
"user", правилом предваряется[role](например,[system]...). - Возвращает
True, если сообщение было успешно решено, в свою очередь,False, если нет доступных ссылок в CLI (например, в режиме шлюза).
Это позволяет подключать такие устройства, как пульт удаленного управления, мосты обмена сообщениями или приемники вебхуков, передавать сообщения в разговор из внешних источников.:::примечание
inject_message доступен только в режиме CLI. В режиме шлюза нет ссылок на CLI, и метод возвращает False.