Модели

Запасные модели (fallback)

Если основная модель не ответила — провайдер лежит, включился рейт-лимит или модель временно недоступна — AITUNNEL сам повторяет запрос в следующую модель из вашего списка. Клиент получает один обычный ответ и ничего не знает о переключении.

Как включить

Передайте массив models вместо model — первая модель в списке становится основной, остальные пробуются по очереди, если она не ответит. Отдельное поле model при этом не нужно.

curl https://api.aitunnel.ru/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-aitunnel-xxx" \
  -d '{
    "models": ["claude-sonnet-4.5", "gpt-5", "deepseek-r1"],
    "max_tokens": 2000,
    "messages": [
      { "role": "user", "content": "Скажи интересный факт" }
    ]
  }'

Работает в /chat/completions, /responses и /messages.

Официальные SDK не знают про models

Поле models не входит в стандарт OpenAI, поэтому SDK его не типизируют: в Python передавайте через extra_body, в TypeScript — с @ts-expect-error. Заодно эти SDK требуют model — там он остаётся, но роли не меняет. На cURL и любых «сырых» HTTP-клиентах ограничений нет.

Правила списка

  • Достаточно одного models — основной станет первая модель из списка.
  • Если model всё-таки прислан, он идёт первым, а models — очередь после него.
  • Повторы схлопываются: "model": "gpt-5" вместе с "models": ["gpt-5", "gpt-4"] — это две попытки, а не три.
  • Не больше 5 моделей на запрос.
  • Подходят и каталожные имена (gpt-5), и слаги OpenRouter (openai/gpt-5), и auto.
  • Имена пресетов в models не работают — только названия моделей (см. ниже).

Ставьте первой ту модель, которую действительно хотите, а следом — более дешёвую или более стабильную замену.

Когда срабатывает переключение

ПереключаемсяНе переключаемся
Модель не найдена или недоступнаНеверный API-ключ (401)
Рейт-лимит провайдера (429)Модель запрещена для ключа (403)
Ошибка провайдера (5xx)Недостаточно средств на балансе
Обрыв соединения с провайдеромИсчерпан бюджет ключа
Провайдер отклонил запрос (модерация)Запрос заблокирован защитой данных (PII)

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

Формат Anthropic: fallbacks

В Anthropic-совместимом /messages тот же механизм доступен в родном для Anthropic формате — массив fallbacks. Он принимается и в /chat/completions с /responses, так что перенос кода между эндпоинтами ничего не ломает.

curl https://api.aitunnel.ru/v1/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-aitunnel-xxx" \
  -d '{
    "model": "claude-sonnet-4.5",
    "max_tokens": 2000,
    "fallbacks": [
      { "model": "claude-opus-4.1" },
      { "model": "gpt-5" }
    ],
    "messages": [
      { "role": "user", "content": "Скажи интересный факт" }
    ]
  }'
  • Элемент fallbacks принимает только поле model. Параметры вроде max_tokens или thinking внутри элемента запрещены — иначе одна и та же просьба выполнялась бы по-разному в зависимости от того, какая модель ответила.
  • Не больше 3 элементов.
  • fallbacks и models нельзя отправлять вместе — выберите один формат.

Списание и стриминг

Платите только за успешную попытку. Неудачные попытки не тарифицируются и в статистику не попадают.

В поле model ответа приходит та модель, которая реально ответила — по ней же считается стоимость и строится статистика в панели.

Переключение только до начала ответа

При stream: true запасная модель подхватит запрос, только если поток ещё не начался. Если модель отвалилась на середине ответа, ошибка вернётся клиенту.

Ошибки

Запрос отклоняется с HTTP 400, если:

  • models — не массив строк;
  • в списке больше 5 моделей (или больше 3 в fallbacks);
  • название модели длиннее 128 символов;
  • элемент fallbacks содержит что-то кроме model;
  • fallbacks отправлен вместе с models;
  • models/fallbacks отправлены вместе с пресетом.

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

Вместе с пресетами

Пресет и models/fallbacks в одном запросе несовместимы: у пресета уже есть свой список моделей и параметры, подобранные под них. Такой запрос отклоняется с 400 — чтобы вы не думали, что запасные модели работают, пока на деле отрабатывает список пресета.

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

Если у ключа включён белый список моделей, в нём должны быть все модели из models — иначе весь запрос отклоняется с 403. См. API-ключи.