Руководство
Как использовать flux-1.1-pro через HiAPI API: curl, Python и работающие запросы
Практическое руководство по интеграции: запросы, которые действительно работают, асинхронная обработка и рецепты промптов с реальными выводами
На этой странице
Что даёт flux-1.1-pro до того, как вы напишете код
flux-1.1-pro — это модель генерации изображений по тексту, вызываемая через HiAPI.ai как управляемая конечная точка. Вы отправляете промпт и параметры генерации в формате JSON, а возвращается сгенерированное изображение. Ничего устанавливать не нужно, веса не нужно хостить самостоятельно, и не нужно управлять GPU-ресурсами. Ваша поверхность интеграции — это HTTP-эндпоинт плюс учётные данные для аутентификации.
Для разработчика это означает, что ещё до первой строки кода дизайн определяют три вещи.
Во-первых, запрос — это JSON на входе и изображение на выходе. Ваш промпт, соотношение сторон и несколько управляющих параметров лежат в теле запроса. Ответ несёт данные изображения или ссылку на них, в зависимости от способа доставки задачи. Относитесь к телу запроса как к контракту и храните его в одном месте, чтобы пути curl и Python никогда не расходились.
Во-вторых, по сравнению с обычным вызовом API генерация изображения — медленная операция. Несколько секунд — это норма; сложные промпты в высоком разрешении могут занять больше. Любой производственный вызывающий код должен предполагать задержку и планировать её, а не трактовать вызов как чтение из базы данных.
В-третьих, качество вывода определяется в первую очередь промптом, а не обвязкой. Интеграция — простая часть. Настоящая работа — точно описать желаемое и проверить рецепт на реальных выводах до запуска в продакшен.
Держа в уме эти три вещи, остальная часть руководства — механический процесс: составить запрос, убедиться, что он работает, перенести его, затем укрепить и настроить. На всём пути всё идёт через HiAPI API — одни учётные данные, один базовый URL, одна структура JSON для изучения.
Ваш первый curl-запрос
Начните с curl. Он убирает все слои абстракции между вами и эндпоинтом, поэтому при сбое вы точно знаете: проблема в теле запроса, а не в вашем фреймворке.
Минимальный вызов состоит из трёх частей: эндпоинт, заголовок аутентификации и тело JSON.
curl -X POST "https://api.hiapi.ai/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-1.1-pro",
"prompt": "a ceramic coffee mug on a weathered wooden table, soft morning window light, shallow depth of field, product photography",
"aspect_ratio": "1:1"
}'
Прочитайте тело запроса по полям:
modelзадаёт модель, которую вы используете. Указывайте её явно, чтобы будущие изменения значений по умолчанию никогда не изменили ваш вывод незаметно.prompt— это описание на естественном языке. Здесь сосредоточен почти весь ваш бюджет качества.aspect_ratioуправляет кадрированием. Выбирайте его осознанно, а не полагайтесь на непроверенное значение по умолчанию.
Поместите ключ в переменную окружения (HIAPI_API_KEY), а не вставляйте его прямо в команду. Эта привычка напрямую перейдёт в Python и в любые шаги CI, которые вы добавите позже.
При успешном вызове вы получите JSON-ответ с описанием готового изображения. Прежде чем закрыть терминал, изучите его и найдите ссылку на изображение или данные. При неудачном вызове вы получите тело ошибки с кодом состояния и сообщением; читайте это сообщение буквально, потому что неверный формат поля — самая частая причина первого сбоя.
Предупреждение, экономящее час: не вставляйте многострочные промпты с неэкранированными кавычками в shell. Для всего длиннее короткой фразы используйте heredoc или файл.
curl -X POST "https://api.hiapi.ai/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
--data @request.json
Этот request.json — артефакт, который следует закоммитить в репозиторий. Это единственный источник истины для тела запроса, и следующий раздел использует его как есть.
Перенос того же вызова в Python
Цель переноса — не написать новую логику, а отправить точно такое же тело JSON. Загружайте тот же request.json, чтобы два пути не могли разойтись.
import json
import os
import requests
API_URL = "https://api.hiapi.ai/v1/images/generations"
with open("request.json") as f:
payload = json.load(f)
response = requests.post(
API_URL,
headers={
"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=120,
)
if response.status_code != 200:
print(response.status_code)
print(response.text)
response.raise_for_status()
print(response.json())
Здесь важны три детали.
Заголовок аутентификации и заголовок содержимого — одна группа заголовков. Использование json=payload заставляет requests сериализовать тело запроса и установить тип содержимого; явное указание заголовка безвредно и документирует намерение.
Задайте таймаут. Никогда не оставляйте запрос генерации висеть на бесконечном значении по умолчанию. Щедрый явный таймаут — это нормально; главное, чтобы он был явным.
Проверяйте тело ошибки до выброса исключения. Если сначала вызвать raise_for_status(), он отбросит тело ответа из ваших логов. Сначала напечатайте код состояния и текст, затем выбрасывайте. Когда поле отклонено, вам понадобится этот текст.
Если вы используете асинхронный HTTP-клиент, структура не меняется: тот же URL, те же заголовки, то же тело, только await client.post(...) с тем же таймаутом. Контракт тела запроса постоянен; клиент — деталь реализации.
Храните тело запроса вне исходников Python. Когда рецепт промпта работает, он должен лежать в файле или строке базы данных, а не в строковом литерале внутри функции — так вы сможете сравнить его и перезапустить.
Обработка асинхронных задач без блокировки приложения
Относитесь к генерации как к задаче, а не как к вызову функции. Независимо от того, выглядит ли ваш путь доставки синхронным или возвращает задачу, которую нужно опрашивать, практическое следствие одно: ваше приложение никогда не должно бесконечно занимать поток запроса в ожидании изображения.
Рабочий шаблон состоит из четырёх шагов.
1. Отправляйте из воркера, а не из пользовательского запроса
Примите действие генерации от пользователя на уровне веб-слоя, сохраните запись задачи, поставьте её в очередь и сразу верните ответ. Фактический вызов API выполняет фоновый воркер. Пользователь опрашивает ваш эндпоинт, а не модель.
2. Ограничьте ожидание
Задайте таймаут для каждой попытки, выбранный осознанно. Если платформа возвращает задачу, которую нужно опрашивать, опрашивайте с фиксированным интервалом, максимальным числом попыток и дедлайном, отсчитываемым от момента старта задачи, а не от числа попыток. Предпочитайте умеренную задержку вместо плотного цикла.
3. Повторяйте только те сбои, которые стоит повторять
Повторяйте транспортные ошибки, таймауты и серверные сбои с экспоненциальной задержкой и джиттером в пределах небольшого числа попыток. Не повторяйте ошибки валидации: отклонённое поле или пустой промпт будут сбоить одинаково каждый раз, и повтор лишь заставит пользователя дольше ждать настоящего сообщения.
4. Сделайте задачу идемпотентной на своей стороне
Записывайте в базу точное тело запроса и ID задачи. Если ваш воркер упал после отправки, но до записи успеха, вы можете перепроверить задачу, а не слепо отправлять её снова. Когда повторная отправка всё же необходима, добавьте короткий клиентский ключ дедупликации, чтобы временный сбой не поставил в очередь три одинаковые генерации.
import time
def poll_until_done(fetch_status, job_id, deadline_seconds=180):
start = time.monotonic()
delay = 2.0
while True:
status = fetch_status(job_id)
if status["state"] in ("succeeded", "failed"):
return status
if time.monotonic() - start > deadline_seconds:
raise TimeoutError(f"generation {job_id} exceeded deadline")
time.sleep(delay)
delay = min(delay * 1.5, 10.0)
Этот вспомогательный метод намеренно универсален: он принимает функцию получения статуса, поэтому один и тот же цикл подходит для любой задачо-ориентированной конечной точки, которую вы интегрируете позже. Важные свойства — дедлайн, ограниченная задержка и проверка конечного состояния, а не конкретный транспорт.
Создание промптов, которые стабильно рендерятся
Длинный промпт не равен лучшему промпту. Структура важнее. Повторяемый каркас даёт стабильные результаты и место, где при проблемах можно менять по одной переменной.
Используйте четыре слота в следующем порядке:
- Субъект — что есть на изображении, конкретно. «Керамическая кофейная кружка» лучше, чем «что-то для кафе».
- Стиль — визуальный тон: фотография, иллюстрация, акварель, 3D-рендер, продуктовая съёмка. Укажите среду и, если полезно, свет.
- Композиция — кадрирование и камера: соотношение сторон, дистанция съёмки, угол, глубина резкости, положение субъекта в кадре.
- Ограничения — конкретное, что вы явно хотите и не хотите, кратко.
[subject] a single ceramic coffee mug, matte glaze, small handle
[style] product photography, soft diffused window light, muted palette
[composition] 1:1, eye-level, subject centered, shallow depth of field, plain background
[constraints] no text, no logos, no hands
При отправке разверните это в одну строку промпта; квадратные скобки — для вас, не для модели. Ценность письма по слотам в том, что когда вывод неверен, вы знаете, какой слот редактировать.
Несколько практических правил:
- Ставьте субъект первым. Первое предложение имеет наибольший вес.
- Предпочитайте конкретные существительные и прилагательные, а не абстрактные эмоции. «Матовая глазурь» меняет пиксели; «премиальность» — почти нет.
- Помещайте язык камеры в слот композиции, а не субъекта. Смешивание создаёт нетерпеливые и противоречивые инструкции.
- При итерации меняйте один слот за раз и сохраняйте точный текст промпта, давший принятый вывод.
Соотношение сторон — решение композиции, а не заплатка. Выбирайте его под место, где будет изображение — квадрат для сетки, выше для главного баннера — и подгоняйте остальную часть промпта под этот кадр.
Эффективное использование списков негативных слов
Список негативных слов говорит модели, чего избегать. Это острый инструмент с узкой областью применения: отлично подавляет повторяющиеся дефекты, но плох как мусорный бак для всех несовершенств, которые вы можете вообразить.
Негативные слова должны быть краткими и конкретными. Для большинства промптов достаточно пяти-восьми коротких пунктов. Указывайте конкретные вещи:
no text, no watermark, no logos, no extra fingers, no harsh shadows
Этот список работает, потому что каждый пункт называет видимое и проверяемое. Сравните с размытыми отрицаниями вроде «not ugly» или «bad quality» — они почти не несут действенного сигнала и размывают действительно важные пункты.
Где негативные слова действительно помогают:
- Подавление дефектов, которые вы видите снова и снова. Если руки или текст повторяются, прямое их указание — самый прямой фикс.
- Брендовая и юридическая гигиена. Исключите логотипы и водяные знаки до того, как изображение попадёт в пользовательский интерфейс.
- Принудительно чистый фон для продуктовых снимков или изображений, близких к UI.
Где они работают против вас:
- Противоречие позитивному промпту. «Без теней» в негативе против «драматического бокового света» в субъекте — конфликт, который модель разрешит непредсказуемо. Исправляйте позитивный промпт.
- Отрицание маловероятного. Длинный список маловероятных сбоев лишь добавляет шум и не меняет рендер.
- Использование негатива для компенсации размытого субъекта. Если субъект неясен, никакой список негативных слов его не спасёт.
Практическая деталь: некоторые клиенты принимают негативные слова как отдельное поле, а не как дополнительный текст. Выясните, какой способ поддерживает ваш запрос, и сохраните это поле в сохранённом теле запроса, чтобы curl и Python вели себя одинаково.
Рецепты промптов с реальными выводами
Приведённые ниже рецепты — отправная точка, а не гарантия. Честный рабочий процесс таков: запустите рецепт через свою интеграцию, посмотрите на вывод, затем настройте один слот. Любой вывод, который вы не сгенерировали лично, следует считать непроверенным.
Рецепт 1 — чистое продуктовое фото
A single matte-black wireless earbud case on a light concrete surface,
studio product photography, soft key light from the left, 1:1, centered,
shallow depth of field, plain background. No text, no logos, no hands.
Ожидаемые характеристики: чёткий, центрированный субъект, мягкое затухание и незахламлённый фон. Если поверхность выглядит слишком сложной, ужесточите «plain background» и уберите любые слова о текстуре. Если свет слишком плоский, добавьте одно направленное ключевое слово — и только его.
Рецепт 2 — редакционный портрет
Portrait of a person in a wool coat, natural window light, calm expression,
3:4, chest-up framing, subject slightly off-center, muted film palette.
No text, no watermark.
Ожидаемые характеристики: мягкий направленный свет, сдержанные цвета. Если кадрирование шире ожидаемого, переместите «chest-up framing» вперёд и уберите конкурирующие слова о композиции.
Рецепт 3 — изометрическая иллюстрация
Isometric illustration of a small reading nook: armchair, floor lamp, bookshelf,
flat vector style, limited palette of warm neutrals and one accent color,
1:1, centered composition, clean white background. No text, no gradients.
Ожидаемые характеристики: чистая геометрия и плоские заливки. Если палитра уходит в сторону, явно укажите акцентный цвет и оставьте «clean white background» последним предложением, чтобы оно победило.
Рецепт 4 — главный баннер
A wide misty mountain ridge at sunrise, layered depth, minimal detail,
16:9, subject occupying the lower third, generous empty sky for overlaid text.
No text, no watermark.
Ожидаемые характеристики: спокойное, малодетализированное изображение с полезным негативным пространством. Формулировка «overlaid text» резервирует место; она не рендерит буквы, а список негативных слов не пускает текст в само изображение.
Для каждого рецепта записывайте точное тело запроса, соотношение сторон и дату. При просмотре через месяц вы сможете перезапустить записанное тело и сравнить с записанным выводом, а не гадать, почему результат изменился.
Ошибки, ограничения и что проверять в первую очередь
Когда генерация сбоит или вывод неверен, пройдите этот чек-лист, прежде чем менять код.
Сначала проверьте тело запроса
- Тело запроса — валидный JSON? Висячие запятые или неэкранированные кавычки — самая частая причина первого сбоя. Проверяйте сохранённый
request.jsonперед отправкой. - Имена полей точно верны? Опечатанные параметры обычно отклоняются или молча игнорируются. Сверяйтесь со структурой запроса в документации, а не с памятью.
- Имя модели верно и существует? Не полагайтесь на значения по умолчанию.
- Промпт непустой и в пределах длины, указанной в документации? Ограничения указаны в документации платформы; читайте там, а не предполагайте число.
Затем проверьте аутентификацию и транспорт
- API-ключ существует и действителен? 401 обычно означает отсутствующий или неверно отформатированный заголовок, либо ротированный ключ.
- URL эндпоинта и метод верны? POST на GET-путь будет выглядеть как проблема с ключом.
- Ваш таймаут слишком жёсткий? Если клиент сдаётся до завершения задачи, вы видите таймаут, не связанный с моделью.
Затем проверьте структуру запроса
- Класс кода состояния говорит, куда смотреть. 4xx почти всегда проблема вашего запроса; 5xx обычно временные и заслуживают ограниченного повтора.
- Читайте сообщение об ошибке буквально. Печатайте тело ответа до выброса исключения. Поле, упомянутое в сообщении, и есть то, что нужно исправить.
- Ответы об ограничении скорости или квоте означают: замедлитесь и повторите с задержкой, а не переписывайте промпт.
Наконец, проверьте промпт
Если вызов успешен, но изображение неверно, вы в области промпта, а не ошибки:
- Субъект отсутствует или слишком общий? Переместите его в первое предложение и сделайте конкретным.
- Композиция неверна? Исправляйте и соотношение сторон, и слова кадрирования; не компенсируйте одно другим.
- Дефекты повторяются? Добавьте короткое, конкретное негативное слово.
- Есть противоречие? Найдите негативное слово, борющееся с позитивным промптом, и удалите его.
Самое важное — сохранять привычку: для каждой важной генерации записывайте точное тело запроса, статус ответа и ссылку на изображение. Воспроизводимость превращает отладку из догадок в сравнение. Составьте первый запрос, проверьте вывод, затем ужесточите промпт перед запуском — и сохраните тело запроса, с которым вышли в продакшен, чтобы следующее изменение имело реальную базу для сравнения.
Похожие статьи
Все статьи →-
Руководство
gemini-omni-1.2-flash на практике: 3 бизнес-сценария генерации видео и чек-лист внедрения
Три прикладных сценария: текстовые креативы, оживление стартового кадра и визуал, ограниченный референсными изображениями
-
Руководство
Как вызвать gpt-image-2.5-sunburst/text-to-image через HiAPI API: curl и Python
Практическое руководство по интеграции с рабочими запросами, обработкой референсных изображений и шаблонами повторов
-
Руководство
Как вызывать gpt-5.6-terra@azure через HiAPI API: руководство по curl и Python
Создайте рабочий запрос, добавьте потоковую передачу и вызов инструментов и обрабатывайте ошибки без догадок