ЦАРЬ РОУТЕР

Выбор канала и надёжность

Как tsarrouter выбирает канал-провайдера, fallback-цепочка models, объект provider, заголовки X-TsarRouter-* и тест отказоустойчивости X-Simulate-Fail

У одной модели может быть несколько каналов-провайдеров. Запрос уходит на один из здоровых каналов (случайный выбор, взвешенный в пользу дешёвых), а при сбое автоматически переключается на следующий - это failover. Кто ответил на самом деле, всегда видно в заголовках ответа.

Что уходит в failover, а что нет

  • Уходит: 429 и 5xx провайдера, таймауты, обрывы соединения, пустой ответ с кодом 200. Сбоящие каналы временно понижаются в очереди выбора.
  • Не помогает: клиентские ошибки 4xx (кроме 429) - другой провайдер отверг бы тот же запрос. В обычном запросе такая ошибка возвращается сразу, с исходным кодом и текстом провайдера.

Обычный запрос (без стрима и без цепочки models) дополнительно повторяет сбойный канал один раз с короткой паузой; в потоковом режиме и с цепочкой каждый кандидат пробуется один раз.

Fallback-цепочка моделей: models

Если недоступны все каналы модели, запрос можно продолжить на резервной модели - перечислите их в models в порядке предпочтения:

{
  "model": "deepseek/deepseek-v4-flash",
  "models": ["Qwen/Qwen3.6-35B-A3B", "sber/gigachat-2-max"],
  "messages": [{"role": "user", "content": "Привет!"}]
}
  • Кандидаты перебираются по порядку: все каналы основной модели, затем все каналы первой резервной и так далее.
  • Основная модель обязана существовать и быть включённой (иначе 400/503); несуществующая или отключённая резервная просто пропускается.
  • Частотные лимиты и признак «бесплатная» считаются по основной модели.
  • В отличие от обычного запроса, клиентская 4xx здесь не прерывает перебор. Если не ответил никто, придёт 502 All providers failed for model chain [...]; когда последней была клиентская ошибка 4xx - она отдаётся с исходным кодом и текстом.
  • Какая модель ответила фактически - в заголовке X-TsarRouter-Model.

Управление выбором канала: provider

{
  "model": "Qwen/Qwen3.6-35B-A3B",
  "messages": [{"role": "user", "content": "Привет!"}],
  "provider": {"sort": "throughput", "ignore": ["mws"]}
}
ПолеДействие
only: ["cloudru"]только перечисленные провайдеры
ignore: ["mws"]исключить перечисленных
order: ["yandex", "cloudru"]пробовать в этом порядке; allow_fallbacks: false запрещает добавлять остальные каналы после перечисленных
sortдетерминированная сортировка вместо случайного выбора: "price" (дешёвые вперёд), "throughput" (токены/с), "latency" (мс); перекрывает order
max_price: {"prompt": 500, "completion": 1000}жёсткий потолок цены, ₽ за 1M токенов - каналы дороже исключаются
preferred_min_throughput: 30мягкий фильтр: каналы медленнее 30 токенов/с уходят в конец очереди, но не исключаются
preferred_max_latency: 2000мягкий фильтр по задержке, мс

Пропускная способность и задержка берутся из живых метрик последних минут. Канал без метрик при sort уходит в конец очереди; мягкие фильтры preferred_* его не штрафуют.

Стриминг: переключение до первого чанка

В потоковом режиме сервис ждёт первый чанк провайдера до 30 секунд и только потом отдаёт вам HTTP 200 - все переключения каналов происходят до этого и незаметны. После первого чанка failover уже невозможен: сбой в середине потока обрывает его без завершающего [DONE] (см. список ошибок).

Заголовки трассировки

ЗаголовокЧто в нём
X-TsarRouter-Providerканал, который реально исполнил запрос
X-TsarRouter-Modelмодель, которая реально ответила (важно при цепочке models)
X-TsarRouter-AttemptsJSON-массив попыток: [{"provider": "...", "model": "...", "status": "ok", "latency_ms": 812.4}]
X-Model-Deprecated: true + Sunsetответившая модель объявлена устаревшей; Sunset - дата отключения (2026-05-12)

Статусы попыток: ok, error (с полем error - текстом причины), insufficient_balance, simulated_fail. У части попыток latency_ms может отсутствовать. На итоговых ошибках (502 после перебора всех) заголовков X-TsarRouter-* нет.

Признак устаревания есть и в GET /v1/models: поле deprecated с датой отключения у затронутых моделей.

Проверить failover без сбоя: X-Simulate-Fail

Заголовок для теста отказоустойчивости, доступен любому ключу. Перечислите через запятую модели, которые нужно искусственно «уронить», - их каналы будут помечены сбойными без обращения к провайдеру (и без списаний):

curl https://api.tsarrouter.ru/v1/chat/completions \
 -H "Authorization: Bearer sk-tsar-ваш-ключ" \
 -H "X-Simulate-Fail: deepseek/deepseek-v4-flash" \
 -H "Content-Type: application/json" \
 -d '{
    "model": "deepseek/deepseek-v4-flash",
    "models": ["sber/gigachat-2-max"],
    "messages": [{"role": "user", "content": "Привет!"}]
  }'

Ответ придёт от резервной модели, а в X-TsarRouter-Attempts будет попытка со status: "simulated_fail". Работает на /v1/chat/completions в потоковом режиме или при заданной цепочке models; если «уронить» все модели запроса, придёт обычный 502 - как при реальном отказе.

На этой странице

Редактировать на GitVerse