Skip to main content
Эта страница предназначена для разработчиков, вызывающих gemini-3-pro-image (Nano Banana Pro) через APIYI. В ней объясняется структура вывода response JSON и что на самом деле означает каждое поле usageMetadata, а также разъясняются несколько особенностей подсчёта, которые выглядят как аномалии, но являются неотъемлемой частью модели. Все выводы получены на основе тестирования в производственном шлюзе (48 запросов text-to-image + 18 запросов image-edit), перепроверены по официальной документации Google (ai.google.dev/gemini-api/docs/image-generation) и не являются предположениями.

Общая структура ответа

Серия nano banana в APIYI использует нативный формат Google. Ответ всегда содержит четыре поля верхнего уровня:

При успешной генерации

parts могут содержать более одного изображения. При сложных prompt с задачами в стиле задания и несколькими ограничениями, например «4-view character sheet», модель может вернуть несколько image parts в одном ответе (в тестировании наблюдалось 2–10) — это промежуточные черновики из «thinking process» модели плюс финальная версия. В документации Google указано, что «последнее изображение внутри Thinking также является финальным отрендеренным изображением», поэтому просто берите последнее. Чистая генерация изображений по тексту и простые правки (добавление аксессуаров / смена фона / смена стиля) обычно возвращают только 1. В любом случае всегда проходите по parts и берите последний inlineData, когда вам нужно только одно изображение. Подробности см. в Dev Guide · Почему ответы иногда содержат несколько изображений.

parts также может содержать текстовый сегмент

Приведённый выше пример показывает массив parts, содержащий один image segment, но такой структуры никто не гарантирует. parts — это гетерогенный массив, и в тестировании было обнаружено три варианта структуры: Если включить TEXT в responseModalities или использовать prompt, который просит модель объяснить себя, в ответ добавится текстовый сегмент — и заранее не фиксировано, окажется он до изображения или после него. Так что индекс, по которому находится изображение, не является постоянным.
Эти два шаблона с жёстко заданным индексом взаимодополняющи: изображение всегда оказывается либо на [0], либо на [1], поэтому если жёстко задать любой из них, останутся запросы, в которых вы не получите изображение. Правильный подход см. в разделе Лучшие практики парсинга и согласования ниже. В качестве меры усиления надёжности вы также можете указать responseModalities: ["IMAGE"] в generationConfig, чтобы задать, что вам нужно только изображение, — но это не заменяет фильтрацию.

При блокировке политиками безопасности

HTTP status code по-прежнему 200; разница находится внутри candidate:
  • В тестировании было обнаружено три значения finishReason: IMAGE_SAFETY (выходное изображение нарушает политику), PROHIBITED_CONTENT (была активирована политика запрещённого использования, с пояснительным finishMessage) и NO_IMAGE (изображение не сгенерировано, обычно возвращается в течение нескольких секунд).
  • Объяснение отказа находится в поле finishMessage — оно не появляется как текстовый сегмент внутри parts.
  • Ваш код парсинга должен уметь обрабатывать parts как null, иначе заблокированные ответы приведут к его сбою.
Для диагностики сбоев, политик модерации контента и стратегий понятных пользователю сообщений см. Gemini Image Error Handling Guide.

Значения поля usageMetadata

Успешные генерации всегда содержат 6 полей:
Image tokens определяются уровнем разрешения, а не соотношением сторон: 1120 tokens на изображение на уровнях 1K и 2K, 2000 на изображение на 4K. Соотношение сторон меняет только размеры в пикселях, но не количество tokens. Когда в одном ответе возвращается N изображений, детали в точности равны N × значению на одно изображение. Приведённая ниже таблица — это официальная справка Google по соотношениям сторон и размерам изображений Pro Image (источник: ai.google.dev/gemini-api/docs/image-generation), полностью согласованная с нашими измерениями gemini-3-pro-image:
В официальной таблице Google заголовок столбца 1K tokens означает «количество tokens для уровня разрешения 1K» — фактическое количество tokens на одно изображение соответствует значению в ячейке: 1120 tokens на изображение для 1K/2K, 2000 для 4K. (В китайской локализации этой страницы заголовок отображается как «1,000 tokens», что легко принять за количество tokens на изображение.) Также обратите внимание: уровень 512px (747 tokens на изображение) существует только для моделей Flash image — gemini-3-pro-image поддерживает только 1K/2K/4K; Nano Banana 2 Lite (gemini-3.1-flash-lite-image) — особый случай: у него есть только уровень 1K, без 512px.

Три поведения, которые выглядят как аномалии

Поведение 1: candidatesTokenCount ≠ сумма candidatesTokensDetails — нормально и неизбежно

В ходе тестирования 100% образцов (49/49 успешных генераций) показали, что candidatesTokenCount превышает сумму details на 88–630 tokens (чем сложнее prompt и чем больше изображений возвращается, тем больше разрыв). Причина: candidatesTokensDetails учитывает только сам image payload (фиксированные 1120/2000 на каждое изображение), тогда как candidatesTokenCount также включает внутренние tokens, сгенерированные вместе с процессом image generation, для которых нет соответствующей записи модальности. Это нативная схема подсчёта Gemini; APIYI передаёт её без изменений.
Вывод: не считайте details полной разбивкой candidatesTokenCount для валидации. Для сверки и тарификации всегда используйте candidatesTokenCount / totalTokenCount; details полезны только для оценки доли изображений.

Поведение 2: totalTokenCount ≠ prompt + candidates + thoughts — только в ответах без вывода изображений

  • При успешной генерации уравнение строго выполняется (49/49): total = promptTokenCount + candidatesTokenCount + thoughtsTokenCount.
  • В ответах, заблокированных системой безопасности (без вывода изображений), уравнение никогда не выполняется (6/6), с фиксированным шаблоном:
