
Hermes Agent я использую как основной «агентный комбайн». Долгое время он крутился на DeepSeek, но захотелось экспериментов с LLM - первое за что взялся GigaChat от Сбера: русский язык, российская юрисдикция и огромное количество токенов "за красивые глаза". Казалось бы, делов-то - подставить ключ в конфиг. Но не тут-то было.
Под капотом вылезло три нюанса, из-за которых «просто подставить ключ» не работает:
- OAuth2 вместо API-ключа. У GigaChat нет статического ключа в стиле DeepSeek/OpenAI. Есть «ключ авторизации» (по сути client_id:client_secret в base64), который нужно обменивать на короткоживущий access_token (живёт ~30 минут) и периодически обновлять.
- Это не drop-in OpenAI. Формат tools/function-calling, streaming-события и список моделей у GigaChat отличаются, поэтому «направить SDK в его endpoint» напрямую не выйдет — посыплются ошибки на мелочах.
- Сертификаты Минцифры. Эндпоинты GigaChat (api.giga.chat, а также OAuth ngw.devices.sberbank.ru:9443) подписаны «Русским доверенным УЦ» (Минцифры), которого нет в стандартном CA-bundle (certifi) внутри контейнера. Любой запрос с включённой проверкой TLS падает с self-signed certificate / unable to get local issuer certificate.
Вывод напрашивается сам собой: между Hermes и GigaChat нужен свой прокси, который возьмёт на себя OAuth-обмен, трансляцию OpenAI-протокола и работу с сертификатами.
Этап 1. Берём готовый шлюз gpt2giga
Писать трансляцию OpenAI → GigaChat с нуля — так себе идея: слишком много подводных камней в маппинге tools, streaming и списка моделей. К счастью, у ai-forever есть зрелый проект gpt2giga - FastAPI-прокси, который:
- принимает OpenAI-совместимые (а также Anthropic/Gemini) запросы и переводит их в GigaChat;
- сам делает OAuth-обмен и обновляет токен по истечении;
- фильтрует транспортные заголовки и отделяет API-ключ прокси от учёток GigaChat;
- отдаёт /models, /chat/completions, /embeddings в OpenAI-виде.
Этап 2. Модели
Актуальный список моделей смотрим через сам прокси (после первого пробного запуска):
curl -s http://127.0.0.1:8090/v1/models -H "Authorization: Bearer $GPT2GIGA_API_KEY"
На момент написания это: GigaChat-2, GigaChat-2-Max, GigaChat-2-Pro, GigaChat-3-Lightning, GigaChat-3-Pro, GigaChat-3-Ultra (+ эмбеддинги EmbeddingsGigaR и др.).
Этап 3. Сертификаты Минцифры (та самая особенность)
Дефолтный certifi внутри python:*-slim-образа gpt2giga не знает про корневой сертификат Минцифры. Первый же запрос в GigaChat с GIGACHAT_VERIFY_SSL_CERTS=True умирает:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain
Самый простой «костыль» — поставить GIGACHAT_VERIFY_SSL_CERTS=False. Но это отключает проверку TLS целиком: между вашим сервером и Сбером появляется возможность MITM. Для LLM-прокси, через который идут мои данные, так делать не хочется.
Решение — подложить нужные сертификаты:
Качаем корневой и промежуточные сертификаты с Госуслуг
Кладём их в
crt/рядом с compose-файлом.Собираем из них единый CA-bundle (они в PEM, так что это просто конкатенация):
cat Russian_Trusted_Root_CA.cer Russian_Trusted_Sub_CA.cer Russian_Trusted_Sub_CA_2024.cer > gigachat-ca-bundle.pemМонтируем в контейнер (
./crt:/certs:roв compose) и указываем bundle в.env(уже сделано выше):
GIGACHAT_VERIFY_SSL_CERTS=True GIGACHAT_CA_BUNDLE_FILE=/certs/gigachat-ca-bundle.pem
Этап 4. Подключаем Hermes
Hermes подключается к прокси как к custom-провайдеру. Две вещи:
1. В hermes.env кладём ключ прокси:
GIGACHAT_PROXY_API_KEY='<тот_самый_GPT2GIGA_API_KEY>'
2. В config.yaml Hermes (HERMES_HOME=/opt/data в контейнере) прописываем провайдера и модели:
Скрытый текст
providers: gigachat: api: http://gigachat-proxy:8090/v1 # alias контейнера в сети nginx key_env: GIGACHAT_PROXY_API_KEY transport: chat_completions default_model: GigaChat-3-Lightning context_length: 131072 model: provider: custom:gigachat default: GigaChat-3-Lightning # Дополнительные модели для переключения командой /model <alias> model_aliases: max: { model: GigaChat-2-Max, provider: custom:gigachat } pro: { model: GigaChat-3-Pro, provider: custom:gigachat } ultra: { model: GigaChat-3-Ultra, provider: custom:gigachat } # Если GigaChat недоступен — откат на DeepSeek fallback_providers: - { provider: deepseek, model: deepseek-chat }
Небольшое наблюдение: в WebUI Hermes для custom-провайдера выпадающий список моделей показывает только модель по умолчанию — это особенность веб-интерфейса, а не конфига. Переключение на max/pro/ultra при этом работает командой в чате /model max и т.д. (алиасы подхватываются корректно).
Что в итоге
1. Поднят gigachat-proxy на базе gpt2giga — OAuth-обмен, трансляция OpenAI→GigaChat и модели под капотом.
2. Решена особенность с сертификатами: собран CA-bundle из корневого и промежуточных сертификатов Минцифры, проверка TLS осталась включённой (verify_ssl_certs=True + ca_bundle_file).
3. Hermes переведён на GigaChat (GigaChat-3-Lightning по умолчанию) с откатом на DeepSeek и переключением моделей через /model.
Бонус: тот же gigachat-proxy можно подставить в любой другой OpenAI-совместимый инструмент (OpenCode, openclaw и т.п.) — он выглядит как обычный OpenAI-эндпоинт с обычным статическим Bearer-ключом.
На всякий случай проект полностью готовый к экспуатации

