Клиент должен различать временную ошибку, несовместимый запрос и частично выполненное действие.
Таймауты#
Задавайте отдельно:
время установления соединения;
время до первого байта;
максимальное время всего запроса;
idle timeout между streaming-событиями.
Reasoning и медиа могут работать заметно дольше обычного chat-запроса.
Повторные попытки#
Повторяйте только временные ошибки и используйте exponential backoff с jitter. Уважайте Retry-After, если он есть.
Не повторяйте автоматически:
ошибку 400 из-за параметров;
401 с тем же ключом;
частично полученный stream;
запрос после выполненного внешнего tool;
создание платной медиа-задачи без idempotency.
Диагностика#
Сохраняйте:
время и endpoint;
ID модели;
HTTP-статус;
request ID из ответа;
финальный статус модели;
usage и стоимость;
число попыток;
обезличенную категорию ошибки.
Не логируйте API-ключ, полные prompts и пользовательские файлы без отдельного основания.
Валидация#
Проверяйте ответ на четырёх уровнях:
HTTP-запрос завершился успешно.
Поток или response object имеет финальный успешный статус.
Структура соответствует ожидаемой схеме.
Бизнес-правила результата выполнены.
Даже успешный HTTP 200 может содержать refusal, incomplete response или tool call вместо финального текста.