|

Если генерация изображения не вернула картинку: сначала проверьте ответ, затем повторяйте запрос — 4 шага, чтобы избежать повторного списания средств

Если генерация изображения не вернула картинку: сначала проверьте ответ, затем повторяйте запрос — 4 шага, чтобы избежать повторного списания средств

От автора: если при вызове API генерации изображений в ответе нет картинки, это не значит, что запрос провалился, и тем более не значит, что деньги не списались. В статье разобран способ из 4 шагов: сначала смотрим на ответ, потом решаем, повторять ли запрос. Там же есть готовый код на Python.

При работе с API генерации изображений вы наверняка сталкивались с такой ситуацией: запрос ушёл, API что-то ответил, а картинки в результате нет. Первая реакция у многих: «наверное, сеть моргнула». Они тут же вызывают API ещё раз, а то и пишут цикл, который долбит его несколько раз подряд. В этой статье речь о порядке действий сначала смотрим на ответ, потом решаем, повторять ли запрос. Он поможет правильно разобраться, почему при генерации изображений не пришла картинка.

Это не очередной общий гайд по ретраям. В моделях генерации изображений с оплатой за запрос каждый вызов может стоить денег. Возьмём gpt-image-2.6-all, которая появилась в APIYI 2026-11-12: один запрос стоит $0.025. Если слепо повторить запрос после пустого ответа, вы заплатите второй раз.

Главная польза: после прочтения вы будете знать, что проверять в первую очередь, если генерация изображений не вернула картинку, в каких случаях запрос можно повторять, а в каких категорически нельзя. Ещё вы узнаете, как заложить эту логику в код, чтобы за одну и ту же картинку не списывали деньги дважды.

image-generation-no-image-check-response-before-retry-ru-image-0


Table of Contents

Ключевые выводы: что делать, если генерация изображения не вернула картинку

Сначала главное. Если генерация изображения не вернула картинку, нельзя просто списывать всё на сеть. Содержимое ответа нужно проверять в строго определённом порядке. В таблице ниже — все 4 шага этого подхода.

Шаг Что проверяем Что делать, если ответ «нет» Зачем это нужно
Шаг 1 Успешен ли HTTP-запрос Обработать по коду состояния, к следующим шагам не переходить Отделить сбой на уровне запроса от проблем с содержимым
Шаг 2 Есть ли в ответе данные изображения или URL картинки Перейти к шагу 3 Если картинка есть, на этом всё — лишних повторов не будет
Шаг 3 Есть ли в ответе сообщение об ошибке Если ошибка есть, обработать её Не платить снова и снова за запрос, который заведомо провалится
Шаг 4 Убедились, что картинки нет и ошибки нет Повторить только один раз Удержать дополнительные расходы в предсказуемых пределах

Почему нельзя сразу повторять запрос, если картинка не пришла

Запрос на генерацию изображения отличается от обычного текстового диалога: один вызов стоит дороже, а результат часто не бывает «всё или ничего». Возможно, сервер уже сгенерировал изображение, а ваш код просто не достал его из нужного поля. А возможно, сам запрос отклонили, и причина прямо написана в ответе. Если повторить запрос сразу, в первом случае вы заплатите дважды за одну и ту же картинку, а во втором — будете снова и снова платить за запрос, который обречён на провал.

Возьмём gpt-image-2.6-all с оплатой за вызов — $0.025. Каждый слепой повтор — это лишние $0.025. Если принять пустой ответ за сетевой сбой и загнать запрос в цикл, три повтора обойдутся в дополнительные $0.075, и возможно, ни одной нормальной картинки за эти деньги вы не получите. Поэтому, когда картинка не пришла, сначала смотрите на ответ и только потом повторяйте запрос. По сути, это почти бесплатная проверка перед тем, как тратить деньги.

Логика проверки: сначала смотрим ответ, потом повторяем

Порядок проверки строится по принципу «снаружи внутрь». HTTP-код состояния — самый внешний сигнал: он показывает, обработан ли запрос нормально. Данные изображения — то, ради чего всё затевалось, поэтому проверяем их следующими. Сообщение об ошибке — это причина сбоя, которую сервер назвал сам, и учитывать её нужно раньше, чем решать вопрос о повторе. И только когда пройдены все три уровня и стало ясно, что картинки нет и никаких пояснений об ошибке тоже нет, повторный запрос имеет смысл.

