Продвинутая генерация изображений: рабочий процесс и реализм
Та же модель, но лучшее качество: что пользовательские приложения для изображений добавляют поверх API — слой переписывания prompt, якорение по референсу, параллельная выборка с отбором по vision-model и пошаговая ретушь. Включает словарь реалистичности для копирования и вставки, сравнения бок о бок и расчет стоимости.
Как получить именно то изображение, которое вы хотите отвечает на вопрос «эта одна попытка не удалась, как мне это исправить». Эта страница отвечает на следующий вопрос: как сделать так, чтобы каждая попытка была удачной.Вопрос, который возникает постоянно: потребительские продукты для изображений, такие как freepik.com и higgsfield.ai, работают на тех же базовых моделях, что и вы, — на тех же семействах Nano Banana, GPT-Image и FLUX, — но их результат выглядит более завершённым. Разница не в весах модели. Она в слое, который обёрнут вокруг модели, и вы можете создать этот слой сами. Эта страница показывает, как.
1. Что оборачивает модель в потребительских image-продуктах
Разберите любой из этих продуктов, и вы обнаружите примерно восемь слоёв вне модели. Каждый из них можно воспроизвести на API:
Что делает продукт
Какую проблему решает
Как воспроизвести это на API
Слой переписывания prompt (Prompt Enhancer)
Пользователи пишут неформально; model’ям нужно структурированное описание
Сначала вызовите текстовую модель для переписывания, затем обратитесь к модели генерации изображений (раздел 2)
Предустановки стиля (десятки пресетов, доступных по клику, плюс сохранённые пользовательские)
Фиксирует эстетику, чтобы пользователям не требовалась фотографическая лексика
Пресет — это всего лишь константа фрагмента prompt в вашем коде плюс фиксированный набор изображений-референсов
Закрепление идентичности (например, Higgsfield’s Soul ID, который обучает устойчивую идентичность на 20–80 фотографиях)
Один и тот же человек остаётся тем же самым в разных генерациях
Приблизьте это с помощью изображений-референсов (см. ограничения ниже)
Сэмплирование нескольких вариантов, показ одного
Пользователь видит только лучший вариант, поэтому воспринимаемая вероятность успеха приближается к 100%
Сгенерируйте N параллельно, затем пусть vision-модель оценит и выберет (раздел 3, шаги 3–4)
Пошаговое редактирование
Сложные инструкции, выданные одним запросом, надёжно распадаются
Сначала зафиксируйте композицию, затем отредактируйте локально, затем добавьте текст
Апскейлинг и постобработка (Freepik приобрела Magnific в 2024 году и предлагает креативный апскейлинг 2×–16×)
Превращает небольшой результат в размеры, готовые к печати
У APIYI нет такого endpoint — вместо этого генерируйте сразу на уровне высокого разрешения (см. ограничения ниже)
Негативные prompt’ы и запасные механизмы безопасности
Обходит известные особенности model’ей и отлавливает запросы, которые moderation отклонит
Встраивайте фиксированную негативную формулировку в ваш шаблон, плюс путь понижения для сбоев moderation
Библиотека ассетов и rehosting
Изображения пользователя никогда не истекают и не исчезают
Сразу копируйте каждый результат в собственное object storage
Две платформенные границы, которые нужно определить до того, как вы копируете список функций конкурента:
У APIYI нет endpoint для апскейлинга, удаления фона или восстановления лица. Если вам нужен большой image, выбирайте уровень высокого разрешения во время генерации (gpt-image-2 at 4K, Nano Banana Pro at 4K), а не рассчитывайте увеличить его позже. Для прозрачного фона только seedream-5-0 и seedream-5-0-pro можно попросить вернуть PNG с alpha-каналом.
APIYI не предлагает LoRA или обучение идентичности. Возможность «обучить один раз и навсегда зафиксировать лицо», лежащая в основе Soul ID, можно лишь приблизить с помощью изображений-референсов: тот же персонаж всё равно будет дрейфовать между сценами и изменениями освещения, а лучше всего это работает, когда новый кадр остаётся близким к фронтальному ракурсу и исходному освещению. Для коммерческих персонажей, которым нужна строгая согласованность, закладывайте этап ручной проверки.
Сравнение бок о бок: одна модель, один бриф, два prompt
Бриф такой: «товарный снимок кофе для e-commerce». Слева — то, что пользователь действительно вводит; справа — тот же бриф, но с заполненными недостающими решениями. Обе версии были запущены по одному разу на gemini-3-pro-image (Nano Banana Pro) в 2K, 1:1:
Casual prompt: 'Make me a coffee product shot, make it look nice, make it feel premium'
Structured prompt: subject, environment, light position, lens, grading, imperfections and composition all specified
Левое изображение нельзя назвать некрасивым, но оно непригодно к использованию. Модель приняла кучу решений, которые никто не утверждал: добавила кофемолку и мешок из мешковины, выбрала ностальгическую тёплую цветокоррекцию и нанесла на чашку вымышленное название бренда — автоматически сгенерированный текст такого рода делает кадр коммерчески бесполезным. Правое изображение можно сразу разместить на странице товара: нейтральный фон, световая схема, которую можно описать вслух, и место для текста.«Выглядит красиво» и «пригодно к использованию» — разные цели. Casual prompt может добиться только первой.
Шесть элементов, которые должен обеспечить слой переписывания
Переписывание не означает сделать prompt длиннее. Оно означает заполнить недостающие решения. У image prompt есть шесть несущих элементов:
Элемент
Что происходит без него
Пример
Объект
Модель импровизирует и добавляет лишние предметы, которых вы не хотели
«Матовая чёрная керамическая чашка для пуровера, заполненная чёрным кофе на 80%»
Окружение
Случайные фоны, из-за которых набор изображений никогда не совпадает
«Поверхность из светло-серого микробетона, стена в той же тональности, размытие»
Свет
Плоское глобальное освещение, которое мгновенно выглядит фальшиво
«Основной свет из софтбокса сверху слева, под углом 45 градусов; белая отражающая карта справа»
Объектив и ракурс
Перспектива и глубина резкости находятся вне вашего контроля
«Макро 85 мм, f/5.6, фронтальный вид под углом 15 градусов вниз»
Цветокоррекция и носитель
По умолчанию получается перенасыщенный, рендерный вид
«Холодный нейтральный баланс белого, низкая общая насыщенность»
Композиция
Объект всегда оказывается строго по центру
«Чашка в левой трети кадра, большое негативное пространство справа»
Разрешение — не седьмой элемент. Выходное разрешение задаётся только параметрами вроде size / imageSize; если написать «4K» или «8K» в prompt, не добавится ни одного пикселя. См. Сжатие изображений и выходное разрешение.
Здесь достаточно дешёвой и быстрой текстовой модели; её стоимость ничтожна по сравнению с генерацией:
import osimport requestsBASE = "https://api.apiyi.com/v1"API_KEY = os.environ["APIYI_API_KEY"] # never hard-code the keyREWRITE_SYSTEM = """You are an image prompt engineer. Rewrite the user's casual briefinto one structured image prompt.Fill in all six elements. Supply whatever is missing; never ask the user:1 Subject: material, colour, count, state2 Environment: what the background is, what is sharp and what is blurred3 Light: direction, hardness, fill or no fill — there must be one identifiable key light4 Lens and angle: focal length, aperture, camera height, tilt5 Grading and medium: white balance bias, saturation, film or digital character6 Composition: where the subject sits in the frame, where the negative space isRules:- Output only the prompt body: no explanation, no bullet points, no heading- No brand names, logos, or legible text unless the user asked for them- Never use vague quality words such as 8K, ultra HD, masterpiece, perfect- Keep any element the user specified exactly as written"""def rewrite(user_prompt: str) -> str: r = requests.post( f"{BASE}/chat/completions", headers={"Authorization": f"Bearer {API_KEY}"}, json={ "model": "gemini-3.5-flash", "messages": [ {"role": "system", "content": REWRITE_SYSTEM}, {"role": "user", "content": user_prompt}, ], }, timeout=60, ) r.raise_for_status() return r.json()["choices"][0]["message"]["content"].strip()
Обратите внимание на правило, запрещающее «8K, ultra HD, masterpiece, perfect» — раздел 4 объясняет почему.
Соедините оставшиеся четыре слоя со слоем переписывания, и у вас будет вся схема:
1
Переписывание: неформальный ввод в структурированный prompt
См. раздел 2. Этот шаг по ходу дела также нейтрализует чувствительный контент во вводе пользователя, что заметно снижает, как часто запрос блокируется на следующих этапах.
2
Опора: референсные изображения плюс константа стиля
Стиль закрепляется двумя вещами: константой стиля, добавляемой к каждому prompt (ваш пресет), и фиксированным набором референсных изображений.Лимиты референсов сильно различаются по семействам — проверьте свой вариант, прежде чем проектировать конвейер:
Сумма входов и выходов должна оставаться на уровне 15 или ниже
FLUX.2 pro / max / flex
8
input_image_2 … input_image_8; klein берет 4, Kontext берет 1
Grok Imagine
1–4
Пятое изображение возвращает 400
Два правила, которых нужно придерживаться: «изображение 1 / изображение 2» в prompt строго соответствуют порядку в массиве, поэтому явно укажите, что есть что; и Grok учитывает референсные изображения только на /v1/images/edits — передача их в /v1/images/generations молча отбрасывает их и все равно списывает с вас средства.
3
Образцы: генерируйте N параллельно, не полагайтесь на n
Ощущение потребительского продукта в духе «попал с первого раза» на самом деле означает, что продукт вытягивает несколько карт за вас.Но параметр n на стороне сервера не влияет на большинство image models (Seedream полностью его игнорирует). Чтобы получить несколько кандидатов, отправляйте несколько запросов одновременно с клиента — на страницах skill этого сайта лимит составляет 5 за раз. Настраивайте параллельные запросы для каждого канала; некоторые начинают возвращать 429 уже при 2, так что добавьте экспоненциальную задержку повторов.
4
Отбор: используйте vision model в роли судьи
Когда у вас есть N кандидатов, вы должны выбрать автоматически, иначе вы просто переложили выбор на пользователя.Отправьте кандидатов обратно в vision model для оценки по стандартному /v1/chat/completions входу изображения; см. Понимание изображений для подходящих моделей. Зафиксируйте рубрику по пяти измерениям и требуйте JSON в ответ: соответствие инструкции, структура и анатомия, корректность текста, реалистичность текстуры, композиция.
Не используйте /v1/rerank для этого. bge-reranker-v2-m3 — это модель reranking только для текста и не принимает изображения. Для оценки изображений требуется модель для понимания изображений.
5
Доработка и релиз
Корректируйте локально после того, как композиция уже определена — так вы получите куда более высокий процент успеха, чем от одной составной инструкции:
Накопительное редактирование в несколько ходов: поддерживается на родном эндпоинте Gemini для моделей Nano Banana (передавайте предыдущее изображение обратно как role: "model"); маршруты, полученные реверс-инжинирингом, этого не поддерживают.
Сразу перенесите на свой хостинг: каждый возвращаемый URL временный (FLUX — примерно 10 минут и без CORS; Seedream и R2 — примерно 24 часа), поэтому загружайте его в свое объектное хранилище сразу, как только получите.
import base64import jsonimport osfrom concurrent.futures import ThreadPoolExecutorimport requestsBASE = "https://api.apiyi.com"API_KEY = os.environ["APIYI_API_KEY"]HEAD = {"Authorization": f"Bearer {API_KEY}"}STYLE_CONST = "Cool neutral white balance, low saturation, clean frame with generous negative space."def draw(prompt: str, size: str = "2K", aspect: str = "1:1") -> bytes: """Generate one image (Nano Banana Pro, native Gemini endpoint).""" url = f"{BASE}/v1beta/models/gemini-3-pro-image:generateContent" body = { "contents": [{"parts": [{"text": prompt}]}], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": aspect, "imageSize": size}, }, } r = requests.post(url, headers=HEAD, json=body, timeout=600) # headroom for 4K r.raise_for_status() parts = r.json()["candidates"][0]["content"]["parts"] part = next((p for p in parts if p.get("inlineData")), None) if part is None: # HTTP 200 with no image usually means moderation raise RuntimeError("no image returned: " + json.dumps(parts)[:300]) return base64.b64decode(part["inlineData"]["data"])def score(image: bytes, prompt: str) -> dict: """Score a candidate with a vision model; returns per-dimension scores and one issue line.""" data_url = "data:image/png;base64," + base64.b64encode(image).decode() rubric = ( "Score this image and return strict JSON: " '{"instruction":0-10,"anatomy":0-10,"text":0-10,"texture":0-10,' '"composition":0-10,"total":0-50,"issue":"one sentence"}. ' "instruction = does it satisfy the brief below; anatomy = errors in hands, limbs, object structure; " "text = is any text in the image correct (score 10 if there is none); " "texture = does it read as a real photograph rather than a render; " "composition = is the framing usable. The brief:\n" + prompt ) r = requests.post( f"{BASE}/v1/chat/completions", headers=HEAD, json={ "model": "gemini-3.5-flash", "messages": [{"role": "user", "content": [ {"type": "text", "text": rubric}, {"type": "image_url", "image_url": {"url": data_url}}, ]}], "response_format": {"type": "json_object"}, }, timeout=120, ) r.raise_for_status() return json.loads(r.json()["choices"][0]["message"]["content"])def best_of(user_input: str, n: int = 4) -> bytes: prompt = rewrite(user_input) + "\n" + STYLE_CONST # steps 1 and 2 with ThreadPoolExecutor(max_workers=n) as pool: # step 3: client-side fan-out results = list(pool.map(lambda _: _safe(draw, prompt), range(n))) cands = [img for ok, img in results if ok] if not cands: raise RuntimeError("all candidates failed; check moderation or fall back to another model") with ThreadPoolExecutor(max_workers=len(cands)) as pool: # step 4: score in parallel scores = list(pool.map(lambda im: score(im, prompt), cands)) ranked = sorted(zip(cands, scores), key=lambda x: x[1]["total"], reverse=True) return ranked[0][0] # step 5 retouch/rehost hooks in heredef _safe(fn, *args): try: return True, fn(*args) except Exception as e: # one failure must not sink the batch return False, str(e)
Одна и та же модель (gemini-3-pro-image), один и тот же объект, два стиля prompt, по две изображения в каждой, показана первая из каждой серии:
Bare prompt: 'A photorealistic half-body portrait of a young woman by a cafe window, smiling at the camera, 8K, ultra HD, ultra detailed, flawless skin, beautiful, perfect lighting, masterpiece'
The same subject after adding four blocks of control language: light position, lens, medium, imperfections
Левое изображение не плохое — базовая модель достаточно сильна, и даже простой prompt все равно дает красивую картинку. Но в нем проявляется весь набор признаков: объект жестко зафиксирован в центре, свет настолько равномерный, что невозможно сказать, откуда он идет, и каждый элемент выглядит безупречно-нейтральным. И это не случайность: оба изображения из этой партии имели по сути одинаковую композицию и схему освещения.Правая картинка сменила подход: свет имеет направление, половине лица позволено уйти в тень, на коже видны жирный блеск и поры, есть родинка на щеке, выбившиеся волосы не причесаны, а объект расположен чуть правее центра. Это читается как конкретный человек, снятый в конкретный момент, а не как «стоковая фотография улыбающейся женщины в кафе».
Именно здесь также проявляется реальная ценность pipeline. Он не превращает неудачный результат в красивый результат — он превращает «случайно удачное» в «то хорошее, которое вы задали, можете описать и можете воспроизвести». Заинтересованная сторона может не предпочесть правое изображение, но по левому вы не сможете сказать, почему оно выглядит именно так, и не сможете попросить следующее изображение повторить его.
Укажите расположение: «объект справа от центра, отрицательное пространство слева»
«идеальная композиция», «золотое сечение»
Пластиковая кожа без пор
«естественная текстура кожи, видимые поры и пушок на лице, лёгкий блеск на носу, без ретуши»
«безупречная кожа», «изысканный», «красивый»
Равномерный свет без различимого источника
Назовите один ключевой источник света и его жёсткость: «свет из окна слева — единственный источник, правая половина лица в тени»
«идеальное освещение», «мягкий свет»
Фальшивая глубина резкости, фон выглядит приклеенным
Укажите фокусное расстояние и диафрагму: «85mm, f/2.8, фокус на ближайшем глазе»
«размытый фон», «кинематографично»
Перенасыщенный, светящийся цвет
Укажите medium и баланс белого: «характер Kodak Portra 400, тёплые света и холодные тени, низкая насыщенность»
«яркие цвета», «HDR»
Всё выглядит новым и неношеным
Специально добавьте следы использования: «свитер с катышками, кольца от стаканов и крошки на столе»
«чисто и аккуратно», «премиальная текстура»
Смотрится как постер или рендер
Укажите ситуацию съёмки: «непозированно», «на уровне глаз с соседнего стола»
«8K», «ultra HD», «шедевр»
Размытые слова о качестве, такие как 8K, ultra HD, ultra detailed, masterpiece и perfect, скорее вредят. Они не добавляют детализации (её дают только параметры) и подталкивают model к слишком резкому, перенасыщенному render — именно в этом и суть AI-облика. Левый prompt выше был ими переполнен, и результат это показывает. Если вам нужен качественный результат, вместо этого указывайте конкретный свет, объектив и medium.
Четыре блока языка управления для копирования и вставки
Добавляйте в prompt по мере необходимости; одной-двух строк из каждого блока обычно достаточно:
Свет
window light from the left is the only source in frame / hard back-side light at three in the afternoon / backlit, with a rim light on the hair / a desk lamp as a practical light inside the frame / overcast diffuse light with no distinct shadows
Объектив
35mm f/2.0, candid, at eye level / 85mm f/2.8, focus on the near eye / 24mm from a low camera position, slight edge distortion / long lens compressing the space, flattened background layers / mild vignetting in the corners
Материал
Kodak Portra 400 character, fine grain / warm highlights, cool shadows / Polaroid instant film, low contrast, soft edges / noise and colour cast of an early CCD digital camera / low saturation overall, no sharpening
Нюансы
natural skin texture, visible pores and facial fuzz / a few loose strands of hair, unbrushed / pilled sweater, worn cuffs / water rings, fingerprints and crumbs on the table / off-centre framing, part of the subject cropped at the edge
Портрет: непринуждённый, не как на фото на удостоверение
Непостановочный портрет по пояс: женщина лет двадцати с небольшим у окна кафе, повернута в сторону, смотрит наружу, с улыбкой, которую она едва сдерживает. Свет из окна слева — единственный источник в кадре; правая половина её лица уходит в тень, под переносицей — небольшая жёсткая тень с чётким краем. Объектив 85 мм, f/2.8, на уровне глаз, фокус на ближнем глазе. Характер Kodak Portra 400 с мелким заметным зерном, тёплыми светами и холодными тенями, в целом низкой насыщенностью. Естественная кожа: видимые поры и пушок на лице, немного блеска на боку носа, маленькая родинка на левой щеке, несколько выбившихся волосков бровей, свободные пряди волос на лбу. Без сглаживания кожи, без бьюти-ретуши, без повышения резкости. Объект правее центра, слева — негативное пространство.
Предметная съёмка: готово для страницы товара
Главный кадр для e-commerce: матовая чёрная керамическая чашка для пуровера, заполненная на 80% чёрным кофе, с тонким кольцом крема на поверхности. Она стоит на светло-серой поверхности из микробетона, а позади — размытая стена того же оттенка. Основной свет — от софтбокса в левом верхнем углу, под углом 45 градусов; белый отражатель справа оставляет узкий блик вдоль правого края чашки; мягкая падающая тень уходит назад вправо. Объектив-макро 85 мм, f/5.6, фронтальный вид, наклонённый вниз на 15 градусов, вся чашка в резкости. Холодный нейтральный баланс белого, в целом низкая насыщенность. Глазурь имеет лёгкую ручную неравномерность и один крошечный след от обжига в печи, а на кромке заметен едва различимый след использования. Щедрое негативное пространство, чашка в левой трети кадра. В изображении нигде нет названий брендов или текста.
Окружение: укажите конкретное время и погоду
Узкая улица старого города в шесть вечера, сразу после дождя, с лужами, отражающими световые вывески магазинов по обе стороны. Единственный основной свет — тёплый уличный фонарь в конце улицы, а в качестве заполняющего света — витрины магазинов; в небе ещё ощущается след холодных сумерек, создавая тёпло-холодный контраст. Объектив 28 мм, f/4, камера на уровне глаз, слегка наклонена вверх. В целом низкая насыщенность, шум сохранён в тенях, без осветления теней. На стенах — потёки от воды, рваные старые плакаты и блоки кондиционеров; верхнюю часть кадра пересекают линии электропроводов. Никто не смотрит в камеру; прохожие видны со спины и слегка смазаны движением.
Зная это заранее, вы сэкономите себе один цикл переделки:
Факт
Последствие для pipeline
Seed фактически недоступен в этой линейке продуктов: ни одна модель Nano Banana или GPT-Image не предоставляет seed, эффективность seed в Seedream 4.x / 5.x измерялась как нулевая, а Grok Imagine его не поддерживает
Не стройте воспроизводимость на seed. Единственный надёжный способ воспроизведения — архивировать весь успешно выполненный запрос — prompt, reference images, все параметры — и повторно отправлять его без изменений
Параметр n на стороне сервера не влияет на большинство image моделей
Несколько кандидатов должны приходить из параллельных запросов на стороне клиента; проведите нагрузочное тестирование параллельных запросов по каждому каналу и добавьте экспоненциальный backoff
Все image API синхронные, не имеют task ID и всё равно тарифицируются при разрыве соединения
Нет эндпоинта для upscaling, удаления фона или восстановления лица
Определяйте размер результата на этапе генерации; прозрачный фон можно получить только через prompt к семейству seedream-5-0
HTTP 200 без изображения обычно означает блокировку модерацией
Логика выбора должна различать «изображение не вернулось» и «изображение вернулось, но оно непригодно»; для первого случая см. Обработка ошибок Gemini Image
Каждый возвращаемый URL изображения — временная ссылка
Перехостите его сразу после получения; никогда не храните исходный URL в вашей базе данных
Пайплайн обменивает деньги на более высокий success rate. На стоимость генерации изображений сильнее всего влияет output (gpt-image-2 выставляет счёт за output по $30 за миллион tokens), тогда как text- и vision-модели, используемые для переписывания и оценки, почти не влияют на итог. Поэтому стоимость по сути определяется тем, сколько вариантов вы сгенерировали.Используйте три уровня вместо одной настройки для всего:
Уровень
Состав
Относительная стоимость
Для чего
Draft
Одноразовый запрос через Lite model
1×
Внутренние предпросмотры, массовые заглушки, простые эксперименты пользователей
Standard
Переписывание + 2 варианта + выбор по оценке
около 2×
Стандартный путь в consumer product
Premium
Переписывание + 4 варианта + оценка + одна локальная доработка
около 5×
Hero images продукта, рекламные креативы, всё, что передаётся наружу
Проверка простая: увидит ли это изображение кто-либо за пределами вашей команды? Если да, Standard или выше окупается; если это только внутренний просмотр, Draft достаточно. Вы также можете добавить промежуточное условие — генерировать больше вариантов только тогда, когда лучшая оценка падает ниже порога, что позволяет большинству запросов сходиться на двух.
Пробел не в весах модели, а в восьми слоях вокруг модели: переписывание, presets, anchoring, sampling, selection, пошаговое редактирование, post-processing, rehosting.
Слой переписывания даёт лучшую отдачу: добавьте субъект, окружение, свет, объектив, grading и композицию, и «выглядит красиво» станет «можно использовать».
Несколько кандидатов плюс оценка с помощью vision-model — вот откуда на самом деле берётся высокий воспринимаемый процент успеха у потребительских продуктов. n не работает, поэтому делайте fan out на стороне клиента; /v1/rerank не может оценивать изображения.
Убрать AI-внешний вид значит добавить конкретику, а не прилагательные: назовите один источник света, укажите фокусное расстояние и диафрагму, задайте medium и grain, намеренно добавьте несовершенства и сместите субъект от центра.
8K / masterpiece / perfect lighting — это чисто отрицательные варианты — дополнительного разрешения нет, а кадр они уводят в сторону отрендеренного вида.
Не рассчитывайте на seeds для воспроизведения; вместо этого архивируйте полный запрос. Image API синхронны и списывают плату при разрыве соединения, поэтому pipeline нужна очередь.
У APIYI нет эндпоинтов для upscaling, удаления фона или identity-training; проектируйте архитектуру с учётом этих слоёв с самого начала.