Добавление провайдеров

Hermes уже может общаться с любым OpenAI-совместимым endpoint через путь пользовательского провайдера. Не добавляйте встроенный провайдер, если только вы не хотите обеспечить первоклассный пользовательский опыт для этого сервиса:

Если провайдер — это просто «ещё один OpenAI-совместимый базовый URL и API-ключ», может быть достаточно именованного пользовательского провайдера.

Ментальная модель

Встроенный провайдер должен быть согласован на нескольких уровнях:

  1. hermes_cli/auth.py определяет, как находятся учётные данные.
  2. hermes_cli/runtime_provider.py преобразует их в данные времени выполнения:
  3. provider
  4. api_mode
  5. base_url
  6. api_key
  7. source
  8. run_agent.py использует api_mode для принятия решения о том, как строить и отправлять запросы.
  9. hermes_cli/models.py и hermes_cli/main.py обеспечивают появление провайдера в CLI. (hermes_cli/setup.py делегирует полномочия main.py автоматически — изменения там не нужны.)
  10. agent/auxiliary_client.py и agent/model_metadata.py обеспечивают работу вспомогательных задач и учёт токенов.

Важная абстракция — api_mode.

Сначала выберите путь реализации

Путь A — OpenAI-совместимый провайдер

Используйте это, когда провайдер принимает стандартные запросы в стиле chat-completions.

Типичная работа:

Обычно вам не нужен новый адаптер или новый api_mode.

Путь B — Нативный провайдер

Используйте это, когда провайдер не ведёт себя как OpenAI chat completions.

Примеры в дереве сегодня:

Этот путь включает всё из Пути A, плюс:

Контрольный список файлов

Обязательно для каждого встроенного провайдера

  1. hermes_cli/auth.py
  2. hermes_cli/models.py
  3. hermes_cli/runtime_provider.py
  4. hermes_cli/main.py
  5. agent/auxiliary_client.py
  6. agent/model_metadata.py
  7. тесты
  8. пользовательская документация в website/docs/

    💡 Tip

    hermes_cli/setup.py не требует изменений. Мастер настройки делегирует выбор провайдера/модели функции select_provider_and_model() в main.py — любой провайдер, добавленный туда, автоматически доступен в hermes setup.

Дополнительно для нативных / не-OpenAI провайдеров

  1. agent/<provider>_adapter.py
  2. run_agent.py
  3. pyproject.toml, если требуется SDK провайдера

Быстрый путь: Провайдеры с простым API-ключом

Если ваш провайдер — это просто OpenAI-совместимый endpoint, который аутентифицируется с помощью одного API-ключа, вам не нужно трогать auth.py, runtime_provider.py, main.py или любые другие файлы из полного списка ниже.

Всё, что вам нужно:

  1. Директория плагина в plugins/model-providers/<your-provider>/, содержащая:
  2. __init__.py — вызывает register_provider(profile) на уровне модуля
  3. plugin.yaml — манифест (name, kind: model-provider, version, description)
  4. Вот и всё. Плагины провайдеров автоматически загружаются при первом вызове get_provider_profile() или list_providers() — как встроенные плагины (этот репозиторий), так и пользовательские плагины в $HERMES_HOME/plugins/model-providers/.

Когда вы добавляете плагин и вызываете register_provider(), автоматически настраиваются следующие вещи:

  1. Запись в PROVIDER_REGISTRY в auth.py (разрешение учётных данных, поиск переменных окружения)
  2. api_mode устанавливается в chat_completions
  3. base_url берётся из конфигурации или объявленной переменной окружения
  4. env_vars проверяются в порядке приоритета для API-ключа
  5. Список fallback_models регистрируется для провайдера
  6. Флаг CLI --provider принимает идентификатор провайдера
  7. Меню hermes model включает провайдера
  8. Мастер hermes setup делегирует полномочия main.py автоматически
  9. Синтаксис псевдонима provider:model работает
  10. Разрешатель времени выполнения возвращает правильные base_url и api_key
  11. Переопределение переменной окружения HERMES_INFERENCE_PROVIDER принимает идентификатор провайдера
  12. Активация резервной модели может чисто переключиться на провайдера