Здесь есть деталь, которую часто упускают: на шаге 2 проверяются именно «данные изображения или URL картинки». В разных форматах API картинка лежит в разных местах: где-то в полях b64_json или url внутри массива data, а где-то ссылка на изображение вписана в текст content сообщения диалога. Если ваш код разбора понимает только один вариант, он примет ответ с картинкой за пустой — и это одна из самых частых причин ложных повторов.

image-generation-no-image-check-response-before-retry-ru-image-1


Разбор типов ответов, когда генерация изображения не вернула картинку

Чтобы сначала посмотреть на ответ и только потом повторять запрос, нужно понимать, как этот ответ вообще может выглядеть. В таблице ниже собраны самые распространённые типы ответов и способы их обработки.

Тип ответа Характерные признаки Изображение уже создано Что делать
Сбой на уровне запроса HTTP-статус не 2xx Нет Действовать по коду статуса; ошибки аутентификации и параметров исправить и отправить заново
Нормальный результат (структурированный) В data есть b64_json или url Да Забрать изображение, повторять запрос не нужно
Нормальный результат (встроен в текст) В content сообщения есть ссылка на изображение Да Достать ссылку регулярным выражением, повторять запрос не нужно
Успешный ответ с информацией об ошибке HTTP успешен, но в теле есть error или объяснение отказа Нет Прочитать причину ошибки, изменить промпт или параметры
Действительно пустой ответ HTTP успешен, изображения нет, ошибки нет Нет Сохранить сырой ответ и повторить запрос один раз
Тайм-аут запроса Клиент не получил ответ Неизвестно Не повторять автоматически, сначала сверить логи и биллинг

Почему при тайм-ауте тоже стоит сначала разобраться, а потом повторять

Тайм-аут чаще всего списывают на «сетевой сбой», но именно здесь нужна максимальная осторожность. Тайм-аут на клиенте означает лишь то, что вы не дождались ответа. Он совсем не значит, что сервер не закончил генерацию. Генерация изображений сама по себе занимает довольно много времени, и если на клиенте стоит слишком короткий тайм-аут, вполне может оказаться, что сервер уже создал картинку и списал деньги, а ваша программа раньше времени перестала ждать.

В такой ситуации разумно сначала увеличить тайм-аут, а при его срабатывании записывать время и параметры запроса и сверять фактическое состояние запроса в логах вызовов в консоли. Если успешной записи там нет, можно отправить запрос повторно вручную. Это гораздо надёжнее, чем позволять программе автоматически слать запрос за запросом.

Ответы с информацией об ошибке нужно обрабатывать как ошибки

Иногда HTTP-статус успешный, но в теле ответа лежит объект ошибки, либо модель прямо в тексте объясняет, почему не смогла сгенерировать изображение, например потому что промпт не прошёл модерацию контента. Картинки в таком ответе нет, зато причина указана предельно ясно, и если отправить тот же запрос ещё раз, почти наверняка получится тот же результат.

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


Если картинка не пришла, сначала смотрим ответ, а потом повторяем запрос: быстрый старт

Ниже на Python показано, как заложить эту логику проверки прямо в код. В примере используется OpenAI-совместимый интерфейс, а в качестве модели взята gpt-image-2.6-all. Конкретный эндпоинт и формат ответа для этой модели смотрите в документации APIYI.

Минимальный пример: получили ответ — сначала проверяем, есть ли в нём изображение

Проще всего после получения ответа проверить поля с изображением. Если картинка есть, на этом всё. Если нет, переходим к дальнейшей диагностике:

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apiyi.com/v1",  # OpenAI-совместимый интерфейс APIYI
)

resp = client.images.generate(
    model="gpt-image-2.6-all",
    prompt="一只坐在窗台上的橘猫,水彩风格",
)

item = resp.data[0] if resp.data else None
if item and (item.b64_json or item.url):
    print("已拿到图片,不要重试")
else:
    print("响应里没有图片,先打印原始响应再决定")
    print(resp.model_dump())

В этом коде чуть больше десятка строк, но он уже защищает от самой частой ошибки: повторного запроса вслепую, без анализа содержимого ответа. Если запрос падает на уровне HTTP, SDK выбрасывает исключение. Его можно перехватить во внешнем try и обработать по коду статуса, а не сразу запускать цикл повторов.

