Создание навыков
Навыки — предпочтительный способ расширить возможности Hermes Agent. Создать их проще, чем инструменты: код агента трогать не нужно, а готовый навык можно передать сообществу.
Навык или инструмент?
Выбирай навык, если:
- Возможность выражается через инструкции + shell-команды + уже доступные инструменты
- Нужно обернуть внешний CLI или API, который агент вызывает через
terminalилиweb_extract - Не требуется встроенная работа с ключами API или кастомная Python-интеграция прямо в агенте
- Примеры: поиск по arXiv, git-процессы, управление Docker, обработка PDF, отправка почты через CLI
Выбирай инструмент, если:
- Нужна сквозная интеграция с ключами API, OAuth-потоками или многокомпонентной конфигурацией
- Требуется кастомная логика обработки, которая должна срабатывать точно каждый раз
- Идёт работа с бинарными данными, потоками или событиями реального времени
- Примеры: браузерная автоматизация, TTS, анализ изображений
Структура каталога навыков
Встроенные навыки хранятся в skills/ с разбивкой по категориям. Официальные опциональные навыки используют ту же структуру в optional-skills/:
skills/
├── research/
│ └── arxiv/
│ ├── SKILL.md # Обязательно: основные инструкции
│ └── scripts/ # Опционально: вспомогательные скрипты
│ └── search_arxiv.py
├── productivity/
│ └── ocr-and-documents/
│ ├── SKILL.md
│ ├── scripts/
│ └── references/
└── ...
Формат SKILL.md
---
name: my-skill
description: Краткое описание (отображается в результатах поиска навыков)
version: 1.0.0
author: Your Name
license: MIT
platforms: [macos, linux] # Опционально — ограничить конкретными ОС
# Допустимые значения: macos, linux, windows
# Если не указано — загружается на всех платформах
metadata:
hermes:
tags: [Category, Subcategory, Keywords]
related_skills: [other-skill-name]
requires_toolsets: [web] # Опционально — показывать только при активных наборах инструментов
requires_tools: [web_search] # Опционально — показывать только при наличии этих инструментов
fallback_for_toolsets: [browser] # Опционально — скрывать при активных наборах инструментов
fallback_for_tools: [browser_navigate] # Опционально — скрывать при наличии этих инструментов
config: # Опционально — настройки config.yaml, нужные навыку
- key: my.setting
description: "Что контролирует этот параметр"
default: "sensible-default"
prompt: "Отображаемый промпт при настройке"
blueprint: # Опционально — помечает навык как запускаемую автоматизацию
schedule: "0 9 * * *" # cron-выражение / "every 2h" / ISO-метка времени
deliver: origin # опционально (по умолчанию origin)
prompt: "Инструкция-задача для каждого запуска" # опционально
no_agent: false # опционально
required_environment_variables: # Опционально — переменные окружения, необходимые навыку
- name: MY_API_KEY
prompt: "Введите ваш API-ключ"
help: "Получить можно на https://example.com"
required_for: "Доступ к API"
---
# Название навыка
Краткое введение.
## Когда использовать
Условия срабатывания — когда агент должен загружать этот навык?
## Краткий справочник
Таблица частых команд или API-вызовов.
## Процедура
Пошаговые инструкции для агента.
## Подводные камни
Известные сценарии сбоев и способы их обработки.
## Проверка
Как агент убеждается, что всё сработало.
Платформо-зависимые навыки
Поле platforms ограничивает навык конкретными операционными системами:
platforms: [macos] # Только macOS (например, iMessage, Apple Reminders)
platforms: [macos, linux] # macOS и Linux
platforms: [windows] # Только Windows
Если поле задано, на несовместимых платформах навык автоматически скрывается из системного промпта, skills_list() и slash-команд. Пустое или отсутствующее поле означает загрузку везде (обратно совместимое поведение).
Условная активация навыков
Навык может объявлять зависимости от конкретных инструментов или наборов инструментов. От этого зависит, появится ли он в системном промпте для данной сессии.
metadata:
hermes:
requires_toolsets: [web] # Скрыть, если набор web НЕ активен
requires_tools: [web_search] # Скрыть, если инструмент web_search НЕ доступен
fallback_for_toolsets: [browser] # Скрыть, если набор browser активен
fallback_for_tools: [browser_navigate] # Скрыть, если browser_navigate доступен
| Поле | Поведение |
|---|---|
requires_toolsets | Навык скрыт, если ЛЮБОЙ из перечисленных наборов инструментов недоступен |
requires_tools | Навык скрыт, если ЛЮБОЙ из перечисленных инструментов недоступен |
fallback_for_toolsets | Навык скрыт, если ЛЮБОЙ из перечисленных наборов инструментов доступен |
fallback_for_tools | Навык скрыт, если ЛЮБОЙ из перечисленных инструментов доступен |
Сценарий для fallback_for_*: навык-заглушка, который включается только при отсутствии основного инструмента. Скажем, duckduckgo-search с fallback_for_tools: [web_search] появляется лишь тогда, когда инструмент веб-поиска (он требует API-ключа) не настроен.
Сценарий для requires_*: навык, который имеет смысл только при наличии определённых инструментов. Например, навык веб-скрапинга с requires_toolsets: [web] не засоряет промпт, когда веб-инструменты отключены.
Требования к переменным окружения
Навык может объявить нужные ему переменные окружения. При загрузке через skill_view объявленные переменные автоматически регистрируются для проброса в изолированные среды выполнения (terminal, execute_code).
required_environment_variables:
- name: TENOR_API_KEY
prompt: "Tenor API key" # Текст при запросе у пользователя
help: "Get your key at https://tenor.com" # Справка или ссылка
required_for: "GIF search functionality" # Для чего нужна переменная
Каждая запись поддерживает:
name(обязательно) — имя переменной окруженияprompt(опционально) — текст при запросе значения у пользователяhelp(опционально) — справка или ссылка для получения значенияrequired_for(опционально) — описание, какая функция требует переменную
Пробросить переменные можно и вручную, через config.yaml:
terminal:
env_passthrough:
- MY_CUSTOM_VAR
- ANOTHER_VAR
Примеры навыков только для macOS — в skills/apple/.
Безопасная настройка при загрузке
Используй required_environment_variables, если навыку нужен API-ключ или токен. Отсутствие значений не скрывает навык из поиска. Hermes запросит их безопасно при загрузке навыка в локальном CLI.
required_environment_variables:
- name: TENOR_API_KEY
prompt: Tenor API key
help: Get a key from https://developers.google.com/tenor
required_for: full functionality
Пользователь может пропустить настройку и продолжить загрузку навыка. Сырое значение секрета модели не передаётся никогда. В сессиях шлюза и мессенджеров вместо запроса секрета прямо в чате показывается инструкция по локальной настройке.
Когда навык загружается, все объявленные required_environment_variables со значениями автоматически пробрасываются в sandbox-среды execute_code и terminal — включая удалённые бэкенды вроде Docker и Modal. Скрипты навыка обращаются к $TENOR_API_KEY (или os.environ["TENOR_API_KEY"] в Python) без какой-либо дополнительной настройки со стороны пользователя. Подробнее — в Проброс переменных окружения.
Устаревший синтаксис prerequisites.env_vars по-прежнему поддерживается как обратно совместимый псевдоним.
Настройки конфигурации (config.yaml)
Навык может объявлять несекретные параметры, которые хранятся в config.yaml в пространстве имён skills.config. В отличие от переменных окружения (это секреты в .env), настройки конфигурации нужны для путей, предпочтений и прочих незащищённых значений.
metadata:
hermes:
config:
- key: myplugin.path
description: Путь к каталогу данных плагина
default: "~/myplugin-data"
prompt: Путь к каталогу данных плагина
- key: myplugin.domain
description: Домен, в котором работает плагин
default: ""
prompt: Домен плагина (например, AI/ML research)
Каждая запись поддерживает:
key(обязательно) — путь к параметру через точку (например,myplugin.path)description(обязательно) — пояснение, что контролирует параметрdefault(опционально) — значение по умолчанию, если пользователь не настраивалprompt(опционально) — текст запроса приhermes config migrate; если не задан, используетсяdescription
Как это работает:
-
Хранение: значения записываются в
config.yamlподskills.config.<key>:skills: config: myplugin: path: ~/my-data -
Обнаружение:
hermes config migrateсканирует все включённые навыки, находит ненастроенные параметры и запрашивает значения у пользователя. Параметры также видны вhermes config showв разделе «Настройки навыков». -
Инъекция при выполнении: когда навык загружается, значения конфигурации разрешаются и добавляются к сообщению навыка:
[Skill config (from ~/.hermes/config.yaml): myplugin.path = /home/user/my-data ]Настроенные значения видны агенту, и самому читать
config.yamlему не нужно. -
Ручная настройка: значения можно задать и напрямую:
hermes config set skills.config.myplugin.path ~/my-data
required_environment_variables — для API-ключей, токенов и других секретов (хранятся в ~/.hermes/.env, модели не передаются). config — для путей, предпочтений и несекретных параметров (хранятся в config.yaml, видны через config show).
Требования к файлам учётных данных (OAuth-токены и др.)
Навыки, использующие OAuth или файловые учётные данные, могут объявлять файлы для монтирования в удалённые sandbox-среды. Это касается учётных данных в виде файлов (не переменных окружения) — обычно OAuth-токенов, созданных скриптом настройки.
required_credential_files:
- path: google_token.json
description: Google OAuth2 token (created by setup script)
- path: google_client_secret.json
description: Google OAuth2 client credentials
Каждая запись поддерживает:
path(обязательно) — путь к файлу относительно~/.hermes/description(опционально) — пояснение, что это за файл и как он создаётся
При загрузке Hermes проверяет наличие файлов. Если их нет — выдаётся setup_needed. Существующие файлы автоматически:
- Монтируются в Docker-контейнеры как bind-монтирования только для чтения
- Синхронизируются в Modal-sandbox (при создании и перед каждой командой — поэтому OAuth работает и в процессе сессии)
- Доступны на локальном бэкенде без каких-либо дополнительных действий
required_environment_variables — для простых API-ключей и токенов (строки в ~/.hermes/.env). required_credential_files — для OAuth-токенов, client secrets, service account JSON, сертификатов и любых учётных данных, лежащих на диске как файл.
Полный пример с обоими механизмами — в skills/productivity/google-workspace/SKILL.md.
Рекомендации по написанию навыков
Без внешних зависимостей
Отдавай предпочтение стандартной библиотеке Python, curl и встроенным инструментам Hermes (web_extract, terminal, read_file). Если зависимость всё же нужна — опиши шаги установки прямо в навыке.
Постепенное раскрытие
Начинай с самого частого сценария. Граничные случаи и продвинутые опции — в конце. Так расход токенов на типовые задачи остаётся минимальным.
Включай вспомогательные скрипты
Для разбора XML/JSON или сложной логики добавляй вспомогательные скрипты в scripts/ — не рассчитывай, что LLM каждый раз будет писать парсеры прямо в ответе.
Отдавай медиа как документы ([[as_document]])
Навык выдаёт скриншот в высоком разрешении, график или другое изображение, для которого потери при сжатии нежелательны? Добавь директиву [[as_document]] где-нибудь в ответе (обычно последней строкой). Шлюз уберёт директиву и доставит все извлечённые из этого ответа медиафайлы как вложения для скачивания, а не как встроенные превью. Подробнее — в Вывод навыков и доставка медиа.
Ссылки на встроенные скрипты из SKILL.md
При загрузке навыка сообщение об активации раскрывает абсолютный путь к каталогу навыка как [Skill directory: /abs/path], а также подставляет два шаблонных токена в любом месте тела SKILL.md:
| Токен | Заменяется на |
|---|---|
${HERMES_SKILL_DIR} | Абсолютный путь к каталогу навыка |
${HERMES_SESSION_ID} | Идентификатор текущей сессии (если сессии нет — оставляется как есть) |
Благодаря этому SKILL.md может дать агенту команду запустить встроенный скрипт напрямую:
Для анализа входных данных выполни:
node ${HERMES_SKILL_DIR}/scripts/analyse.js <input>
Агент видит подставленный абсолютный путь и вызывает инструмент terminal с готовой командой — без вычисления путей и лишних запросов skill_view. Подстановку можно отключить глобально через skills.template_vars: false в config.yaml.
Встроенные shell-сниппеты (включаются явно)
Навыки также могут встраивать shell-сниппеты в формате !`cmd` прямо в тело SKILL.md. Если функция включена, вывод каждого сниппета вставляется в сообщение до того, как его прочитает агент, — так навык подаёт динамический контекст:
Current date: !`date -u +%Y-%m-%d`
Git branch: !`git -C ${HERMES_SKILL_DIR} rev-parse --abbrev-ref HEAD`
По умолчанию функция отключена — любой сниппет в SKILL.md выполняется на хосте без подтверждения, поэтому включай её только для источников навыков, которым доверяешь:
# config.yaml
skills:
inline_shell: true
inline_shell_timeout: 10 # секунд на один сниппет
Сниппеты выполняются с рабочим каталогом навыка, вывод обрезается до 4000 символов. Если что-то пошло не так (тайм-аут, ненулевой код выхода), вместо сбоя всего навыка появляется короткая пометка [inline-shell error: ...].
Тестируй
Запусти навык и убедись, что агент корректно следует инструкциям:
hermes chat --toolsets skills -q "Use the X skill to do Y"
Где должен жить навык?
Встроенные навыки (в skills/) поставляются с каждой установкой Hermes. Они должны быть полезны большинству пользователей:
- Работа с документами, веб-исследования, типовые dev-процессы, системное администрирование
- Регулярно используются широкой аудиторией
Навык официальный и полезный, но нужен не всем поголовно (например, интеграция с платным сервисом или тяжёлая зависимость)? Помести его в optional-skills/. Он поставляется вместе с репозиторием, виден через hermes skills browse (с пометкой «official») и устанавливается с встроенным доверием.
Специализированные, нишевые или созданные сообществом навыки лучше подходят для Skills Hub — загрузи их в реестр и делись через hermes skills install.
Шаблоны автоматизации: навыки, которые ещё и автоматизации
Шаблон автоматизации — это обычный навык, у которого в frontmatter дополнительно объявлено расписание. Добавь блок metadata.hermes.blueprint, и навык превращается в автоматизацию, которой можно делиться и которую можно запускать:
metadata:
hermes:
tags: [blueprint, email]
blueprint:
schedule: "0 8 * * *" # сам факт наличия `blueprint:` делает навык запускаемым
deliver: telegram # опционально (по умолчанию: origin)
prompt: "Summarize my unread email and today's calendar." # опционально
no_agent: false # опционально
Раз шаблон остаётся навыком, он без изменений проходит весь конвейер навыков — поиск, просмотр, установку, сканирование безопасности, проверку происхождения, источники (taps), централизованный индекс и hermes skills publish для обмена. Учить ничего нового не нужно.
Установка шаблона. Когда устанавливаешь навык с блоком blueprint:, Hermes регистрирует его как предлагаемую задачу cron, а не планирует сразу. Планирование — по запросу: установка никогда молча не создаёт повторяющуюся задачу. Предложение разбираешь и принимаешь через /suggestions:
hermes skills install owner/morning-brief
# → Blueprint: 'morning-brief' is an automation (schedule 0 8 * * *).
# Added to your suggestions — run /suggestions to schedule or dismiss it.
# затем, в сессии:
/suggestions # перечисляет ожидающие предложения, пронумерованные
/suggestions accept 1 # создаёт задачу cron
/suggestions dismiss 1 # больше не предлагать
Шаблон — один из источников единой поверхности «Предлагаемые задачи cron»: туда же попадают подобранные стартовые автоматизации и (позже) предложения по паттернам использования и интеграциям. См. Предлагаемые задачи cron ниже.
Как поделиться собранной автоматизацией. Шаблон, загруженный задачей cron (hermes cron create --skill <name> ...), можно экспортировать обратно в SKILL.md и опубликовать, как любой другой навык, — так настроенная под себя автоматизация становится установкой в одну команду для кого-то ещё.
Слой шаблонов не вводит ни нового типа объекта, ни хранилища, ни транспорта: шаблон — это навык, расписание — это задача cron, а обмен идёт по уже существующему пути publish/tap/index.
Предлагаемые задачи cron
Hermes умеет предлагать автоматизации и принимать их в одно нажатие — вместо того, чтобы собирать задачи cron вручную. Любое предложение проходит через одну поверхность — команду /suggestions — откуда бы оно ни пришло:
| Источник | Триггер |
|---|---|
catalog | Подобранные стартовые автоматизации (/suggestions catalog) — ежедневная сводка, монитор важной почты, еженедельный обзор, напоминание в начале рабочего дня |
blueprint | Ты установил навык с блоком blueprint: |
usage | Фоновый анализ заметил повторяющийся запрос, который закрыло бы расписание |
integration | Ты подключил аккаунт (Gmail, GitHub, …), и предлагаются очевидные автоматизации |
/suggestions # список ожидающих
/suggestions accept N # запланировать предложение N (создаёт задачу cron)
/suggestions dismiss N # отклонить — с защёлкой, повторно не предлагается
/suggestions catalog # добавить подобранные стартовые автоматизации
Принятие предложения вызывает тот же cron.jobs.create_job, что и инструмент cronjob, — второго движка задач нет. Предложения никогда не создают задачи автоматически; принятие всегда явное. Отклонённые предложения защёлкиваются по устойчивому ключу, поэтому одно и то же предложение повторно не всплывает. Список ожидающих ограничен по длине, так что он не превращается в стену из назойливых напоминаний.
Запись каталога монитор важной почты — это паттерн «опрос → классификация → показ»: она оценивает письма во входящих дешёвой моделью-классификатором (auxiliary.monitor в config.yaml) и доставляет лишь те, что выше порога срочности, в остальное время молчит.
Публикация навыков
В Skills Hub
hermes skills publish skills/my-skill --to github --repo owner/repo
В собственный репозиторий
Добавь свой репозиторий как источник:
hermes skills tap add owner/repo
После этого пользователи смогут искать и устанавливать навыки из твоего репозитория.
Проверка безопасности
Все навыки, установленные из хаба, проходят сканер безопасности, который проверяет:
- Паттерны эксфильтрации данных
- Попытки prompt-инъекций
- Деструктивные команды
- Shell-инъекции
Уровни доверия:
builtin— поставляется с Hermes (всегда доверенный)official— изoptional-skills/в репозитории (встроенное доверие, без предупреждений о сторонних источниках)trusted— из openai/skills, anthropics/skills, huggingface/skillscommunity— некритичные находки можно пропустить через--force; вердиктыdangerousостаются заблокированными
Hermes умеет подтягивать сторонние навыки из нескольких источников:
- прямые идентификаторы GitHub (например,
openai/skills/k8s) - идентификаторы
skills.sh(например,skills-sh/vercel-labs/json-render/json-render-react) - well-known эндпоинты, отдающие
/.well-known/skills/index.json
Хочешь, чтобы твои навыки находились без GitHub-специфичного установщика? Помимо публикации в репозитории или маркетплейсе размести их на well-known эндпоинте.