Полезната миграция към 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 като формати за изход. Приема URL в image, входни данни в 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 като 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)
Помощната функция изпраща заявка към GET /ai/v1/images/{id} приблизително на всеки 15 секунди, докато задачата достигне крайно състояние. Това е препоръчаният в документацията интервал за проверка, а не интервал, налаган от сървъра. Уебкуки изискват 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 в даден ред означава, че резултатът не може да бъде прочетен, а не че генерирането не е произвело нищо или че таксите са се променили.
Продължете да използвате ключа, с който е създадена задачата. По-специално, достъпът до списъка, подробностите и съдържанието на задачите в обединения API е изолиран по токен: друг ключ от същия акаунт не може да прочете тези задачи. Локално прекъсване не доказва нито че задачата е неуспешна, нито че не са начислени такси.
5. Грешки при миграцията и актуални грешки
Документацията за наследения адаптер на Doubao изброява по-старите ID под /v1/models/doubao/<id>/predictions с обвивка input. В списъка ѝ няма версия 5.5. Използвайте откриваемия маршрут за 5.5 и плоско тяло на заявката, както е показано тук; не е тествано дали генерирането по наследения маршрут се проваля. Копирайте точно актуалното име с тирета, без да приемате, че вариант с точка е негов псевдоним.
Не пренасяйте полетата от най-горно ниво 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 за пускането се посочва приблизителна цена от CNY 0.28 за една редакция на квадратно изображение 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.
Често задавани въпроси
Кой идентификатор на модела и коя крайна точка трябва да се използват за Seedream 5.5?
Използвайте doubao-seedream-5-5 с POST /ai/v1/images/generations и плосък JSON. Не приемайте, че друг правопис или остарял адаптер са еквивалентни.
Включва ли този урок проверени резултати от генериране?
Не. Кодът е базиран на документацията, като са проверени само локалният синтаксис и помощните функции офлайн. Не е изпълнявана заявка за извеждане, не са измервани качеството на изображението или латентността и не е правен тест за таксуване.
Задължително ли е асинхронното изпълнение?
Не; по подразбиране се изчаква синхронно. За изпълнение във фонов режим използвайте булевата стойност async: true. Активирането на функцията за задачи на ниво акаунт е предварително условие за собствените крайни точки за медийни задачи, дори когато се изчаква синхронно.
Означава ли HTTP 200, че изображението е генерирано успешно?
Не. Проверете състоянието на задачата и грешката ѝ. Задачата може да е неуспешна дори когато HTTP заявката е успешна; изтегляйте само след завършване.
Може ли URL адресът за изтегляне на резултата да се използва като следващо референтно изображение за редактиране?
Не приемайте, че може. Изтеглете изображението с ключа, с който е създадено, след което го кодирайте локално като Data URI или предоставете действително публичен URL адрес на изображение.
Какво трябва да се направи след изтичане на времето за изчакване или изгубен отговор?
Не повтаряйте автоматично генерирането. Проверете запазения идентификатор на задачата или я възстановете от списъка с изображения чрез ключа, с който е създадена. Запазете идентификаторите на заявките и се свържете с поддръжката, ако резултатът е неясен.
Гарантира ли изборът на PNG прозрачен изход или сметка от CNY 0.28?
Нито едното. Схемата не предоставя проверена настройка за прозрачност. CNY 0.28 е приблизителен сценарий за редактиране на 2K, споменат в медиите, а не оферта от AIHubMix или фиксирана цена за генериране на изображение по текст и последващо редактиране.
Продължете с поредицата Seedream 5.5
- Преди да промените съществуващ работен процес със Seedream 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; идентификатор на модела и краткотрайни удостоверени изтегляния; за грешки, специфични за маршрута, използвайте документацията за унифицирания API.
- Отразяване на пускането на Seedream 5.5 — Sina Technology; приблизителен сценарий за разходите при редактиране, а не официална тарифа.



