Корисна міграція на Seedream 5.5 — це робота з файлами, а не просто заміна назви моделі: згенеруйте зображення, перевірте отримане завдання, збережіть зображення, а потім надішліть збережені байти як референс для редагування.
Seedream 5.5 на AIHubMix наразі використовує doubao-seedream-5-5 і POST /ai/v1/images/generations. У цьому посібнику створюється зображення керамічної чашки, а потім запитується редагування лише її кольору.
Обсяг: документацію перевірено 12 листопада 2026 року. Код пройшов лише локальну перевірку синтаксису та допоміжних функцій офлайн; запит на генерацію не виконувався. Це не є доказом якості результату, точності редагування, затримки чи фактичного рахунку.
1. Підготуйте один короткий і чіткий запит
Використовуйте Python 3.10+ і requests. У Bash установіть залежність і введіть ключ так, щоб його значення не потрапило в історію команд оболонки:
python3 -m pip install requests
read -r -s -p 'AIHubMix API key: ' AIHUBMIX_API_KEY
printf '\n'
export AIHUBMIX_API_KEY
Для розгорнутого коду передавайте змінну середовища через менеджер секретів. Не зберігайте ключ у файлах із вихідним кодом, прикладах запитів, журналах, ноутбуках чи коді браузера. Перш ніж надсилати будь-який із двох POST-запитів, увімкніть функцію завдань для облікового запису, як вимагає посібник з асинхронних завдань. Ця вимога стосується нативних ендпоінтів медіазавдань /ai/v1, зокрема й синхронного очікування; вона не залежить від вибору фонового виконання.
Перегляньте актуальну схему ендпоінта моделі, вибравши запис за path, а не за позицією в масиві. Обмеження, специфічні для моделі, мають перевагу над спільним списком параметрів.
| Параметр | Використане тут значення |
|---|---|
| Модель | doubao-seedream-5-5 |
| Маршрут | POST /ai/v1/images/generations |
| Тіло запиту | Плаский JSON |
| Розмір | 2048x2048 |
| Кількість зображень | n = 1 |
| Формат файлу | png |
| Формат відповіді | url |
Схема вимагає model і непорожній prompt, обмежує n значенням 1 та передбачає вивід у форматах png і jpeg. Параметр image приймає URL, вхідні дані у форматі Base64 або об’єкт {url}; параметр images приймає масив із опублікованим максимальним значенням у 14 референсів. Це обмеження тут не перевірялося під час виконання. У прикладі використовується один референс і явно заданий розмір за замовчуванням, без зовнішнього об’єкта input чи розширень extra.
2. Згенеруйте зображення, перевірте завдання та збережіть PNG
Документація уніфікованого API для зображень визначає відповідь із полями завдання id, object: image, model, status, output і error. Не сприймайте її як застарілий формат data[0].url.
Спочатку ознайомтеся з коротким робочим процесом; повне налаштування та допоміжна функція завантаження наведені в згорнутому Додатку нижче. Перш ніж виконувати ці приклади, один раз завантажте блок із додатка в ту саму сесію Python. Він визначає settings, api_json і collect, не надсилаючи запит на генерацію зображення. Потім запускайте короткі блоки по черзі. Кожен POST — це окрема платна дія; не запускайте його повторно, щоб виправити відсутню відповідь або невдале завантаження.
Надішліть запит на зображення один раз
generation = {
**settings,
"prompt": "Product photograph of one matte blue ceramic mug on a cream tabletop, "
"soft side lighting, plain warm-gray background, no text or logos.",
}
task = api_json("POST", IMAGES + "/generations", generation)
Перевірте завдання, а потім збережіть PNG
Якщо не вказати async, запит чекатиме синхронно. Навіть за HTTP 200 відповідь може містити status: failed. Допоміжна функція зберігає ID завдання перед перевіркою статусу: завантаження виконується лише для completed; значення failed, cancelled та невідомі статуси призводять до зупинки. Для pending і in_progress потрібно перевірити наявне завдання, а не надсилати запит на генерацію знову.
collect(task, "mug-blue")
Цей єдиний виклик використовує ключ, яким створено завдання, щоб отримати завершений результат, перевіряє байти PNG і зберігає файл як mug-blue.png. Він не повторює автоматично створення й відхиляє несподівані хости завантаження або перенаправлення до того, як переслати ключ. Повна реалізація наведена в додатку; це описана в документації поведінка, а не перевірений результат генерації.
Посібник моделі зазначає, що URL результатів доступні приблизно 30 хвилин. Завантажте файл якнайшвидше з тим самим заголовком Bearer і збережіть байти самостійно. expires_at: null не означає, що файл зберігатиметься постійно. Якщо заповнено b64_json, декодуйте його замість завантаження за URL.
3. Редагуйте локальний файл, а не захищений URL для завантаження
Перш ніж витрачати кошти на редагування, самостійно перевірте збережене зображення. Те, що автентифікований клієнт може завантажити content_url, не означає, що провайдер зображень зможе отримати його за публічним URL. Повторно завантажте локальний PNG як Data URI:
reference = Path("mug-blue.png").read_bytes()
if not reference.startswith(b"\x89PNG\r\n\x1a\n"):
raise SystemExit("The editing reference must be the saved PNG.")
edit = {
**settings,
"prompt": "Change only the mug color from blue to forest green. Preserve the mug shape, "
"camera angle, tabletop, background, lighting, and shadows.",
"image": "data:image/png;base64," + base64.b64encode(reference).decode("ascii"),
}
task = api_json("POST", IMAGES + "/generations", edit)
collect(task, "mug-green")
Цей запит вимагає зберегти зображення; він не доводить, що збереження відбулося. Перевірте результат, перш ніж розпочинати наступний платний раунд. Увесь JSON-запит, включно з вбудованим кодуванням, має вкладатися в 32 MiB; також діють обмеження моделі на медіадані. Ще один прийнятний варіант — справді публічний URL зображення, доступний провайдеру.
4. За бажанням: асинхронне очікування та відновлення після переривання
Вимога до облікового запису з розділу 1 не залежить від режиму виконання. Помилка 403 async_not_enabled означає, що функцію завдань потрібно активувати в консолі. Лише фонове виконання є необов’язковим.
Якщо ви віддаєте перевагу фоновій генерації, створіть той самий словник generation, а потім замість рядка синхронного виклику task = api_json(...) і окремого виклику collect(...) скористайтеся наведеними нижче двома рядками. Виберіть режим до надсилання запиту; не запускайте обидва варіанти:
task = api_json("POST", IMAGES + "/generations", {**generation, "async": True})
collect(task, "mug-blue", poll=True)
Допоміжна функція приблизно кожні 15 секунд надсилає запит GET /ai/v1/images/{id}, доки завдання не перейде в кінцевий стан. Це рекомендований у документації інтервал опитування, а не обов’язковий інтервал, встановлений сервером. Для вебхуків потрібне значення async: true; налаштування приймача вебхуків виходить за межі цього посібника.
Якщо збирання результату зупинилося, за потреби повторно завантажте лише спільний блок налаштування й допоміжних функцій із додатка в новій сесії, а не блок створення. Якщо ID збережено, продовжте без POST-запиту:
task_id = Path("mug-blue.task-id").read_text(encoding="utf-8").strip()
task = api_json("GET", IMAGES + "/" + quote(task_id, safe=""))
collect(task, "mug-blue", poll=True)
Щоб відновити редагування, використайте відповідний префікс mug-green. Якщо відповідь створення зникла до збереження ID, натомість перегляньте нещодавні завдання:
recent = api_json("GET", IMAGES + "?limit=20&order=desc")
for row in recent.get("data", []):
print(row.get("id"), row.get("model"), row.get("status"), row.get("created_at"))
Зіставте модель і час створення; не вибирайте навмання найновіше завдання. За потреби використайте next_after як курсор after для наступного запиту. Якщо відповідність неоднозначна, зверніться до служби підтримки, а не надсилайте запит повторно. Список — це знімок стану; для опитування використовуйте деталі завдання. Значення output_error у рядку означає, що не вдалося прочитати результат, а не те, що генерація нічого не створила чи сума списань змінилася.
Продовжуйте використовувати ключ, яким створено завдання. Зокрема, доступ до списку уніфікованих завдань, їхніх деталей і вмісту ізольований за токеном: інший ключ того самого облікового запису не може прочитати ці завдання. Переривання на локальному пристрої не доводить, що завдання не виконалося або що кошти не списано.
5. Помилки міграції та актуальні помилки
Документація застарілого адаптера Doubao перелічує старіші ID для /v1/models/doubao/<id>/predictions з обгорткою input. У цьому переліку немає версії 5.5. Використовуйте наведений тут доступний маршрут для 5.5 і пласке тіло запиту; збої застарілого способу генерації не перевірялися. Точно скопіюйте актуальний ID із дефісами, а не припускайте, що варіант із крапками є його псевдонімом.
Не переносіть сюди верхньорівневі параметри quality, background, aspect_ratio чи seed: їх немає в актуальній схемі цієї моделі. У анонсі ByteDance про запуск описано нативне створення з прозорістю RGBA, але схема шлюзу не передбачає ані background, ані layer_decomposition. Сам вибір PNG не є перевіреним способом отримати прозоре зображення.
Ці помилки описані в документації уніфікованого API для зображень, але не спостерігалися у відповідях 5.5. Перевіряйте HTTP-статус окремо від статусу завдання та обробляйте поле code, а не повний текст повідомлення.
| Де | Код | Наступна дія |
|---|---|---|
| HTTP 400 | schema_violation | Виправте поля відповідно до схеми |
| HTTP 400 | capability_not_supported | Приберіть непідтримувані параметри |
| HTTP 504 | sync_timeout | Відновіть роботу; зверніться до служби підтримки |
| HTTP 502 | task_status_unavailable | Не надсилайте запит повторно |
| HTTP 422 | output_blocked | Змініть вміст |
| HTTP 403 | async_not_enabled | Активуйте функцію завдань |
| Завдання завершилося помилкою | result_delivery_failed | З’ясуйте, що сталося з наявним результатом |
Для HTTP 502 task_status_unavailable у посібнику сказано:
Не вдалося підтвердити стан завдання у провайдера моделі. Не надсилайте запит повторно. Зверніться до служби підтримки, вказавши ID завдання або ID запиту.
Для помилки на рівні завдання result_delivery_failed зазначено:
Не вдалося передати згенерований результат. Не надсилайте запит повторно автоматично. Зверніться до служби підтримки, вказавши ID завдання.
sync_timeout не доводить, що виконання взагалі не відбулося. Збережіть error.tid, використовуйте ID завдання лише тоді, коли його справді повернули, а в разі невизначеного результату попросіть службу підтримки з’ясувати ситуацію. Якщо завантаження можна відновити, повторіть отримання результату, а не генерацію. Помилка 410 artifact_expired означає інше: цей артефакт уже неможливо отримати. Спершу перевірте збережені файли; якщо потрібна заміна, свідомо дозвольте нову платну генерацію. За помилки 429 too_many_downloads перевірте збережені копії або зверніться до служби підтримки; очікування саме по собі не гарантує відновлення доступу.
У посібнику прямо зазначено, що плата за генерацію не стягується у випадку output_blocked, зокрема коли про це повідомляється в завданні зі статусом помилки. Не поширюйте цей виняток на всі завдання зі збоями чи модерацією; для output_policy_violation діють чинні правила оплати, пов’язані з модерацією.
6. Плануйте бюджет на весь процес, а не лише на один результат
У звіті Sina Technology про запуск вказано приблизну вартість 0.28 CNY за одне редагування зображення розміром 2K із квадратним співвідношенням сторін, включно з вхідним і вихідним зображеннями; текстові токени безкоштовні. Це дані зі ЗМІ, а не перевірений офіційний тариф чи цінова пропозиція AIHubMix.
Для прикладу: два платні раунди редагування наявного зображення, кожен заокруглено відповідає цьому сценарію, коштуватимуть приблизно 2 × CNY 0.28 = CNY 0.56. Сюди не входять початкова генерація з тексту в зображення, додаткові референси, додаткові варіанти та повторні спроби. Це не фактичний рахунок.
Для цього сценарію «генерація, потім редагування» використовуйте формулу загальна вартість = плата за початкову генерацію + плата за редагування з референсом. За матеріалами розглянутих сторінок не вдалося встановити повний офіційний тариф для 5.5, тож у цьому посібнику не наведено ані фіксованої загальної вартості, ані точного співвідношення економії між старою та новою версіями.
Перш ніж надсилати запит:
- Перевірте актуальний ID, маршрут, пласке тіло запиту та схему моделі.
- Зберігайте ключ у змінній середовища, а ID завдань — для відновлення.
- Вважайте кожен POST окремою платною дією, а завантаження повторюйте лише для отримання результату.
- Перевірте статус завдання та збережене зображення, перш ніж редагувати його.
- Повторно завантажте локальні дані зображення, указавши правильний MIME-тип.
- З’ясуйте долю завдань із невизначеним статусом, перш ніж запускати генерацію повторно.
Почніть з одного зображення й однієї ретельно продуманої правки; додавайте наступні кроки лише після перевірки файлів.
Додаток: спільне налаштування та допоміжна функція завантаження
Пропустіть цей додаток, якщо читаєте посібник. Перш ніж запускати короткі приклади, розгорніть цей блок і один раз завантажте його в ту саму сесію Python. Він налаштовує сесію та визначає функції, не генеруючи зображення. Щоб відновити перерване завдання в новій сесії, завантажте повторно лише цей блок, а не блок створення чи редагування.
Розгорніть повний допоміжний код — завантажте один раз перед короткими прикладами; запитів на створення зображення немає
import base64
import os
import time
from pathlib import Path
from urllib.parse import quote, urlsplit
import requests
BASE = "https://aihubmix.com"
IMAGES = "/ai/v1/images"
settings = {
"model": "doubao-seedream-5-5",
"size": "2048x2048",
"n": 1,
"output_format": "png",
"response_format": "url",
}
client = requests.Session()
client.headers["Authorization"] = "Bearer " + os.environ["AIHUBMIX_API_KEY"]
def api_json(method, path, body=None):
try:
response = client.request(
method, BASE + path, json=body,
timeout=(15, 600), allow_redirects=False,
)
except requests.RequestException:
raise SystemExit(
"Connection interrupted. Recover the existing task before another POST."
) from None
try:
data = response.json()
except ValueError:
raise SystemExit(
f"HTTP {response.status_code}: non-JSON response; recover before another POST."
) from None
if not isinstance(data, dict):
raise SystemExit("Unexpected response; recover before another POST.")
if not 200 <= response.status_code < 300:
error = data.get("error") or {}
raise SystemExit(
f"HTTP {response.status_code}: code={error.get('code')}, "
f"tid={error.get('tid')}. No automatic generation retry."
)
return data
def collect(task, stem, poll=False):
task_id = task.get("id")
if not isinstance(task_id, str) or not task_id:
raise SystemExit("No task ID returned. Recover from the task list; do not resubmit.")
Path(stem + ".task-id").write_text(task_id + "\n", encoding="utf-8")
while True:
status = task.get("status")
print("Task:", task_id, "status:", status)
if status == "completed":
break
if status not in {"pending", "in_progress"}:
error = task.get("error") or {}
raise SystemExit(
f"Stopped: status={status}, code={error.get('code')}; task={task_id}."
)
if not poll:
raise SystemExit("Task still active. Query the saved ID; do not recreate it.")
time.sleep(15)
task = api_json("GET", IMAGES + "/" + quote(task_id, safe=""))
output = task.get("output") or []
if not output:
raise SystemExit("Completed without readable output; investigate the saved task.")
item = output[0]
if item.get("b64_json"):
image_bytes = base64.b64decode(item["b64_json"], validate=True)
else:
url = item.get("content_url")
if not isinstance(url, str):
raise SystemExit("Missing content_url; investigate the saved task.")
parsed = urlsplit(url)
if (parsed.scheme, parsed.netloc) != ("https", "aihubmix.com"):
raise SystemExit("Unexpected download origin; key was not forwarded.")
try:
response = client.get(url, timeout=(15, 120), allow_redirects=False)
except requests.RequestException:
raise SystemExit("Download interrupted; recover this task, not a new generation.") from None
if not 200 <= response.status_code < 300:
try:
detail = response.json()
except ValueError:
detail = {}
error = detail.get("error", {}) if isinstance(detail, dict) else {}
code = error.get("code") if isinstance(error, dict) else None
if response.status_code == 410 or code == "artifact_expired":
raise SystemExit("Artifact expired; retrieval cannot recover it. Check saved files first.")
if code == "too_many_downloads":
raise SystemExit("Download allowance exhausted; check saved files or contact support.")
raise SystemExit(
f"Download HTTP {response.status_code}, code={code}; "
"inspect the saved task. Retry retrieval only if recoverable."
)
image_bytes = response.content
if not image_bytes.startswith(b"\x89PNG\r\n\x1a\n"):
raise SystemExit("Expected PNG bytes; stopped before saving or reusing the result.")
destination = Path(stem + ".png")
destination.write_bytes(image_bytes)
print("Saved:", destination)
return destination
Тайм-аут читання у 600 секунд — це налаштування клієнта, а не обіцянка щодо затримки сервісу. Перевірка PNG відповідає явно заданому в цьому посібнику формату виводу; якщо виберете JPEG, змініть її відповідно.
FAQ
Який ID моделі та ендпоінт слід використовувати для Seedream 5.5?
Використовуйте doubao-seedream-5-5 із POST /ai/v1/images/generations і пласким JSON. Не вважайте інше написання чи застарілий адаптер рівноцінними.
Чи містить цей посібник перевірені результати генерації?
Ні. Код ґрунтується на документації; перевірено лише синтаксис і допоміжні функції в автономному режимі. Запитів на інференс, вимірювань якості зображень і затримки чи перевірки білінгу не виконували.
Чи обов’язковий асинхронний режим?
Ні; за замовчуванням використовується синхронне очікування. Фонове виконання вмикається булевим параметром async: true. Для нативних ендпоінтів завдань медіа потрібне попереднє ввімкнення відповідної функції на рівні облікового запису, навіть якщо очікування синхронне.
Чи означає HTTP 200, що зображення створено успішно?
Ні. Перевірте статус завдання та повідомлення про помилку. Завдання може завершитися помилкою, навіть якщо HTTP-запит успішний; завантажуйте результат лише після завершення.
Чи можна використати URL для завантаження результату як наступне посилання для редагування?
Не варто цього припускати. Завантажте зображення за допомогою ключа, яким його створено, а потім закодуйте локальний файл як Data URI або вкажіть справді загальнодоступний URL зображення.
Що робити після тайм-ауту або втрати відповіді?
Не запускайте генерацію повторно автоматично. Перевірте збережений ID завдання або знайдіть його у списку зображень за допомогою ключа, яким його створено. Збережіть ID запитів і зверніться до служби підтримки, якщо результат невідомий.
Чи гарантує вибір PNG прозорий результат або рахунок на CNY 0.28?
Ні те, ні інше. У схемі немає підтвердженого параметра керування прозорістю. CNY 0.28 — це приблизна вартість редагування зображення 2K, наведена в пресі, а не пропозиція AIHubMix і не фіксована ціна за створення зображення з тексту та його редагування.
Читайте далі: серія Seedream 5.5
- Перш ніж змінювати наявний робочий процес на 5.0 Pro, оцініть переваги оновлення: Seedream 5.5 чи 5.0 Pro: чи варто переходити?
- Якщо в тому самому робочому процесі можна використати іншу модель зображень, порівняйте компроміси: Seedream 5.5 чи GPT Image 2.6 Sunburst: що вибрати?
Джерела
- Анонс запуску Seedream 5.5 — ByteDance Seed; заявлені постачальником можливості.
- Актуальна схема ендпоінта Seedream 5.5 — AIHubMix; поля запиту та обмеження для конкретної моделі.
- Уніфікований API генерації зображень — AIHubMix; завдання, завантаження та актуальні помилки.
- Посібник із моделі Seedream 5.5 — AIHubMix; ID моделі та короткочасні посилання для автентифікованого завантаження; щодо помилок, характерних для окремих маршрутів, дивіться документацію уніфікованого API.
- Матеріал про запуск Seedream 5.5 — Sina Technology; приблизний сценарій вартості редагування, а не офіційний тариф.



