Перейти к содержанию

Providers

На этой странице Hermes уже может взаимодействовать с любой OpenAI-совместимой конечной точкой через путь пользовательского провайдера. Не добавляйте встроенный провайдер, если только вы не хотите обеспечить первоклассный пользовательский опыт для этого сервиса: * аутентификация или обновление токенов, специфичные для провайдера * курируемый каталог моделей * пункты меню настройки / hermes model * псевдонимы провайдера для синтаксиса provider:model * не-OpenAI форма API, требующая адаптера

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

Модель​

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

Важная абстракция — api_mode. * Большинство провайдеров используют chat_completions. * Codex использует codex_responses. * Anthropic использует anthropic_messages. * Новый не-OpenAI протокол обычно означает добавление нового адаптера и новой ветки api_mode.

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

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

Используйте этот путь, когда провайдер принимает стандартные запросы в стиле chat completions. Типичная работа: * добавление метаданных аутентификации * добавление каталога моделей / псевдонимов * добавление разрешения во время выполнения * подключение меню CLI * добавление значений по умолчанию для вспомогательных моделей * добавление тестов и пользовательской документации

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

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

Используйте этот путь, когда провайдер не ведёт себя как OpenAI chat completions. Примеры в дереве сегодня: * codex_responses * anthropic_messages

Этот путь включает всё из Пути A плюс: * адаптер провайдера в agent/ * ветки в run_agent.py для построения запроса, отправки, извлечения использования, обработки прерываний и нормализации ответа * тесты адаптера

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

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

  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/

совет 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-совместимая конечная точка, аутентифицирующаяся одним API-ключом, вам не нужно трогать auth.py, runtime_provider.py, main.py или любые другие файлы из полного контрольного списка ниже. Всё, что нужно: 1. Директория плагина в plugins/model-providers/<your-provider>/, содержащая: * __init__.py — вызывает register_provider(profile) на уровне модуля * plugin.yaml — манифест (name, kind: model-provider, version, description) 2. Это всё. Плагины провайдеров автоматически загружаются при первом вызове 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. Флаг --provider CLI принимает ID провайдера 7. Меню hermes model включает провайдера 8. Мастер hermes setup автоматически делегирует вызовы main.py 9. Синтаксис псевдонимов provider:model работает 10. Разрешитель времени выполнения возвращает корректные base_url и api_key 11. Переопределение через переменную окружения HERMES_INFERENCE_PROVIDER принимает ID провайдера 12. Активация резервной модели может чисто переключиться на провайдера

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

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

Используйте полный контрольный список ниже, когда вашему провайдеру требуется что-либо из следующего: * OAuth или обновление токенов (Nous Portal, Codex, Google Gemini, Qwen Portal, Copilot) * Не-OpenAI форма API, требующая нового адаптера (Anthropic Messages, Codex Responses) * Пользовательское обнаружение конечной точки или многорегиональное зондирование (z.ai, Kimi) * Курируемый статический каталог моделей или динамический запрос /models * Пункты меню hermes model, специфичные для провайдера, с собственными потоками аутентификации

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

Выберите один ID провайдера и используйте его везде. Примеры из репозитория: * openai-codex * kimi-coding * minimax-cn

Этот же ID должен появляться в: * PROVIDER_REGISTRY в hermes_cli/auth.py * _PROVIDER_LABELS в hermes_cli/models.py * _PROVIDER_ALIASES и в hermes_cli/auth.py, и в hermes_cli/models.py * параметрах --provider CLI в hermes_cli/main.py * ветках настройки / выбора модели * значениях по умолчанию для вспомогательных моделей * тестах

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

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

Для провайдеров с API-ключом добавьте запись ProviderConfig в PROVIDER_REGISTRY с: * id * name * auth_type="api_key" * inference_base_url * api_key_env_vars * опционально base_url_env_var

Также добавьте псевдонимы в _PROVIDER_ALIASES. Используйте существующих провайдеров в качестве шаблонов: * простой путь с API-ключом: Z.AI, MiniMax * путь с API-ключом и обнаружением конечной точки: Kimi, Z.AI * нативное разрешение токенов: Anthropic * путь OAuth / хранилище аутентификации: Nous, OpenAI Codex

Вопросы, на которые нужно ответить здесь: * Какие переменные окружения должен проверять Hermes и в каком порядке приоритета? * Нужны ли провайдеру переопределения базового URL? * Требуется ли обнаружение конечной точки или обновление токенов? * Что должно быть в сообщении об ошибке аутентификации, когда учётные данные отсутствуют?

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

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

Обновите каталог провайдера, чтобы провайдер работал в меню и в синтаксисе provider:model. Типичные правки: * _PROVIDER_MODELS * _PROVIDER_LABELS * _PROVIDER_ALIASES * порядок отображения провайдера внутри list_available_providers() * provider_model_ids(), если провайдер поддерживает динамический запрос /models

Если провайдер предоставляет динамический список моделей, отдавайте ему предпочтение и оставляйте _PROVIDER_MODELS в качестве статического запасного варианта. Этот файл также отвечает за работу таких вводов: [code] anthropic:claude-sonnet-4-6
kimi:model-name

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

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

resolve_runtime_provider() — это общий путь, используемый CLI, gateway, cron, ACP и вспомогательными клиентами. Добавьте ветку, возвращающую словарь как минимум с: [code] {
"provider": "your-provider",
"api_mode": "chat_completions", # или ваш нативный режим
"base_url": "https://...",
"api_key": "...",
"source": "env|portal|auth-store|explicit",
"requested_provider": requested_provider,
}

