akyko

Ошибки и поведение

Что возвращает шлюз, когда что-то не так, как работает поток и в какой момент возможно переключение между поставщиками.

Формат ошибки

Тело ошибки - JSON с объектом error, причина - в error.message. Такой формат понимают стандартные SDK, поэтому ошибки шлюза прилетают в код как обычные ошибки API. Часть системных сообщений пока приходит не по-русски.

json
{
  "error": {
    "message": "...",
    "type": "...",
    "code": "..."
  }
}

Коды ответа

КодЧто случилосьЧто делать
400Запрос не разобран: невалидный JSON, отсутствует или испорчено обязательное поле.Починить запрос. Повтор без изменений не поможет.
401Ключ не принят: не передан, отозван, просрочен, скопирован не целиком.Проверить заголовок и сам ключ, при необходимости выпустить новый.
403Запрос отклонён до обращения к модели: не хватает баланса на резерв, модель вне белого списка ключа, адрес вне списка разрешённых IP.Пополнить баланс или снять ограничение ключа; что именно не сошлось, сказано в теле ответа.
429Превышен лимит частоты запросов по аккаунту.Повторить с экспоненциальной задержкой, снизить параллельность.
5xxОшибка на стороне поставщика или шлюза, которую не удалось обойти переключением.Повторить с задержкой: запрос не выполнен и не списан.

Резерв, списание и нехватка баланса

Перед вызовом шлюз резервирует оценку максимальной стоимости запроса, а после ответа списывает фактическую. Если на резерв не хватает, запрос не уходит к поставщику и сразу возвращается 403 с обычным JSON в теле.

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

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

Потоковая передача (SSE)

С "stream": true ответ приходит как text/event-stream: серия событий data: с дельтами и завершающее data: [DONE].

text/event-stream
data: {"choices":[{"delta":{"content":"При"}}]}

data: {"choices":[{"delta":{"content":"вет"}}]}

data: [DONE]

SDK OpenAI и Anthropic разбирают поток сами - руками парсить события не нужно.

Повторы и переключение поставщиков

Одну модель может обслуживать несколько поставщиков, и шлюз сам пробует следующего, если предыдущий ответил ошибкой: обрыв соединения, 429, 5xx. Клиент этого не видит - он получает один нормальный ответ. Модель при этом не меняется: другой поставщик обслуживает ту же модель, которую вы назвали - Имена моделей.

Если поставщик оборвался в середине потока, поток завершается событием ошибки, а полученная часть остаётся у клиента. Повтор оборвавшегося потока - на стороне клиента, и повторять надо запрос целиком. Списание идёт по фактически обработанным токенам, поэтому оборванный ответ стоит ровно столько, сколько успел отдать.

Что ещё полезно знать

  • На 429 и 5xx повтор уместен, на 400, 401 и 403 - нет: без изменений результат будет тот же.
  • Для долгих запросов держите таймаут клиента с запасом: ответ большой модели может идти минуты.
  • Текущее состояние шлюза - на странице Статус.