Полный пример: проверка в 4 шага и не больше одного повтора

В продакшене лучше использовать вот эту, более полную версию. Она проверяет HTTP-статус, разбирает оба места, где может прийти картинка, распознаёт сообщения об ошибках, не перезапускает запрос при таймауте и позволяет сделать не больше одного повтора, и только когда точно установлено, что изображения нет:

import re
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.apiyi.com/v1"  # Единый адрес интерфейса APIYI
MODEL = "gpt-image-2.6-all"
IMG_URL_RE = re.compile(r"https?://\S+?\.(?:png|jpe?g|webp)", re.I)


def find_images(body):
    """Проверяет и структурированное поле data, и ссылки на изображения в content диалога"""
    images = []
    for item in body.get("data") or []:
        if item.get("url"):
            images.append(item["url"])
        elif item.get("b64_json"):
            images.append("base64-image")
    for choice in body.get("choices") or []:
        content = (choice.get("message") or {}).get("content") or ""
        images += IMG_URL_RE.findall(content)
    return images


def generate_with_check(prompt, max_retry=1):
    for attempt in range(max_retry + 1):
        try:
            resp = requests.post(
                f"{BASE_URL}/images/generations",
                headers={"Authorization": f"Bearer {API_KEY}"},
                json={"model": MODEL, "prompt": prompt},
                timeout=300,
            )
        except requests.Timeout:
            # При таймауте нельзя понять, сгенерировал ли сервер картинку и списал ли деньги, поэтому автоматически не повторяем
            return {"status": "timeout", "action": "check_logs_first"}

        # Шаг 1: успешен ли HTTP-запрос
        if resp.status_code != 200:
            return {"status": "http_error", "code": resp.status_code,
                    "detail": resp.text[:500]}

        try:
            body = resp.json()
        except ValueError:
            return {"status": "bad_json", "detail": resp.text[:500]}

        # Шаг 2: есть ли в ответе данные изображения или URL картинки
        images = find_images(body)
        if images:
            return {"status": "ok", "images": images}

        # Шаг 3: если есть сообщение об ошибке, обрабатываем как ошибку и не повторяем
        if body.get("error"):
            return {"status": "api_error", "error": body["error"]}

        # Шаг 4: убедились, что нет ни картинки, ни ошибки, — записываем сырой ответ и только потом разрешаем повтор
        print(f"第 {attempt + 1} 次请求无图片,原始响应:{str(body)[:300]}")

    return {"status": "empty_after_retry", "action": "stop_and_report"}


result = generate_with_check("一只坐在窗台上的橘猫,水彩风格")
print(result)

В этом коде стоит обратить внимание на несколько важных решений. По умолчанию max_retry равен 1, то есть за одну картинку вы заплатите максимум за два запроса, и верхняя граница расходов предсказуема. При таймауте функция сразу возвращает результат, а не идёт на следующий круг цикла: в этот момент невозможно узнать, списаны ли деньги. Каждый раз, когда ответ признан пустым, печатается сырой ответ. Так потом проще разобраться, в чём была проблема: в разборе или в том, что сервер действительно не вернул изображение.

🚀 Быстрый старт: если хотите сначала проверить эту логику в тестовой среде, получите бесплатный тестовый лимит на APIYI (apiyi.com). Одним и тем же API-ключом можно вызывать gpt-image-2.6-all и другие популярные модели: сначала отладьте процесс проверки, а потом подключайте его к боевому проекту.


Сколько стоит слепой ретрай, когда генерация не вернула картинку

Прежде чем писать в коде логику проверки, многие не до конца представляют, во что обходится «попробуем ещё пару раз». Возьмём gpt-image-2.6-all с оплатой $0.025 за запрос и сравним две стратегии: слепые повторы и повтор только после анализа ответа. Смотрим на дополнительные расходы в пересчёте на одну картинку.

Стратегия Макс. число запросов на одну картинку Доп. расходы в худшем случае Риск
Не проверять, при сбое повторить 1 раз 2 $0.025 Можно заплатить повторно за запрос, который на самом деле уже вернул картинку
Не проверять, повторять в цикле 3 раза 4 $0.075 Многократная оплата запросов, которые заведомо обречены на сбой
Не проверять, повторять до получения картинки Неопределённо Без ограничений Деньги списываются снова и снова, если запрос отклонён модерацией контента
Сначала проверить ответ, при отсутствии картинки повторить 1 раз 2 $0.025 Дополнительные затраты только при действительно пустом ответе