[/code] Если провайдер OpenAI-совместимый, api_mode обычно должен оставаться chat_completions. Будьте осторожны с приоритетом API-ключа. Hermes уже содержит логику, чтобы избежать утечки ключа OpenRouter к несвязанным конечным точкам. Новый провайдер должен быть столь же явным в том, какой ключ идёт к какому базовому URL.

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

Провайдер не будет обнаружен, пока не появится в интерактивном потоке hermes model. Обновите следующее в hermes_cli/main.py: * словарь provider_labels * список providers в select_provider_and_model() * диспетчеризацию провайдера (if selected_provider == ...) * варианты аргумента --provider * варианты входа/выхода, если провайдер поддерживает такие потоки * функцию _model_flow_<provider>() или используйте _model_flow_api_key_provider(), если она подходит

совет hermes_cli/setup.py не нуждается в изменениях — он вызывает select_provider_and_model() из main.py, поэтому ваш новый провайдер появляется как в hermes model, так и в hermes setup автоматически.

Шаг 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 фокусируется на оркестрации. Он должен вызывать вспомогательные функции адаптера, а не встраивать полезные данные провайдера вручную по всему файлу. Нативный провайдер обычно требует работы в следующих местах:

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

Типичные обязанности: * создать SDK / HTTP-клиент * разрешить токены * преобразовать сообщения разговора в стиле OpenAI в формат запроса провайдера * преобразовать схемы инструментов, если необходимо * нормализовать ответы провайдера обратно в то, что ожидает run_agent.py * извлечь данные об использовании и причине завершения

run_agent.py​

Найдите api_mode и проверьте каждую точку переключения. Как минимум проверьте: * __init__ выбирает новый api_mode * создание клиента работает для провайдера * _build_api_kwargs() знает, как форматировать запросы * _interruptible_api_call() отправляет вызов правильному клиенту * пути прерывания / пересоздания клиента работают * проверка ответа принимает формат провайдера * извлечение причины завершения корректно * извлечение использования токенов корректно * активация резервной модели может чисто переключиться на нового провайдера * пути генерации суммаризации и сброса памяти всё ещё работают

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

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

Кэширование подсказок и специфические для провайдера параметры легко сломать. Примеры уже в дереве: * У Anthropic есть нативный путь кэширования подсказок * OpenRouter получает поля маршрутизации провайдера * Не каждый провайдер должен получать все опции со стороны запроса

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

Шаг 8: Тесты​

Как минимум, затроньте тесты, которые проверяют подключение провайдера. Обычные места: * tests/test_runtime_provider_resolution.py * tests/test_cli_provider_resolution.py * tests/test_cli_model_command.py * tests/test_setup_model_selection.py * tests/test_provider_parity.py * tests/test_run_agent.py * tests/test_<provider>_adapter.py для нативного провайдера

Для примеров, ориентированных только на документацию, точный набор файлов может отличаться. Суть в том, чтобы охватить: * разрешение аутентификации * меню CLI / выбор провайдера * разрешение провайдера во время выполнения * путь выполнения агента * разбор provider:model * любое преобразование сообщений, специфичное для адаптера

Запустите тесты с отключенным xdist: [code] 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

[/code] Для более глубоких изменений запустите полный набор перед отправкой: [code] source venv/bin/activate
python -m pytest tests/ -n0 -q

[/code]

Шаг 9: Живая проверка​

После тестов запустите реальный smoke-тест. [code] source venv/bin/activate
python -m hermes_cli.main chat -q "Say hello" --provider your-provider --model your-model

[/code] Также протестируйте интерактивные потоки, если вы изменили меню: [code] source venv/bin/activate
python -m hermes_cli.main model
python -m hermes_cli.main setup

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

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

Если провайдер предназначен для поставки как опция первого класса, обновите также пользовательскую документацию: * website/docs/getting-started/quickstart.md * website/docs/user-guide/configuration.md * website/docs/reference/environment-variables.md

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

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

Используйте это, если провайдер — стандартный chat completions. * ProviderConfig добавлен в hermes_cli/auth.py * псевдонимы добавлены в hermes_cli/auth.py и hermes_cli/models.py * каталог моделей добавлен в hermes_cli/models.py * ветка времени выполнения добавлена в hermes_cli/runtime_provider.py * подключение CLI добавлено в hermes_cli/main.py (setup.py наследует автоматически) * вспомогательная модель добавлена в agent/auxiliary_client.py * длины контекста добавлены в agent/model_metadata.py * тесты времени выполнения / CLI обновлены * пользовательская документация обновлена

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

Используйте это, когда провайдеру нужен новый протокольный путь. * всё из контрольного списка OpenAI-совместимого провайдера * адаптер добавлен в agent/<provider>_adapter.py * новый api_mode поддерживается в run_agent.py * путь прерывания / пересоздания работает * извлечение использования и причины завершения работает * путь резервирования работает * тесты адаптера добавлены * живой smoke-тест проходит

Распространённые ошибки​

1. Добавление провайдера в auth, но не в разбор моделей​

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

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

Много кода выбора провайдера должен нормализовать обе формы.

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

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

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

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

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

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

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

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

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

Оба потока должны знать о провайдере.

Хорошие цели для поиска при реализации​

Если вы ищете все места, которых касается провайдер, ищите эти символы: * PROVIDER_REGISTRY * _PROVIDER_ALIASES * _PROVIDER_MODELS * resolve_runtime_provider * _model_flow_ * select_provider_and_model * api_mode * _API_KEY_PROVIDER_AUX_MODELS * self.client.

Связанная документация​