В ответах с отказом candidatesTokenCount зеркалирует thoughtsTokenCount, поэтому суммирование трёх полей даёт двойной учёт tokens рассуждения. Это также присущее upstream поведение. totalTokenCount само по себе корректно — просто используйте его напрямую. Если примерно 10% ответов в ваших логах «не сходятся», проверьте, пустое ли в этих ответах parts — почти наверняка это образцы, заблокированные системой безопасности.

Поведение 3: output tokens иногда достигают 6000+ — из-за нескольких image parts из процесса thinking

Официальная документация Google указывает, что image models Gemini 3 являются моделями thinking: «Thinking» включён по умолчанию и его нельзя отключить в API. Модель генерирует промежуточные изображения для проверки композиции и логики, и «последнее изображение в Thinking также является финальным отрендеренным изображением» (источник: раздел Thinking Process в ai.google.dev/gemini-api/docs/image-generation). В ходе наших тестов эти промежуточные черновики thinking возвращаются в нативном ответе generateContent как обычные image parts: каждая часть содержит поле thoughtSignature, но не содержит флаг thought: true, и каждая из них учитывается как 1120 tokens в candidatesTokensDetails. В документации Google сказано, что Thinking генерирует не более двух промежуточных изображений, но при сложных prompt в стиле задач мы наблюдали до 10 image parts в одном ответе. Потребление растёт строго линейно с количеством изображений: Поле thoughtsTokenCount учитывает только text thinking и в тестах никогда не превышало 400 — источник высоких output tokens это количество image parts, а не это поле. Когда вы видите 6000+ или даже пятизначные output tokens, проверьте количество частей в этом ответе — это почти наверняка ответ с несколькими изображениями и нормальная тарификация (при этом всё равно сверяйте с totalTokenCount).

Уровни thinking и две API-парадигмы

Как thinkingLevel влияет на tokens

Управление уровнем thinking поддерживается только Gemini 3.1 Flash Image / Flash Lite Image (generationConfig.thinkingConfig.thinkingLevel, по умолчанию minimal или high); на gemini-3-pro-image thinking всегда включён и не настраивается. Измерено (тот же prompt, 1K text-to-image, через шлюз APIYI):
  • high only increases thinking tokens and latency — image tokens stay unchanged (по-прежнему 1120 на одно изображение).
  • Передача thinkingLevel в gemini-3-pro-image не вызывает ошибки, но не даёт измеримого эффекта — thinking tokens остаются в диапазоне по умолчанию.
  • includeThoughts: true не изменило ни структуру ответа, ни тарификацию в ходе тестирования; Google прямо указывает, что thinking tokens тарифицируются по умолчанию, независимо от того, просматриваете ли вы процесс thinking.
  • Google также отмечает, что «minimal thinking» не означает, что модель совсем не думает; при minimal usage просто перестаёт выводить отдельное поле thoughtsTokenCount.
Nano Banana 2 Lite (gemini-3.1-flash-lite-image) находится в том же семействе 3.1 Flash, что и Nano Banana 2, и также поддерживает управление thinkingLevel с тем же механизмом, что и в таблице выше; она ещё не была отдельно измерена и пока не включена в таблицу. Подробности о ценах см. в Тарифы серии Nano Banana.

Чем thinking tokens в image-моделях отличаются от text моделей

  • Text thinking models: выход thinking — текст; thoughtsTokenCount может достигать тысяч и тарифицируется по цене output-token. Официально тарификация основана на полных внутренних мыслях, которые генерирует модель, хотя API возвращает только краткие сводки мыслей (источник: раздел о тарификации в ai.google.dev/gemini-api/docs/thinking).
  • Image thinking models: thinking produces two kinds of output — a small amount of text thinking counted in thoughtsTokenCount (measured: up to 400 on Pro, ~800 on Flash at high), and interim draft images, which come back as ordinary image parts billed at 1120/2000 tokens each in candidatesTokenCount. So for image models the «cost of thinking» mostly shows up in the number of image parts, not in the thoughtsTokenCount field (см. поведение 3 выше).

Две API-парадигмы

Документация по image-моделям Google теперь представлена в двух вариантах: классический generateContent API (без состояния) и недавно рекомендованный Interactions API (созданный для агентов и инструментов). Шлюз APIYI использует родной формат generateContent от Google — всё на этой странице основано именно на нём. Отличия, связанные с thinking: Для полного сравнения двух парадигм (эндпоинты, управление состоянием, хранение данных и тесты совместимости шлюза APIYI) см. Interactions API против generateContent.

Лучшие практики разбора и сверки

  1. Сверяйте тарификацию с totalTokenCount (она точна даже при отказах); не проверяйте это, самостоятельно суммируя три поля, или суммируя детали.
  2. Итерируйте по частям — никогда не предполагайте одно изображение; любая бизнес-логика на уровне изображения должна опираться на фактическое количество частей inlineData.
  3. Обрабатывайте заблокированные ответы с parts = null + HTTP 200, выполняя ветвление по finishReason.
  4. Простые правки занимают ~22–25s; сложные задачи (ответы с несколькими изображениями) занимают 35–142s, дольше при большем количестве изображений. Установите тайм-ауты клиента на ≥ 5 минут (включая любой proxy layer).

Связанные документы

Руководство для разработчиков Nano Banana

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

Руководство по обработке ошибок

Три ключевых показателя для диагностики неудачных генераций, политики модерации контента и дружественные стратегии промптов

План гарантии при неудачной генерации

Если сбой не вызван вашим вводом, кредиты возмещаются в соответствии с количеством неудачных запросов

Цены Nano Banana

Цена за изображение в зависимости от разрешения и уровня модели