На первый взгляд, худший случай у стратегий «сначала проверить ответ» и «при сбое повторить 1 раз» одинаковый, но условия срабатывания у них совершенно разные. В первом случае вы тратите $0.025 только тогда, когда точно нет ни картинки, ни сообщения об ошибке. Во втором эти деньги уйдут и тогда, когда картинка уже пришла, но не распарсилась, и тогда, когда контент отклонён модерацией. Результата при этом вы не получите.

При пакетной генерации эта разница растёт кратно. Лишние $0.025 за каждую картинку, умноженные на суточное число запросов, дают совершенно ненужные траты.

image-generation-no-image-check-response-before-retry-ru-image-2


Справочник по интерфейсам и моделям: что делать, если генерация изображения не вернула картинку

Разные модели и форматы интерфейсов возвращают изображение в разных местах. Это напрямую влияет на то, насколько точным будет вывод на шаге 2. В таблице ниже собраны типичные форматы ответа и на что стоит обратить внимание: так вы проверите, что ваш код разбора ничего не пропускает.

Формат ответа Где находится изображение На что обратить внимание при разборе Доступные платформы
Интерфейс генерации изображений (URL) data[].url Ссылка может иметь срок действия, поэтому скачивайте и сохраняйте файл сразу после получения APIYI apiyi.com, ориентируйтесь на документацию модели
Интерфейс генерации изображений (Base64) data[].b64_json Декодируйте и записывайте в файл, не принимайте за пустую строку Там же
Изображение внутри ответа чат-интерфейса choices[].message.content Извлекайте Markdown-изображение или ссылку регулярным выражением Там же
Потоковый ответ Полное содержимое после склейки фрагментов Дождитесь конца потока и склейте все фрагменты, только потом проверяйте, есть ли изображение Там же

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


Частые вопросы FAQ

Q1: Если генерация не вернула картинку, значит ли это, что деньги точно не списали?

Нет, не обязательно. Списание зависит от того, обработал ли сервер запрос, а не от того, получил ли ваш код изображение. Если вы неправильно указали поле для разбора ответа, не дособрали потоковый ответ или клиент завершился по таймауту раньше времени, получится ситуация «деньги списаны, а картинки нет». Поэтому сначала смотрите на ответ и только потом повторяйте запрос, а не отправляйте его заново, решив, что ничего не списалось.

Q2: Чем «сначала посмотреть ответ, потом повторить» отличается от обычных повторов с экспоненциальной задержкой?

Экспоненциальная задержка отвечает на вопрос «когда повторять». Она подходит для ограничения частоты запросов и временных сбоев на стороне сервера. Проверка ответа отвечает на вопрос «стоит ли повторять вообще». Для запросов генерации изображений с оплатой за каждый вызов сначала нужно убедиться по четырём шагам, что повтор действительно необходим, и уже потом выбирать момент повтора по стратегии с задержкой. Эти подходы идут друг за другом и не заменяют друг друга.

Q3: Когда вышла gpt-image-2.6-all и сколько она стоит?

gpt-image-2.6-all появилась в APIYI 2026-11-12. Оплата идёт за каждый запрос: $0.025. Каждый запрос тарифицируется отдельно, поэтому повтор после пустого ответа обойдётся ещё в одну оплату. Именно поэтому в статье так настаивают: сначала посмотрите на ответ, потом повторяйте.

Q4: В каких случаях, если картинка не вернулась, повторять запрос нельзя категорически?

Есть три основных случая:

— **В ответе есть сообщение об ошибке.** Например, промпт не прошёл модерацию контента или параметры недопустимы. Если отправить тот же запрос, результат будет таким же.
— **Таймаут запроса.** Неизвестно, успел ли сервер сгенерировать изображение и списать плату, поэтому сначала проверьте логи.
— **HTTP-ошибки аутентификации или квоты.** Повтор ничего не изменит, сначала нужно исправить API-ключ или решить вопрос с квотой.

Q5: Как быстро проверить, что моя логика принятия решений работает правильно?

Рекомендуем сначала прогнать весь процесс в тестовой среде:

