Hubris
Возможности

Model Fallbacks

Запасные модели на случай 429/5xx/контент-фильтра. Передайте массив `models` — Hubris сам переключится при сбое.

Model Fallbacks

Если основная модель временно недоступна — упёрлась в rate limit провайдера, упала с 5xx или ответ зарезали контент-фильтром — Hubris автоматически попробует следующие модели из массива models. Биллинг по фактически использованной модели (она возвращается в поле model ответа).

Поддерживается только в POST /v1/chat/completions. На /v1/responses пока нет.

Как работает

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

curl -s https://api.hubris.pw/v1/chat/completions \
  -H "Authorization: Bearer sk-gw-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-opus-4.7",
    "models": [
      "anthropic/claude-opus-4.7",
      "anthropic/claude-sonnet-4.6",
      "openai/gpt-4o-mini"
    ],
    "messages": [{"role": "user", "content": "Привет"}]
  }'

Если Opus 4.7 вернёт 429 от провайдера — сразу пойдёт Sonnet 4.6; если и тот недоступен — GPT-4o mini. Клиент получит обычный успешный ответ, как если бы fallback не было.

Когда срабатывает fallback

  • 429 — rate limit провайдера.
  • 5xx — апстрим упал.
  • Контент-фильтр — провайдер заблокировал ответ модерацией (вы получите fallback-результат, а не блок).
  • Network timeout между Hubris и провайдером.

Биллинг

Списывается стоимость только той модели, которая реально ответила. Поле model в JSON-ответе — это победитель (не первый из массива). На странице /usage запрос будет залогирован под этой моделью.

Если в models несколько моделей разной цены и срабатывает fallback на самую дорогую — да, спишется по её тарифу. Поэтому имеет смысл располагать модели по возрастанию цены или ставить в конец «дешёвый, но всегда живой» вариант:

{
  "model": "anthropic/claude-opus-4.7",
  "models": [
    "anthropic/claude-opus-4.7",
    "anthropic/claude-sonnet-4.6",
    "anthropic/claude-haiku-4.5"
  ],
  "messages": [{"role": "user", "content": "..."}]
}

Стриминг

stream: true работает с fallback так же. Если основная модель упала ДО первого SSE-чанка, Hubris молча переключится на следующую, и клиент получит чанки уже от неё. Поле model в каждом чанке — это уже final-модель. После начала успешного стрима fallback больше не сработает (это технически невозможно: байты пошли клиенту).

Edge-case: если клиент дисконнектнется до того, как пришёл первый чанк с полем model, биллинг спишется по тарифу основной модели — мы просто не успеем узнать, какая ответила. Это безопасно (over-bill вместо undelivered), но может слегка завысить стоимость в редких сетевых сбоях.

Ограничения

  • Максимум 10 моделей в массиве (включая основную).
  • /v1/responses — не поддерживается (используйте /v1/chat/completions).
  • /v1/embeddings — не поддерживается (embedding-модели обычно стабильны и не требуют fallback).
  • Структурные ошибки запроса (400 invalid_request) не триггерят fallback — это значит ваш запрос неверен, и пробовать другую модель бессмысленно.

Что дальше