A migração útil do Seedream 5.5 envolve um fluxo de arquivos, não apenas substituir o nome do modelo: gere uma imagem, inspecione a tarefa retornada, salve a imagem e, em seguida, envie esses bytes salvos como referência para uma edição.
Seedream 5.5 no AIHubMix usa atualmente doubao-seedream-5-5 e POST /ai/v1/images/generations. Este tutorial cria uma imagem de produto de uma caneca de cerâmica e, em seguida, solicita uma edição apenas de cor.
Escopo: documentação verificada em 12 de novembro de 2026. O código passou apenas por verificações locais de sintaxe e auxiliares offline; nenhuma solicitação de geração foi executada. Isso não comprova a qualidade do resultado, a fidelidade da edição, a latência nem uma cobrança real.
1. Prepare uma solicitação simples e explícita
Use Python 3.10+ com requests. No Bash, instale a dependência e informe a chave sem incluir seu valor no histórico do shell:
python3 -m pip install requests
read -r -s -p 'AIHubMix API key: ' AIHUBMIX_API_KEY
printf '\n'
export AIHUBMIX_API_KEY
Em código implantado, injete a variável de ambiente por meio do seu gerenciador de segredos. Mantenha a chave fora dos arquivos-fonte, exemplos de solicitação, logs, notebooks e código executado no navegador. Antes de qualquer um dos POSTs, ative o recurso de tarefas da conta, conforme exigido pelo guia de tarefas assíncronas. Esse pré-requisito se aplica aos endpoints de tarefas de mídia nativos /ai/v1, inclusive ao aguardar de forma síncrona; ele é independente da escolha de execução em segundo plano.
Consulte o esquema atual do endpoint do modelo, selecionando a entrada por path, não pela posição no array. As restrições específicas do modelo prevalecem sobre uma lista compartilhada de parâmetros.
| Configuração | Valor usado aqui |
|---|---|
| Modelo | doubao-seedream-5-5 |
| Rota | POST /ai/v1/images/generations |
| Corpo | JSON simples |
| Tamanho | 2048x2048 |
| Quantidade de imagens | n = 1 |
| Formato do arquivo | png |
| Formato da resposta | url |
O esquema exige model e um prompt não vazio, limita n a 1 e lista as saídas png e jpeg. Aceita um URL em image, entrada Base64 ou um objeto {url}; images aceita um array com um máximo publicado de 14 referências. Esse limite não foi testado em tempo de execução aqui. Este exemplo usa uma referência e especifica o tamanho padrão, sem objeto externo input nem extensões extra.
2. Gere, inspecione a tarefa e salve o PNG
A documentação da API unificada de imagens define uma resposta de tarefa com id, object: image, model, status, output e error. Não a interprete como o formato legado data[0].url.
Leia primeiro o fluxo resumido; a configuração completa e o auxiliar de download estão no Apêndice recolhido abaixo. Antes de executar estes exemplos, carregue uma vez o bloco do apêndice na mesma sessão do Python. Ele define settings, api_json e collect sem enviar uma solicitação de imagem. Em seguida, execute os blocos resumidos na ordem. Cada POST é uma ação paga separada; não o execute novamente para corrigir uma resposta ausente ou um download com falha.
Envie a solicitação de imagem uma vez
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)
Inspecione a tarefa e salve o PNG
A omissão de async implica espera síncrona. Uma resposta HTTP 200 ainda pode conter status: failed. O auxiliar salva o ID da tarefa antes de inspecionar o status: somente completed segue para o download; failed, cancelled e estados desconhecidos interrompem o processo. pending e in_progress exigem a inspeção de uma tarefa existente, não outra geração.
collect(task, "mug-blue")
Esta única chamada usa a chave que criou a tarefa para recuperar o resultado concluído, verifica os bytes do PNG e salva mug-blue.png. Ela não tenta criar novamente de forma automática e rejeita hosts de download ou redirecionamentos inesperados antes de encaminhar a chave. A implementação completa está no apêndice; este é o comportamento descrito na documentação, não um resultado de geração verificado.
O guia do modelo informa que os URLs de saída duram cerca de 30 minutos. Baixe o arquivo prontamente usando o mesmo cabeçalho Bearer e armazene os bytes por conta própria. expires_at: null não é uma promessa de retenção permanente. Se b64_json estiver preenchido, decodifique-o em vez de baixar um URL.
3. Edite o arquivo local, não o URL de download protegido
Inspecione você mesmo a imagem salva antes de pagar por uma edição. Um content_url que seu cliente autenticado consegue baixar não é necessariamente um URL público que o provedor de imagens possa acessar. Reenvie o PNG local como 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")
Isso solicita a preservação; não demonstra que ela ocorreu. Analise o resultado antes de outra rodada paga. A solicitação JSON inteira, incluindo a codificação embutida, deve caber em 32 MiB; também se aplicam os limites de mídia específicos do modelo. Um URL de imagem realmente público e acessível ao provedor é outra opção de entrada aceita.
4. Opcional: espera assíncrona e recuperação após interrupções
O pré-requisito da conta mencionado na seção 1 é independente do modo de execução. 403 async_not_enabled significa que o recurso de tarefas precisa ser ativado no console. Apenas a execução em segundo plano é opcional.
Se preferir a geração em segundo plano, crie o mesmo dicionário generation e use as duas linhas abaixo no lugar da linha síncrona task = api_json(...) e da chamada separada collect(...). Escolha o modo antes de enviar; não execute as duas versões:
task = api_json("POST", IMAGES + "/generations", {**generation, "async": True})
collect(task, "mug-blue", poll=True)
O auxiliar consulta GET /ai/v1/images/{id} aproximadamente a cada 15 segundos, até chegar a um estado terminal. Essa é a recomendação de consulta documentada, não um intervalo imposto pelo servidor. Webhooks exigem async: true; a configuração de um receptor está fora do escopo deste tutorial.
Se a coleta for interrompida, se necessário, carregue novamente apenas o bloco compartilhado de configuração/auxiliares do apêndice em uma sessão nova, não um bloco de criação. Se um ID foi salvo, retome sem fazer nenhum 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)
Use o radical correspondente mug-green para recuperar a edição. Se a resposta de criação desapareceu antes de um ID ser salvo, inspecione as tarefas recentes:
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"))
Confira o modelo e o horário de criação; não selecione cegamente a tarefa mais recente. Se necessário, use next_after como cursor after da próxima solicitação. Se não for possível identificar a tarefa com segurança, contate o suporte em vez de enviar outra solicitação. Uma lista é um instantâneo; use os detalhes da tarefa para fazer consultas. output_error em uma linha significa que não foi possível ler o resultado, não que a geração não produziu nada ou que as cobranças foram alteradas.
Continue usando a chave que criou a tarefa. Em particular, o acesso à lista unificada de tarefas, aos detalhes e ao conteúdo é isolado por token: outra chave da mesma conta não pode ler essas tarefas. Uma interrupção local não comprova que houve falha ou que não houve cobrança.
5. Erros atuais e armadilhas de migração
A documentação do adaptador legado do Doubao lista IDs mais antigos em /v1/models/doubao/<id>/predictions, com um envelope input. A lista não inclui a versão 5.5. Use aqui a rota 5.5 disponível para descoberta e o corpo simples; nenhuma falha de geração pelo endpoint legado foi testada. Copie exatamente o ID atual com hífens, sem presumir que uma grafia com pontos seja um alias.
Não reutilize os campos de nível superior quality, background, aspect_ratio ou seed: eles não constam do esquema atual deste modelo. O anúncio de lançamento da ByteDance descreve uma saída RGBA transparente nativa, mas o esquema do gateway não expõe background nem layer_decomposition. Selecionar apenas PNG não é uma receita de transparência verificada.
Estes são erros documentados da API unificada de imagens, não respostas observadas do 5.5. Verifique separadamente o status HTTP e o status da tarefa, e use code para determinar a ação, não a mensagem completa.
| Onde | Código | Próxima ação |
|---|---|---|
| HTTP 400 | schema_violation | Corrija os campos do esquema |
| HTTP 400 | capability_not_supported | Remova as opções não compatíveis |
| HTTP 504 | sync_timeout | Recupere; contate o suporte |
| HTTP 502 | task_status_unavailable | Não envie novamente |
| HTTP 422 | output_blocked | Revise o conteúdo |
| HTTP 403 | async_not_enabled | Ative o recurso de tarefas |
| Tarefa com falha | result_delivery_failed | Investigue o resultado existente |
Para HTTP 502 task_status_unavailable, o guia informa:
Não foi possível confirmar o status da tarefa no provedor do modelo. Não a envie novamente. Entre em contato com o suporte e informe o ID da tarefa ou o ID da solicitação.
Para result_delivery_failed no nível da tarefa, o guia informa:
Não foi possível entregar o resultado gerado. Não envie novamente de forma automática. Entre em contato com o suporte e informe o ID da tarefa.
Um sync_timeout não comprova que a execução nunca ocorreu. Guarde error.tid, use um ID de tarefa somente se ele tiver sido realmente retornado e peça ao suporte que resolva resultados incertos. Se um download recuperável falhar, tente recuperar o arquivo novamente, em vez de gerar outra imagem. 410 artifact_expired é diferente: esse artefato não pode mais ser recuperado. Primeiro, verifique os arquivos salvos; se ainda precisar de uma substituição, autorize deliberadamente uma nova geração paga. Para 429 too_many_downloads, verifique as cópias salvas ou contate o suporte; aguardar não garante que o acesso será restabelecido.
O guia isenta explicitamente a taxa de geração para output_blocked, inclusive quando informado em uma tarefa com falha. Não estenda essa exceção a toda solicitação com falha ou moderada; output_policy_violation segue as regras de cobrança de moderação vigentes.
6. Planeje o orçamento para o fluxo de trabalho, não apenas para uma saída
A reportagem de lançamento da Sina Technology informa aproximadamente CNY 0.28 para uma edição quadrada em 2K, incluindo entrada e saída de imagem, com tokens de texto gratuitos. Trata-se de uma reportagem, não de uma tabela oficial de tarifas verificada nem de uma cotação do AIHubMix.
Um exemplo: duas rodadas pagas de edição de uma imagem existente, cada uma correspondendo a esse cenário arredondado, custam aproximadamente 2 × CNY 0.28 = CNY 0.56. Isso exclui a geração inicial de texto para imagem, imagens de referência adicionais, candidatos extras e novas tentativas. Não se trata de uma cobrança medida.
Para este exemplo de geração seguida de edição, use total = cobrança da geração inicial + cobrança da edição com referência. Não foi possível estabelecer uma tarifa oficial completa do 5.5 com base nas páginas examinadas; por isso, este tutorial não apresenta nem um total fixo nem uma proporção precisa de economia entre a versão antiga e a nova.
Antes de enviar:
- Confirme o ID atual, a rota, o corpo simples e o esquema do modelo.
- Mantenha a chave no ambiente e guarde os IDs das tarefas para recuperação.
- Trate cada POST como uma ação paga separada, nunca como uma nova tentativa de download.
- Confira o status da tarefa e a imagem salva antes de editar.
- Envie novamente os bytes locais com o tipo MIME correto.
- Recupere tarefas cujo resultado é incerto antes de considerar uma nova geração.
Comece com uma imagem e uma edição deliberada; só adicione mais etapas depois de revisar os arquivos.
Apêndice: configuração compartilhada e função auxiliar de download
Ignore este apêndice ao acompanhar o fluxo de trabalho. Antes de executar os exemplos curtos, expanda e carregue este bloco uma vez na mesma sessão do Python. Ele configura a sessão e define funções, sem gerar uma imagem. Para recuperar uma tarefa interrompida em uma sessão nova, recarregue apenas este bloco — não um bloco de criação ou edição.
Expandir a função auxiliar completa — carregue uma vez antes dos exemplos curtos; nenhuma solicitação de imagem
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
O tempo limite de leitura de 600 segundos é uma escolha do cliente, não uma promessa de latência do serviço. A verificação de PNG corresponde ao formato de saída explícito deste tutorial; adapte-a se escolher JPEG.
Perguntas frequentes
Qual ID do modelo e endpoint o Seedream 5.5 deve usar?
Use doubao-seedream-5-5 com POST /ai/v1/images/generations e JSON simples. Não presuma que outra grafia ou um adaptador legado seja equivalente.
Este tutorial inclui resultados de geração testados?
Não. O código se baseia na documentação, com apenas verificações locais de sintaxe e auxiliares offline. Não foi executada nenhuma solicitação de inferência, medição da qualidade da imagem, medição de latência ou teste de cobrança.
O modo assíncrono é obrigatório?
Não; a espera síncrona é o padrão. A execução em segundo plano usa o valor booleano async: true. A ativação do recurso de tarefas no nível da conta é um pré-requisito para os endpoints nativos de tarefas de mídia, mesmo ao aguardar de forma síncrona.
HTTP 200 significa que a imagem foi gerada com sucesso?
Não. Confira o status da tarefa e o erro, se houver. Uma tarefa pode falhar mesmo quando a solicitação HTTP é bem-sucedida; faça o download somente após a conclusão.
Uma URL de download do resultado pode ser usada como referência para a próxima edição?
Não presuma que sim. Faça o download com a chave usada na criação e, em seguida, codifique a imagem local como um Data URI ou forneça uma URL de imagem realmente pública.
O que fazer após um tempo limite ou a perda da resposta?
Não repita a geração automaticamente. Verifique o ID da tarefa salvo ou recupere-o da lista de imagens com a chave usada na criação. Guarde os IDs das solicitações e entre em contato com o suporte quando o resultado for incerto.
Escolher PNG garante saída transparente ou uma cobrança de CNY 0.28?
Nenhuma das duas coisas. O esquema não fornece um controle de transparência verificado. CNY 0.28 é um valor aproximado, divulgado pela imprensa, para um exemplo de edição em 2K — não é uma cotação da AIHubMix nem um preço fixo para texto para imagem mais edição.
Continue lendo: a série Seedream 5.5
- Antes de alterar um fluxo de trabalho existente com 5.0 Pro, avalie a atualização: Seedream 5.5 vs 5.0 Pro: vale a pena atualizar?
- Se o mesmo fluxo de trabalho puder usar outro modelo de imagem, compare as vantagens e desvantagens: Seedream 5.5 vs GPT Image 2.6 Sunburst: qual você deve escolher?
Fontes
- Anúncio de lançamento do Seedream 5.5 — ByteDance Seed; declarações do fornecedor sobre os recursos.
- Esquema atual do endpoint do Seedream 5.5 — AIHubMix; campos da solicitação e restrições específicas do modelo.
- API unificada de geração de imagens — AIHubMix; tarefas, downloads e erros atuais.
- Guia do modelo Seedream 5.5 — AIHubMix; ID do modelo e downloads autenticados de curta duração; consulte o documento da API unificada para erros específicos da rota.
- Cobertura do lançamento do Seedream 5.5 — Sina Technology; cenário de custo aproximado de edição, não uma tarifa oficial.



