Создание навыков

Навыки — предпочтительный способ расширить возможности 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

Пользователь может пропустить настройку и продолжить загрузку навыка. Сырое значение секрета модели не передаётся никогда. В сессиях шлюза и мессенджеров вместо запроса секрета прямо в чате показывается инструкция по локальной настройке.

совет
Проброс в sandbox

Когда навык загружается, все объявленные 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

Как это работает:

  1. Хранение: значения записываются в config.yaml под skills.config.<key>:

    skills:
      config:
        myplugin:
          path: ~/my-data
  2. Обнаружение: hermes config migrate сканирует все включённые навыки, находит ненастроенные параметры и запрашивает значения у пользователя. Параметры также видны в hermes config show в разделе «Настройки навыков».

  3. Инъекция при выполнении: когда навык загружается, значения конфигурации разрешаются и добавляются к сообщению навыка:

    [Skill config (from ~/.hermes/config.yaml):
      myplugin.path = /home/user/my-data
    ]

    Настроенные значения видны агенту, и самому читать config.yaml ему не нужно.

  4. Ручная настройка: значения можно задать и напрямую:

    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/skills
  • community — некритичные находки можно пропустить через --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 эндпоинте.

ESC