1. Зарегистрируйте аккаунт на APIYI apiyi.com, получите API-ключ и бесплатную тестовую квоту.
2. В полном примере из этой статьи задайте `BASE_URL` равным `https://api.apiyi.com/v1` и вызовите gpt-image-2.6-all.
3. Протестируйте обычный промпт и промпт, который могут отклонить, и посмотрите, что возвращается в каждой ветке.

Когда убедитесь, что каждый тип ответа попадает в нужную ветку, подключайте логику к боевому сервису.

Q6: Что делать, если после одного повтора картинки всё равно нет?

Остановите автоматические повторы и сохраните исходные ответы обоих запросов, параметры запросов и время отправки. Сначала проверьте, не пропускает ли код разбора поле с изображением, затем сверьте записи об этих двух вызовах в консоли. Если выяснится, что сервер действительно подряд вернул пустой результат, обратитесь в техподдержку APIYI на apiyi.com, приложив время запросов и исходные ответы. Это эффективнее, чем продолжать платно отправлять запросы заново.

Q7: Как контролировать стоимость повторов при пакетной генерации изображений?

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


Генерация изображения не вернула картинку: сначала смотрим ответ, потом повторяем запрос. Ключевые выводы

  • Нет картинки ≠ нет списания: если запрос на генерацию тарифицируется за вызов, деньги могут списаться уже после того, как сервер его обработал.
  • Порядок проверки всегда один: HTTP-статус → данные изображения или URL → сообщение об ошибке → повтор только после того, как точно убедились, что картинки нет.
  • Повторяем один раз: если картинки нет и ошибки тоже нет, делаем ровно один повтор. Так верхняя граница расходов понятна заранее.
  • Таймаут не повод сразу слать запрос снова: по таймауту нельзя понять, дошла ли генерация до конца. Сначала сверьтесь с логами, потом решайте, стоит ли отправлять запрос ещё раз.
  • Разбирайте ответ во всех возможных местах: проверяйте и поле data, и content в диалоговом ответе, иначе можно ошибочно принять нормальный ответ за пустой.
  • Слепые повторы стоят денег: каждый лишний слепой повтор для gpt-image-2.6-all обходится ещё в $0.025.
  • Сначала проверьте на тестовом лимите: прогоните всю схему проверки на бесплатном тестовом лимите APIYI (apiyi.com) и только потом выкатывайте в прод.

Итоги

Главное, что нужно помнить, если генерация изображения не вернула картинку: сначала смотрим на ответ и только потом повторяем запрос.

  1. Сначала разбираемся, потом платим: проверка ответа почти ничего не стоит, а слепой повтор каждый раз оплачивается заново.
  2. Идём по 4 шагам: успешен ли HTTP-запрос, есть ли в ответе изображение, есть ли ошибка, и только убедившись, что картинки нет, повторяем запрос один раз.
  3. Зашиваем правила в код: ограничиваем число повторов, не перезапускаем запрос автоматически после таймаута, сохраняем сырой ответ. Так расходы под контролем, а проблемы легко отследить.

Если вы работаете с моделями генерации изображений с оплатой за вызов, этот подход несложный, но он реально спасает от ситуации, когда за одну и ту же картинку списывают деньги дважды. Советую сначала прогнать в тестовой среде все ветки логики, а потом сделать из этого стандартную обёртку для вызовов генерации изображений.

Чтобы быстро проверить эту логику на практике, можно воспользоваться APIYI (apiyi.com). Платформа предоставляет OpenAI-совместимый интерфейс и бесплатный тестовый лимит, а с одним ключом доступны gpt-image-2.6-all и другие популярные модели.


📚 Источники

  1. Центр документации APIYI: способы вызова моделей и описание форматов ответа
  2. Ссылка: docs.apiyi.com
  3. Описание: конкретные эндпоинты и поля ответа для gpt-image-2.6-all смотрите в документации — она первична

  4. Справочник OpenAI Images API: стандартная структура ответа интерфейса генерации изображений

  5. Ссылка: platform.openai.com/docs/api-reference/images
  6. Описание: объясняет, что означают поля url и b64_json в массиве data

Автор: техническая команда APIYI
Обратная связь: пишите нам на главной странице сайта APIYI, а больше материалов по подключению найдёте в центре документации docs.apiyi.com

Читайте также

Похожие записи