Пользовательские плагины в $HERMES_HOME/plugins/model-providers/<name>/ переопределяют встроенные плагины с тем же именем (последний записавший побеждает в register_provider()) — так что третьи лица могут модифицировать или заменять любой встроенный профиль без редактирования репозитория.

Смотрите plugins/model-providers/nvidia/ или plugins/model-providers/gmi/ в качестве шаблона и полное руководство по плагинам провайдеров моделей для справки по полям, идиомам хуков и сквозным примерам.

Полный путь: OAuth и сложные провайдеры

Используйте полный список ниже, когда вашему провайдеру требуется что-либо из следующего:

Шаг 1: Выберите один канонический идентификатор провайдера

Выберите один идентификатор провайдера и используйте его везде.

Примеры из репозитория:

Этот же идентификатор должен появиться в:

Если идентификатор различается между этими файлами, провайдер будет казаться наполовину подключённым: аутентификация может работать, а /model, настройка или разрешение времени выполнения будут молча его пропускать.

Шаг 2: Добавьте метаданные аутентификации в hermes_cli/auth.py

Для провайдеров с API-ключом добавьте запись ProviderConfig в PROVIDER_REGISTRY с:

Также добавьте псевдонимы в _PROVIDER_ALIASES.

Используйте существующих провайдеров в качестве шаблонов:

Вопросы, на которые нужно ответить здесь:

Если провайдеру нужно нечто большее, чем «найти API-ключ», добавьте специальный разрешатель учётных данных, а не втискивайте логику в несвязанные ветки.

Шаг 3: Добавьте каталог моделей и псевдонимы в hermes_cli/models.py

Обновите каталог провайдера, чтобы провайдер работал в меню и в синтаксисе provider:model.

Типичные изменения:

Если провайдер предоставляет список живых моделей, отдавайте предпочтение ему, а _PROVIDER_MODELS оставляйте как статический запасной вариант.

Этот файл также обеспечивает работу таких входных данных:

anthropic:claude-sonnet-4-6
kimi:model-name

Если псевдонимы здесь отсутствуют, провайдер может аутентифицироваться правильно, но всё равно не работать при разборе /model.

Шаг 4: Разрешите данные о времени выполнения в hermes_cli/runtime_provider.py

resolve_runtime_provider() — это общий путь, использование CLI, шлюза, cron, ACP и вспомогательных клиентов.

добавьте ветку, которая возвращает словарь как минимум с:

{
    "provider": "your-provider",
    "api_mode": "chat_completions",  # или ваш нативный режим
    "base_url": "https://...",
    "api_key": "...",
    "source": "env|portal|auth-store|explicit",
    "requested_provider": requested_provider,
}

Если провайдер совместим с OpenAI, api_mode обычно должен оставаться chat_completions.

Будьте осторожны с приоритетом API-ключа. Hermes уже содержит логику, чтобы избежать утечки ключа OpenRouter на несвязанные endpoint. Новый провайдер должен быть столь же явным в отношении того, какой ключ идёт к какому базовому URL.

Шаг 5: Подключите CLI в hermes_cli/main.py

Провайдер не будет обнаружен, пока не появится в интерактивном потоке hermes model.

Обновите это в hermes_cli/main.py:

Шаг 6: Обеспечьте работу вспомогательных вызовов

Здесь важны два файла:

agent/auxiliary_client.py

Добавьте дешёвую/быструю вспомогательную модель по умолчанию в _API_KEY_PROVIDER_AUX_MODELS, если это прямой провайдер с API-ключом.

Вспомогательные задачи включают такие вещи, как:

Если у провайдера нет разумной вспомогательной модели по умолчанию, побочные задачи могут плохо откатываться или неожиданно использовать дорогую основную модель.

agent/model_metadata.py

Добавьте длины контекста для моделей провайдера, чтобы учёт токенов, пороги сжатия и лимиты оставались разумными.

