Российские AI-провайдеры для OpenCode

Написано

в

OpenCode — открытый агент для программирования, который работает прямо в терминале: читает файлы проекта, правит код, запускает команды и тесты, ищет по репозиторию и работает с git. Его сильная сторона в том, что он не привязан к одному поставщику моделей и умеет подключать десятки провайдеров.

GigaChat — большая языковая модель от Сбера. В готовом списке провайдеров OpenCode её нет, но это не проблема: OpenCode подключает произвольных провайдеров через пакеты Vercel AI SDK. Для GigaChat есть пакет gigachat-ai-sdk-provider, который берёт на себя авторизацию по OAuth и обновление токена доступа. Отдельный нюанс — сертификаты Минцифры: без них Node не доверяет серверам GigaChat, и запросы падают с ошибкой проверки сертификата.

В этой заметке я опишу, как получить ключ, поставить сертификаты и подключить GigaChat к OpenCode.

Что понадобится

Для работы нужны три вещи:

  • Установленный OpenCode. Если агент ещё не стоит, порядок установки я разбирал в отдельной заметке про OpenCode и DeepSeek.
  • Аккаунт GigaChat. Регистрация в GigaChat Studio и ключ авторизации — для входа понадобится Sber ID.
  • Современный терминал. Подойдёт WezTerm, Alacritty, Ghostty, Kitty или любой другой.

Ключ авторизации GigaChat

Ключ создаётся в личном кабинете GigaChat Studio. Заходим на developers.sber.ru/studio, авторизуемся и создаём проект в разделе GigaChat API. В настройках проекта есть блок с авторизационными данными: строка, которую оттуда копируют, — это уже готовый ключ авторизации в base64. Именно он подставляется в переменную окружения, а не пара клиент-секрет по отдельности.

Вместе с ключом задаётся scope — область доступа:

  • GIGACHAT_API_PERS — для физических лиц.
  • GIGACHAT_API_B2B — для ИП и юридических лиц.
  • GIGACHAT_API_CORP — корпоративный доступ.

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

Важно понимать, что это за строка. Ключ авторизации — это не отдельный секрет, а уже закодированная в base64 пара client_id:client_secret. Библиотека gigachat-js подставляет его в OAuth-запрос заголовком:

Authorization: Basic ваш_ключ_авторизации

В ответ приходит JWE-токен доступа со сроком жизни около получаса, и дальше библиотека обновляет его автоматически. Пакет сам проверяет, что значение похоже на base64, и предупреждает, если в переменную случайно попал «сырой» client secret. Поэтому в конфиг и переменную окружения нужно передавать именно готовую base64-строку из кабинета, а не пару client_id и client_secret по отдельности.

Сертификаты Минцифры

GigaChat API использует сертификаты НУЦ Минцифры. В стандартном хранилище доверенных корней их нет, поэтому при попытке получить токен доступа запрос завершается ошибкой вида:

self-signed certificate in certificate chain

Сертификаты можно поставить на уровне операционной системы — тогда им будут доверять браузер и системные утилиты. Но OpenCode работает на Node и Bun, поэтому надёжнее и проще указать файл сертификата прямо в переменной NODE_EXTRA_CA_CERTS. Скачаем корневой и выпускающий сертификаты и сложим их в один PEM-файл:

curl -s https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt -o russian_trusted_root_ca_pem.crt
curl -s https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt -o russian_trusted_sub_ca_pem.crt
cat russian_trusted_root_ca_pem.crt russian_trusted_sub_ca_pem.crt > russian_trusted_ca_bundle.pem

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

Тут есть подвох. Скачанные файлы используют переводы строк CRLF, а у корневого сертификата нет завершающего перевода строки. Поэтому обычный cat склеивает конец первого сертификата и начало второго в одну строку:

-----END CERTIFICATE----------BEGIN CERTIFICATE-----

LibreSSL — а системный openssl на macOS, напомню, это именно LibreSSL — такой файл не принимает и отвечает ошибкой:

PEM routines:CRYPTO_internal:bad end line

Значит, одним cat не обойтись. Каждый сертификат нужно сначала прогнать через openssl: он перекодирует его в канонический PEM с переводами строк LF и завершающим переводом строки, и только потом склеивать:

openssl x509 -in russian_trusted_root_ca_pem.crt -out russian_trusted_root_ca.pem
openssl x509 -in russian_trusted_sub_ca_pem.crt -out russian_trusted_sub_ca.pem
cat russian_trusted_root_ca.pem russian_trusted_sub_ca.pem > russian_trusted_ca_bundle.pem

Проверить, что файл читается, можно так:

openssl x509 -in russian_trusted_ca_bundle.pem -noout -subject

Если сертификаты взяты из другого источника и приходят в формате DER или PKCS#7, их тоже достаточно перекодировать в PEM:

