Добавление провайдеров
Hermes уже может общаться с любым OpenAI-совместимым endpoint через путь пользовательского провайдера. Не добавляйте встроенный провайдер, если только вы не хотите обеспечить первоклассный пользовательский опыт для этого сервиса:
- аутентификация или обновление токена, специфичные для провайдера
- курируемый каталог моделей
- пункты меню настройки /
hermes model - псевдонимы провайдеров для синтаксиса
provider:model - форма API, отличная от OpenAI, требующая адаптера
Если провайдер — это просто «ещё один OpenAI-совместимый базовый URL и API-ключ», может быть достаточно именованного пользовательского провайдера.
Ментальная модель
Встроенный провайдер должен быть согласован на нескольких уровнях:
hermes_cli/auth.pyопределяет, как находятся учётные данные.hermes_cli/runtime_provider.pyпреобразует их в данные времени выполнения:providerapi_modebase_urlapi_keysourcerun_agent.pyиспользуетapi_modeдля принятия решения о том, как строить и отправлять запросы.hermes_cli/models.pyиhermes_cli/main.pyобеспечивают появление провайдера в CLI. (hermes_cli/setup.pyделегирует полномочияmain.pyавтоматически — изменения там не нужны.)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_responsesanthropic_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/💡 Tip
hermes_cli/setup.pyне требует изменений. Мастер настройки делегирует выбор провайдера/модели функцииselect_provider_and_model()вmain.py— любой провайдер, добавленный туда, автоматически доступен вhermes setup.
Дополнительно для нативных / не-OpenAI провайдеров
agent/<provider>_adapter.pyrun_agent.pypyproject.toml, если требуется SDK провайдера
Быстрый путь: Провайдеры с простым API-ключом
Если ваш провайдер — это просто OpenAI-совместимый endpoint, который аутентифицируется с помощью одного API-ключа, вам не нужно трогать auth.py, runtime_provider.py, main.py или любые другие файлы из полного списка ниже.
Всё, что вам нужно:
- Директория плагина в
plugins/model-providers/<your-provider>/, содержащая: __init__.py— вызываетregister_provider(profile)на уровне модуляplugin.yaml— манифест (name, kind: model-provider, version, description)- Вот и всё. Плагины провайдеров автоматически загружаются при первом вызове
get_provider_profile()илиlist_providers()— как встроенные плагины (этот репозиторий), так и пользовательские плагины в$HERMES_HOME/plugins/model-providers/.
Когда вы добавляете плагин и вызываете register_provider(), автоматически настраиваются следующие вещи:
- Запись в
PROVIDER_REGISTRYвauth.py(разрешение учётных данных, поиск переменных окружения) api_modeустанавливается вchat_completionsbase_urlберётся из конфигурации или объявленной переменной окруженияenv_varsпроверяются в порядке приоритета для API-ключа- Список
fallback_modelsрегистрируется для провайдера - Флаг CLI
--providerпринимает идентификатор провайдера - Меню
hermes modelвключает провайдера - Мастер
hermes setupделегирует полномочияmain.pyавтоматически - Синтаксис псевдонима
provider:modelработает - Разрешатель времени выполнения возвращает правильные
base_urlиapi_key - Переопределение переменной окружения
HERMES_INFERENCE_PROVIDERпринимает идентификатор провайдера - Активация резервной модели может чисто переключиться на провайдера
Пользовательские плагины в $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)
- Форма API, отличная от OpenAI, требующая нового адаптера (Anthropic Messages, Codex Responses)
- Пользовательское обнаружение endpoint или многозондовое тестирование (z.ai, Kimi)
- Курируемый статический каталог моделей или динамическая загрузка
/models - Пункты меню
hermes model, специфичные для провайдера, с собственными потоками аутентификации
Шаг 1: Выберите один канонический идентификатор провайдера
Выберите один идентификатор провайдера и используйте его везде.
Примеры из репозитория:
openai-codexkimi-codingminimax-cn
Этот же идентификатор должен появиться в:
PROVIDER_REGISTRYвhermes_cli/auth.py_PROVIDER_LABELSвhermes_cli/models.py_PROVIDER_ALIASESв обоих файлахhermes_cli/auth.pyиhermes_cli/models.py- выборах
--providerCLI вhermes_cli/main.py - ветках настройки / выбора модели
- настройках вспомогательной модели по умолчанию
- тестах
Если идентификатор различается между этими файлами, провайдер будет казаться наполовину подключённым: аутентификация может работать, а /model, настройка или разрешение времени выполнения будут молча его пропускать.
Шаг 2: Добавьте метаданные аутентификации в hermes_cli/auth.py
Для провайдеров с API-ключом добавьте запись ProviderConfig в PROVIDER_REGISTRY с:
idnameauth_type="api_key"inference_base_urlapi_key_env_vars- опционально
base_url_env_var
Также добавьте псевдонимы в _PROVIDER_ALIASES.
Используйте существующих провайдеров в качестве шаблонов:
- простой путь с API-ключом: Z.AI, MiniMax
- путь с API-ключом и обнаружением endpoint: Kimi, Z.AI
- нативное разрешение токенов: Anthropic
- путь OAuth / хранилище аутентификации: Nous, OpenAI Codex
Вопросы, на которые нужно ответить здесь:
- Какие переменные окружения должна проверять Hermes и в каком порядке приоритета?
- Нужны ли провайдеру переопределения базового URL?
- Нужно ли ему зондирование endpoint или обновление токенов?
- Что должно говорить сообщение об ошибке аутентификации, когда учётные данные отсутствуют?
Если провайдеру нужно нечто большее, чем «найти API-ключ», добавьте специальный разрешатель учётных данных, а не втискивайте логику в несвязанные ветки.
Шаг 3: Добавьте каталог моделей и псевдонимы в hermes_cli/models.py
Обновите каталог провайдера, чтобы провайдер работал в меню и в синтаксисе provider:model.
Типичные изменения:
_PROVIDER_MODELS_PROVIDER_LABELS_PROVIDER_ALIASES- порядок отображения провайдера внутри
list_available_providers() provider_model_ids(), если провайдер поддерживает динамическую загрузку/models
Если провайдер предоставляет список живых моделей, отдавайте предпочтение ему, а _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:
- словарь
provider_labels - список
providersвselect_provider_and_model() - диспетчеризация провайдера (
if selected_provider ==...) - аргументы
--provider - выборы входа/выхода, если провайдер поддерживает эти потоки
- функцию
_model_flow_<provider>()или повторное использование_model_flow_api_key_provider(), если она подходит💡 Tip
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()отправляет запрос правильному клиенту- пути прерывания / перестроения клиента работают
- проверка ответа принимает формат провайдера
- извлечение причины завершения корректно
- извлечение использования токенов корректно
- активация резервной модели может чисто переключиться на нового провайдера
- пути генерации суммаризации и сброса памяти всё ещё работают
Также выполните поиск self.client. в run_agent.py. Любой путь кода, который предполагает существование стандартного клиента OpenAI, может сломаться, если нативный провайдер использует другой объект клиента или self.client = None.
Кэширование подсказок и поля запроса, специфичные для провайдера
Кэширование подсказок и специфические для провайдера настройки легко сломать.
Примеры уже в дереве:
- Anthropic имеет нативный путь кэширования подсказок
- OpenRouter получает поля маршрутизации провайдера
- не каждый провайдер должен получать все опции со стороны запроса
Когда вы добавляете нативного провайдера, дважды проверьте, что Hermes отправляет только те поля, которые этот провайдер действительно понимает.
Шаг 8: Тесты
Как минимум, затроньте тесты, которые защищают подключение провайдера.
Обычные места:
tests/test_runtime_provider_resolution.pytests/test_cli_provider_resolution.pytests/test_cli_model_command.pytests/test_setup_model_selection.pytests/test_provider_parity.pytests/test_run_agent.pytests/test_<provider>_adapter.pyдля нативного провайдера
Для примеров, ориентированных на документацию, точный набор файлов может отличаться. Суть в том, чтобы охватить:
- разрешение аутентификации
- меню CLI / выбор провайдера
- разрешение провайдера во время выполнения
- путь выполнения агента
- разбор
provider:model - любое специфическое для адаптера преобразование сообщений
Запустите тесты с отключённым 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: Обновите пользовательскую документацию
Если провайдер предназначен для поставки как лучший вариант, обновите также пользовательскую документацию:
сайт/документы/начало работы/quickstart.mdсайт/документы/пользователь-руководство/configuration.mdвеб-сайт/документы/ссылка/среда-переменные.md
Разработчик может идеально подключить провайдера, но оставить пользователей неспособными обеспечить необходимые переменные окружения или настройки температуры.
Контрольный список OpenAI-совместимого провайдера
Используйте это, если провайдер — это стандартные завершения чата.
- [ ]
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 - [ ] путь прерывания / перестроения работает
- [ ] извлечение использования и причины завершения работы
- [ ] путь резервного копирования работает
- [ ] добавлены тесты адаптера
- [ ] живое прохождение дымового теста
Частые ошибки
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
Оба потока необходимо знать о провайдере.
Полезные цели поиска при реализации
Если вы ищете все места, касающиеся провайдера, выполните поиск по этим символам:
PROVIDER_REGISTRY_PROVIDER_ALIASES_PROVIDER_MODELSresolve_runtime_provider_model_flow_select_provider_and_modelapi_mode_API_KEY_PROVIDER_AUX_MODELSсам.клиент.