Шаг 7: Если провайдер нативный, добавьте адаптер и поддержку в run_agent.py

Если провайдер не является обычным chat completions, изолируйте специфичную для провайдера логику в agent/<provider>_adapter.py.

Сосредоточьте run_agent.py на оркестровке. Он должен вызывать вспомогательные функции адаптера, а не вручную собирать полезные нагрузки провайдера по всему файлу.

Нативный провайдер обычно требует работы в следующих местах:

Новый файл адаптера

Типичные обязанности:

run_agent.py

Выполните поиск api_mode и проверьте каждую точку переключения. Как минимум, убедитесь:

Также выполните поиск self.client. в run_agent.py. Любой путь кода, который предполагает существование стандартного клиента OpenAI, может сломаться, если нативный провайдер использует другой объект клиента или self.client = None.

Кэширование подсказок и поля запроса, специфичные для провайдера

Кэширование подсказок и специфические для провайдера настройки легко сломать.

Примеры уже в дереве:

Когда вы добавляете нативного провайдера, дважды проверьте, что Hermes отправляет только те поля, которые этот провайдер действительно понимает.

Шаг 8: Тесты

Как минимум, затроньте тесты, которые защищают подключение провайдера.

Обычные места:

Для примеров, ориентированных на документацию, точный набор файлов может отличаться. Суть в том, чтобы охватить:

Запустите тесты с отключённым xdist:

source venv/bin/activate
python -m pytest tests/test_runtime_provider_resolution.py tests/test_cli_provider_resolution.py tests/test_cli_model_command.py tests/test_setup_model_selection.py -n0 -q

Для более обоснованных изменений запустите полный набор перед отправкой:

source venv/bin/activate
python -m pytest tests/ -n0 -q

Шаг 9: Проверка живости

После испытаний проведите настоящий дымовой тест.

source venv/bin/activate
python -m hermes_cli.main chat -q "Say hello" --provider your-provider --model your-model

Также проверьте интерактивные потоки, если вы меняли меню:

source venv/bin/activate
python -m hermes_cli.main model
python -m hermes_cli.main setup

Для местных провайдеров проверьте также, хотя бы один инструмент вызова, а не только ответ в виде простого текста.

Шаг 10: Обновите пользовательскую документацию

Если провайдер предназначен для поставки как лучший вариант, обновите также пользовательскую документацию:

Разработчик может идеально подключить провайдера, но оставить пользователей неспособными обеспечить необходимые переменные окружения или настройки температуры.

Контрольный список OpenAI-совместимого провайдера

Используйте это, если провайдер — это стандартные завершения чата.

Контрольный список родного провайдера

Используйте это, когда провайдеру понадобится новый путь протокола.

Частые ошибки

1. Добавление провайдера в аутентификацию, но не в разбор моделей

Это приводит к тому, что учётные данные разрешаются правильно, а /model и входные данные provider:model терпят неудачу.

2. Забывание, что config["model"] может быть строковой или словарём

Большая часть кода выбора провайдера должна нормализовать обе формы.

3. Предложение, что встроенный провайдер обязателен

Если сервис просто совместим с OpenAI, пользовательский провайдер уже может решить проблему пользователя с учетом затрат на поддержку.

4. Забывание вспомогательных путей

Основной путь чата может работать во время более медленной обработки, сброса памяти или помощников по зрению терпят неудачу, потому что маршрутизация вспомогательных задач никогда не обновлялась.

5. Ветки нативного провайдера, спрятанные в run_agent.py

Выполните поиск api_mode и self.client.. Не предполагайте, что очевидный путь запроса —единственный.

6. Отправка настроек, предназначенных только для OpenRouter, другим провайдерам

Такие поля, как маршрутизация провайдера, принадлежат только тем провайдерам, которые их применяют.

7. Обновление hermes model, но не hermes setup

Оба потока необходимо знать о провайдере.

Полезные цели поиска при реализации

Если вы ищете все места, касающиеся провайдера, выполните поиск по этим символам:

Связанные документы