openssl x509 -in cert.crt -inform DER -outform PEM -out cert.pem
openssl pkcs7 -print_certs -in bundle.p7b -out cert.pem

Подключение к OpenCode

Провайдер описывается в конфигурационном файле opencode.jsonc. OpenCode сам скачает и подключит npm-пакет, указанный в поле npm, найдёт в нём фабрику createGigaChat и передаст ей опции. Достаточно перечислить модели по их идентификаторам из API.

Файл можно разместить в двух местах:

  • Глобально — ~/.config/opencode/opencode.jsonc. Настройки действуют для всех проектов пользователя.
  • В проекте — opencode.jsonc в корне проекта. Такой конфиг имеет больший приоритет и его безопасно коммитить в git.

Оба файла используют одну схему и объединяются: проектный перекрывает глобальный только по совпадающим ключам, остальные настройки сохраняются. Поддерживается и расширение .jsonc. Если GigaChat нужен лишь в части репозиториев, удобнее держать провайдера в проектном конфиге, а не в глобальном.

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "gigachat": {
      "npm": "gigachat-ai-sdk-provider",
      "name": "GigaChat",
      "models": {
        "GigaChat-2-Max": { "name": "GigaChat 2 Max" },
        "GigaChat-2-Pro": { "name": "GigaChat 2 Pro" },
        "GigaChat-2": { "name": "GigaChat 2 Lite" },
        "GigaChat": { "name": "GigaChat" }
      }
    }
  }
}

Здесь перечислены модели, доступные персональному ключу. Если у вас проект для ИП или юрлица с доступом к GigaChat 3, добавьте в блок models нужные идентификаторы из метода models.

Сам ключ удобнее не хранить в файле, а передавать переменной окружения: пакет gigachat-js читает её автоматически. Значение scope тоже можно задать переменной. Осталось выставить путь к сертификатам и запустить агент:

export GIGACHAT_CREDENTIALS=ваш_ключ_авторизации
export GIGACHAT_SCOPE=GIGACHAT_API_PERS
export NODE_EXTRA_CA_CERTS=/путь/к/russian_trusted_ca_bundle.pem
opencode

Такой вариант хорош ещё и тем, что секрет не оседает в локальном хранилище auth.json: он живёт только в окружении процесса. Для CI и одноразовых запусков это удобнее.

Модели

Набор доступных моделей зависит от scope ключа. Персональному ключу (GIGACHAT_API_PERS) доступно семейство GigaChat и GigaChat 2:

  • GigaChat — базовая модель.
  • GigaChat-2 — быстрая и лёгкая модель для повседневных задач, в интерфейсе отображается как Lite.
  • GigaChat-2-Pro — усовершенствованная модель для ресурсоёмких задач.
  • GigaChat-2-Max — самая мощная из доступных по персональному ключу.

Семейство GigaChat 3 (GigaChat-3-Ultra, GigaChat-3-Pro, открытые модели вроде GigaChat3.5-432B-A28B-Reasoning) видно в каталоге консоли, но персональному ключу оно недоступно: для него нужен проект ИП или юрлица со scope GIGACHAT_API_B2B или GIGACHAT_API_CORP и подходящим тарифом. На персональном ключе такая модель отвечает ошибкой:

{"status":404,"message":"No such model"}

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

curl -H "Authorization: Bearer <токен_доступа>" https://gigachat.devices.sberbank.ru/api/v1/models

Ещё два нюанса. Идентификаторы моделей в API не совпадают с отображаемыми названиями — лёгкая модель вызывается как GigaChat-2, а не GigaChat-2-Lite. И каталог в консоли показывает не то же самое, что доступно вашему ключу, поэтому ориентироваться стоит на ответ метода models, а не на список с ценами.

В интерфейсе список моделей открывается командой:

/models

Для рутины в репозитории — навигации по файлам, мелких правок, запуска тестов — вполне хватает GigaChat-2. На сложные задачи и проектирование имеет смысл переключаться на Pro или Max.

Первый запуск в проекте

Переходим в каталог проекта и запускаем агента:

cd ваш_проект
opencode

Первым делом полезно инициализировать агент:

/init

OpenCode проанализирует структуру проекта и создаст файл AGENTS.md — инструкции для агента. Этот файл стоит закоммитить в git: он помогает агенту понимать принятые в проекте соглашения и паттерны.

Альтернатива: локальный прокси

Если по каким-то причинам не хочется тянуть npm-провайдер, тот же результат даёт локальный прокси. У команды GigaChat есть официальный gpt2giga — FastAPI-сервис, который транслирует запросы в формате OpenAI, Anthropic и Gemini в GigaChat API и сам обновляет токен доступа. Он поднимается локально на порту 8090, после чего в OpenCode настраивается обычный OpenAI-совместимый провайдер через пакет @ai-sdk/openai-compatible с базовым адресом http://localhost:8090/v1. Минус этого пути в том, что рядом с OpenCode нужно держать ещё и запущенный Python-сервис.

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "gigachat": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "GigaChat (proxy)",
      "options": {
        "baseURL": "http://localhost:8090/v1"
      },
      "models": {
        "GigaChat-2-Max": { "name": "GigaChat 2 Max" }
      }
    }
  }
}

