Skip to main content
В одной строке: когда вы просите модель сгенерировать десятки тысяч символов за один вызов (планы эпизодов, длинную художественную прозу, большие переводы, крупный код), используйте потоковую передачу ответа, а не режим без потоковой передачи; установите тайм-аут чтения клиента на интервал между событиями данных (десятки секунд — 90–120 с является безопасным значением), а не на общее время генерации; дайте max_tokens запас; и проверяйте stop_reason перед использованием текста. Выполните эти четыре действия, и вызовы с длинным выводом перестанут «ничего не возвращать».
Эта страница относится ко всем большим моделям (OpenAI, Claude, Gemini, Grok и другим). В примерах кода используется нативный /v1/messages Claude; различия для OpenAI-совместимого формата указаны отдельно.

Три вещи, которые нужно знать в первую очередь

  1. Для вывода на 10 тыс. слов нормальна реальная генерация в течение 10–20 минут. Модель последовательно генерирует десятки тысяч символов token за token, а также проходит этап рассуждения/обдумывания — общая задержка действительно велика. Дело не в медленной работе шлюза; сама генерация занимает много времени.
  2. Без потоковой передачи весь результат буферизуется перед отправкой. При отсутствии потоковой передачи (stream опущен или false) сервер должен дождаться, пока модель завершит всю генерацию, и только затем отправить весь body одним ответом. В течение этих минут тайм-аут чтения вашего клиента конкурирует с этим ожиданием, и чем дольше генерация, тем выше вероятность отключения до получения результата — при этом исключение часто оказывается пустым (httpx.ReadError’s str(e) пуст), поэтому вы не сможете увидеть причину.
  3. За разорванное соединение всё равно взимается плата, поэтому повторные попытки вслепую приводят к двойной тарификации. После того как сервер сгенерировал вывод, вызов тарифицируется, даже если результат до вас не дошёл. Повторная попытка после того, как вы уже получили часть body, означает, что модель запустится снова и вы заплатите повторно.

Используйте потоковую передачу, не используйте непотоковый режим

При потоковой передаче (stream: true) первый байт приходит в течение нескольких секунд, а затем событие данных поступает каждые несколько десятков секунд. Ваш тайм-аут чтения должен покрывать только интервал между событиями, а не генерацию, которая выполняется много минут — именно поэтому потоковая передача надёжно доставляет длинный вывод. У этих двух протоколов разные маркеры завершения — не путайте их: При включённом адаптивном thinking нативный Claude сначала отправляет блок type: "thinking" (его инкременты — thinking_delta), затем блок text. При отображении направляйте thinking_delta и text_delta раздельно и не объединяйте thinking с основным текстом. Минимальный пример потоковой передачи для нативного Claude /v1/messages (обычный httpx, построчный разбор SSE):
Если вы используете официальный SDK Anthropic, направьте base_url на https://api.apiyi.com и используйте client.messages.stream(...).get_final_message() — SDK обработает разбор SSE, тайм-ауты и stop_reason за вас. Версия с httpx выше предназначена для случаев, когда вы предпочитаете не подключать SDK.

Настройте тайм-аут чтения по межсобытийному интервалу, а не по общему времени

Многие задают тайм-аут чтения равным одному очень большому значению, рассчитанному на всю генерацию (например, 1800 секунд), и всё равно получают тайм-аут — потому что в режиме без потоковой передачи это значение должно покрывать всю генерацию целиком, и любая задержка приводит к сбою. Правильный подход — использовать потоковую передачу и задать тайм-аут чтения по межсобытийному интервалу. Измеренный ориентир (claude-opus-5 создаёт план эпизода примерно на 20 тыс. символов из входных данных примерно на 15 тыс. символов): Таким образом, тайм-аут чтения 90–120 секунд покрывает самый большой межсобытийный интервал с запасом — задавать значение в несколько минут не требуется. Трёхчастный тайм-аут разделяет этапы и позволяет настроить каждый из них отдельно:

Оставьте место для max_tokens и проверяйте stop_reason

Длинный вывод легко достигает предела max_tokens и усекается. Особенно это актуально для таких моделей, как Claude, с включённым рассуждением — само рассуждение расходует бюджет max_tokens, и большой фрагмент может его исчерпать.
  • Установите max_tokens на 64000 (при высоком уровне усилий или глубоком рассуждении задавайте ещё больше; claude-opus-5 поддерживает вывод размером до 128K).
  • Проверяйте stop_reason перед использованием ответа:
    • end_turn — завершено штатно, текст полный; это единственный успешный результат.
    • max_tokens — усечено, текст может быть неполным или даже пустым. Это усечение, а не «пустой результат» — увеличьте max_tokens и повторите запрос.
    • refusal — запрос отклонён политикой безопасности; обработайте этот случай отдельно.
Определять успешность только по str(e) или по признаку «текст пуст» вводит в заблуждение — пустое тело обычно означает усечение max_tokens.

Стратегия повторных попыток

Будьте консервативны при повторных попытках для длинного вывода, чтобы «повторная попытка при сбое» не превратилась в «двойную тарификацию плюс второй длительный запуск»:
  • Повторяйте запрос только при сбоях до получения заголовков ответа и при 5xx / 429 (с экспоненциальной задержкой, не более двух раз). Это проблемы с подключением или временные сбои, при которых повторная попытка имеет смысл.
  • Не повторяйте бездумно потоковую передачу, прервавшуюся после получения части тела ответа. Сервер уже сгенерировал и тарифицировал ответ; повторная попытка запускает операцию заново и приводит к повторной оплате.
  • Для сверки и устранения неполадок записывайте идентификатор запроса из заголовков ответа.

Краткая памятка по сценариям

Всегда используйте потоковую передачу. Используйте api.apiyi.com (рекомендуется в материковом Китае) или vip.apiyi.com (рекомендуется за пределами Китая) и не api-cf.apiyi.com (узел CDN возвращает 524 примерно через 100 секунд и не может обрабатывать длинные запросы).

Связанные материалы

Как избежать таймаутов API

Значения таймаутов для разных сценариев

Потоковая передача и непотоковая передача

Компромиссы и выбор подходящего варианта

Рассуждение и усилия Claude

Адаптивное рассуждение, уровни усилий, max_tokens и усечение

Обработка ответов Claude

Нативная структура ответа, события SSE, stop_reason