От автора: если при вызове API генерации изображений в ответе нет картинки, это не значит, что запрос провалился, и тем более не значит, что деньги не списались. В статье разобран способ из 4 шагов: сначала смотрим на ответ, потом решаем, повторять ли запрос. Там же есть готовый код на Python.
При работе с API генерации изображений вы наверняка сталкивались с такой ситуацией: запрос ушёл, API что-то ответил, а картинки в результате нет. Первая реакция у многих: «наверное, сеть моргнула». Они тут же вызывают API ещё раз, а то и пишут цикл, который долбит его несколько раз подряд. В этой статье речь о порядке действий сначала смотрим на ответ, потом решаем, повторять ли запрос. Он поможет правильно разобраться, почему при генерации изображений не пришла картинка.
Это не очередной общий гайд по ретраям. В моделях генерации изображений с оплатой за запрос каждый вызов может стоить денег. Возьмём gpt-image-2.6-all, которая появилась в APIYI 2026-11-12: один запрос стоит $0.025. Если слепо повторить запрос после пустого ответа, вы заплатите второй раз.
Главная польза: после прочтения вы будете знать, что проверять в первую очередь, если генерация изображений не вернула картинку, в каких случаях запрос можно повторять, а в каких категорически нельзя. Ещё вы узнаете, как заложить эту логику в код, чтобы за одну и ту же картинку не списывали деньги дважды.

Ключевые выводы: что делать, если генерация изображения не вернула картинку
Сначала главное. Если генерация изображения не вернула картинку, нельзя просто списывать всё на сеть. Содержимое ответа нужно проверять в строго определённом порядке. В таблице ниже — все 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 сообщения диалога. Если ваш код разбора понимает только один вариант, он примет ответ с картинкой за пустой — и это одна из самых частых причин ложных повторов.

Разбор типов ответов, когда генерация изображения не вернула картинку
Чтобы сначала посмотреть на ответ и только потом повторять запрос, нужно понимать, как этот ответ вообще может выглядеть. В таблице ниже собраны самые распространённые типы ответов и способы их обработки.
| Тип ответа | Характерные признаки | Изображение уже создано | Что делать |
|---|---|---|---|
| Сбой на уровне запроса | 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 за каждую картинку, умноженные на суточное число запросов, дают совершенно ненужные траты.

Справочник по интерфейсам и моделям: что делать, если генерация изображения не вернула картинку
Разные модели и форматы интерфейсов возвращают изображение в разных местах. Это напрямую влияет на то, насколько точным будет вывод на шаге 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) и только потом выкатывайте в прод.
Итоги
Главное, что нужно помнить, если генерация изображения не вернула картинку: сначала смотрим на ответ и только потом повторяем запрос.
- Сначала разбираемся, потом платим: проверка ответа почти ничего не стоит, а слепой повтор каждый раз оплачивается заново.
- Идём по 4 шагам: успешен ли HTTP-запрос, есть ли в ответе изображение, есть ли ошибка, и только убедившись, что картинки нет, повторяем запрос один раз.
- Зашиваем правила в код: ограничиваем число повторов, не перезапускаем запрос автоматически после таймаута, сохраняем сырой ответ. Так расходы под контролем, а проблемы легко отследить.
Если вы работаете с моделями генерации изображений с оплатой за вызов, этот подход несложный, но он реально спасает от ситуации, когда за одну и ту же картинку списывают деньги дважды. Советую сначала прогнать в тестовой среде все ветки логики, а потом сделать из этого стандартную обёртку для вызовов генерации изображений.
Чтобы быстро проверить эту логику на практике, можно воспользоваться APIYI (apiyi.com). Платформа предоставляет OpenAI-совместимый интерфейс и бесплатный тестовый лимит, а с одним ключом доступны gpt-image-2.6-all и другие популярные модели.
📚 Источники
- Центр документации APIYI: способы вызова моделей и описание форматов ответа
- Ссылка:
docs.apiyi.com -
Описание: конкретные эндпоинты и поля ответа для gpt-image-2.6-all смотрите в документации — она первична
-
Справочник OpenAI Images API: стандартная структура ответа интерфейса генерации изображений
- Ссылка:
platform.openai.com/docs/api-reference/images - Описание: объясняет, что означают поля
urlиb64_jsonв массивеdata
Автор: техническая команда APIYI
Обратная связь: пишите нам на главной странице сайта APIYI, а больше материалов по подключению найдёте в центре документации docs.apiyi.com