DeepSeek и другие модели через Cloud.ru

У самого GigaChat API моделей DeepSeek нет: там только семейство GigaChat и модели для эмбеддингов. Если в OpenCode нужен именно DeepSeek, но через российский облачный шлюз, подойдёт сервис Foundation Models от Cloud.ru. Он отдаёт модели по OpenAI-совместимому протоколу, поэтому подключается штатным пакетом @ai-sdk/openai-compatible.

В каталоге Cloud.ru Foundation Models есть, например, такие модели:

deepseek-ai/DeepSeek-V4.1-Flash
deepseek-ai/DeepSeek-V4-Flash
deepseek-ai/DeepSeek-V4-Pro

Ключ выпускается в консоли Cloud.ru: раздел Пользователи, вкладка Сервисные аккаунты. Создаём сервисный аккаунт уровня проекта, затем в его учётных данных создаём API-ключ с сервисом Foundation Models. Секрет ключа показывается один раз — его и сохраняем.

Конфигурация провайдера в opencode.json выглядит так:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "cloudru": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Cloud.ru Foundation Models",
      "options": {
        "baseURL": "https://foundation-models.api.cloud.ru/v1",
        "apiKey": "{env:CLOUDRU_API_KEY}"
      },
      "models": {
        "deepseek-ai/DeepSeek-V4.1-Flash": { "name": "DeepSeek V4.1 Flash", "limit": { "context": 1048576, "output": 1048576 } },
        "deepseek-ai/DeepSeek-V4-Flash": { "name": "DeepSeek V4 Flash", "limit": { "context": 1048576, "output": 1048576 } },
        "deepseek-ai/DeepSeek-V4-Pro": { "name": "DeepSeek V4 Pro", "limit": { "context": 1048576, "output": 1048576 } }
      }
    }
  }
}

Ключ передаём переменной окружения:

export CLOUDRU_API_KEY=ваш_ключ_cloudru
opencode

Сертификаты Минцифры здесь не нужны: у домена api.cloud.ru обычный TLS, в отличие от GigaChat. Зато стоит следить за балансом проекта. При нулевом счёте авторизация проходит, а запросы падают с ответом биллинга:

{"message":"Not enough money"}

Это не ошибка конфига, а сигнал, что нужно пополнить проект в консоли Cloud.ru.

На что обратить внимание

Пара практических моментов, которые чаще всего мешают при первой настройке:

  • Ошибка проверки сертификата. Сообщение про self-signed certificate в цепочке означает, что переменная NODE_EXTRA_CA_CERTS не подхватилась. Проверьте путь к файлу, то, что агент запущен в том же окружении, и сам файл: если при склейке двух сертификатов через cat их концы оказались в одной строке, LibreSSL вернёт bad end line, и bundle нужно пересобрать через openssl, как в разделе про сертификаты.
  • Ошибка 401. Как правило, это неверный ключ авторизации или несовпадающий scope — для физлица нужен GIGACHAT_API_PERS.
  • Ошибка 404 с текстом No such model. Это не сбой подключения, а отсутствие доступа к конкретной модели. Уберите её из конфига или замените на доступную. В сообщении вида GigaChat 404: Unknown error виноват тот же ответ GigaChat — провайдер просто не смог разобрать тело ошибки.
  • Cost. OpenCode не требует подписки: вы платите GigaChat напрямую по факту расхода токенов, поэтому длинные сессии предсказуемы по цене.
  • Качество модели. На сложных архитектурных задачах модели разных классов отличаются, поэтому для проектирования имеет смысл брать модель посильнее, а рутину отдавать быстрой.

Ссылки

https://opencode.ai/
https://opencode.ai/docs/providers/
https://developers.sber.ru/studio/
https://developers.sber.ru/docs/ru/gigachat/guides/main
https://github.com/nyddle/gigachat-ai-sdk-provider
https://github.com/ai-forever/gpt2giga
https://cloud.ru/docs/foundation-models/ug/topics/quickstart

Источники

https://opencode.ai/docs/providers/#custom-provider
https://developers.sber.ru/docs/ru/gigachat/certificates
https://developers.sber.ru/docs/ru/gigachat/models/main
https://developers.sber.ru/docs/ru/gigachat/guides/selecting-a-model
https://github.com/nyddle/gigachat-ai-sdk-provider
https://github.com/ai-forever/gpt2giga
https://cloud.ru/docs/foundation-models/ug/topics/quickstart
https://cloud.ru/docs/foundation-models/ug/topics/overview__available__models

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

DemensDeum
Обзор конфиденциальности

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