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 для построения запроса, отправки, извлечения использования, обработки прерываний и нормализации ответа
* тесты адаптера
Контрольный список файлов¶
Обязательно для каждого встроенного провайдера¶
hermes_cli/auth.pyhermes_cli/models.pyhermes_cli/runtime_provider.pyhermes_cli/main.pyagent/auxiliary_client.pyagent/model_metadata.py- тесты
- пользовательская документация в
website/docs/
совет
hermes_cli/setup.py не нуждается в изменениях. Мастер настройки делегирует выбор провайдера/модели функции select_provider_and_model() в main.py — любой провайдер, добавленный туда, автоматически становится доступен в hermes setup.
Дополнительно для нативных / не-OpenAI провайдеров¶
agent/<provider>_adapter.pyrun_agent.pypyproject.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.
Связанная документация¶
- Разрешение провайдера во время выполнения
- Архитектура
- Сначала выберите путь реализации
- Контрольный список файлов
- Быстрый путь: Провайдеры с простым API-ключом
- Полный путь: OAuth и сложные провайдеры
- Шаг 1: Выберите один канонический ID провайдера
- Шаг 2: Добавьте метаданные аутентификации в
hermes_cli/auth.py - Шаг 3: Добавьте каталог моделей и псевдонимы в
hermes_cli/models.py - Шаг 4: Разрешите данные времени выполнения в
hermes_cli/runtime_provider.py - Шаг 5: Подключите CLI в
hermes_cli/main.py - Шаг 6: Обеспечьте работу вспомогательных вызовов
- Шаг 7: Если провайдер нативный, добавьте адаптер и поддержку в
run_agent.py - Шаг 8: Тесты
- Шаг 9: Живая проверка
- Шаг 10: Обновите пользовательскую документацию
- Контрольный список OpenAI-совместимого провайдера
- Контрольный список нативного провайдера
- Распространённые ошибки
- 1. Добавление провайдера в auth, но не в разбор моделей
- 2. Забывание, что
config["model"]может быть строкой или словарём - 3. Предположение, что встроенный провайдер обязателен
- 4. Забывание вспомогательных путей
- 5. Ветки нативного провайдера, спрятанные в
run_agent.py - 6. Отправка параметров, специфичных только для OpenRouter, другим провайдерам
- 7. Обновление
hermes model, но неhermes setup
- Хорошие цели для поиска при реализации
- Связанная документация