Geração de imagens por template com Genviso e BetterToken

Como separar a exploração visual da execução no backend e transformar um bom prompt em um template de produção versionado.

Uma boa imagem ainda não é um processo de produção. Para uma única peça, é possível reescrever o prompt, examinar algumas respostas e escolher uma manualmente. Com centenas de SKUs, esse hábito vira uma sequência cara de testes. Cada mudança de luz, ângulo ou material dispara outra requisição, enquanto o motivo do acerto continua apenas na cabeça de quem escreveu o prompt.

Divida o trabalho em dois ciclos. Primeiro, a equipe testa a direção visual e registra regras que podem ser repetidas. Depois, o backend insere dados do negócio no template aprovado, envia requisições, salva resultados e trata erros. A exploração criativa fica fora da fila de produção, e um ajuste de composição deixa de exigir alterações no código do servidor.

Por que depurar prompts no código foge do controle

Há variáveis demais conectadas

O modelo reage ao objeto, ambiente, iluminação, posição da câmera, material, profundidade de campo e paleta ao mesmo tempo. Em uma foto de um frasco de sérum, o resultado muda bastante entre:

  • vista frontal e tomada superior de 45 graus;
  • luz direcional dura e luz difusa suave;
  • vidro com reflexos marcados e acabamento fosco;
  • fundo de travertino, metal ou papel liso;
  • aparência macro de 85 mm e composição grande-angular.

Quando vários fatores mudam juntos, ninguém sabe qual frase melhorou a imagem. Quando eles mudam um por vez, o número de requisições cresce rapidamente. Um backend usando BetterToken pode executar o template pela Image API, mas iniciar a fila cedo demais apenas reproduz uma hipótese visual ainda não validada.

Cada tarefa tem uma gramática visual própria

Uma página de produto precisa de silhueta legível, reflexos controlados e espaço para layout. Uma ilustração 3D tem outras exigências de forma e material. Um pôster para redes sociais depende de hierarquia, contraste e áreas seguras. Um prompt universal costuma acumular adjetivos contraditórios.

É mais prático manter famílias de templates:

skincare_product luxury_watch food_photography 3d_illustration social_poster

Cada família define os próprios campos obrigatórios e critérios de aceitação. O programa escolhe o template pela categoria e preenche os dados do produto ou da campanha.

Exploração e produção precisam de regras diferentes

A exploração aceita muitas variações e comparação subjetiva. A produção precisa de contrato previsível, versão do template, tentativas limitadas, identificador de tarefa e resultado de aceitação explícito.

editar o prompt no código → enviar uma requisição de API → abrir a imagem → editar o código novamente → enviar outra requisição

Esse ciclo não tem um ponto em que a decisão visual é aprovada. Assim, qualquer discussão de design alcança o backend e a fila de tarefas.

Arquitetura: da hipótese visual ao arquivo no CMS

Na exploração visual, a equipe usa o Genviso para comparar opções na galeria visual de prompts, testar composição, luz e estilo e preservar a estrutura que funciona. Na execução do servidor, a aplicação usa o BetterToken com a Base URL compatível com OpenAI e a API Key do próprio usuário, preenche os dados, chama um modelo disponível e registra o resultado. A entrega entre as etapas é uma versão do Prompt Template, não uma imagem escolhida ou instruções verbais.

Para testar essa fronteira antes de conectar uma fila, crie sua própria API Key, execute uma requisição de controle com o template aprovado e confira imediatamente modelo, status e cobrança real no Dashboard. Assim, a rota do servidor é validada sem transformar a exploração visual em requisições de produção.

exploração visual ↓ validação do Prompt Template ↓ variáveis e restrições definidas ↓ dados de PIM / CMS / SKU ↓ requisição de Image API no backend ↓ arquivo, status e metadados ↓ aceitação visual

Cada transição precisa gerar um artefato verificável:

EtapaResultadoCondição de saída
Exploração visualVariações aprovadas e rejeitadasOs parâmetros relevantes são conhecidos
ValidaçãoPrompt com variáveis nomeadasFunciona em produtos representativos
IntegraçãoFunção de renderização e esquemaCampos obrigatórios são validados antes da API
TesteUm arquivo salvo e um registroO arquivo abre e modelo/status estão corretos
ProduçãoTarefa com template_id, versão e job_idTentativas são limitadas e o resultado aponta para o SKU

Etapa 1: transforme a decisão visual em template

Uma estrutura inicial para fotografia de cosméticos pode ser:

Commercial studio product photography of {subject}. Environment: {environment} Visual style: {visual_style} Lighting: {lighting} Composition: {composition} Color palette: {color_palette} Crisp reflections, premium material texture, high-end commercial editorial photography.

A ordem e as dimensões visuais permanecem estáveis. Os valores de subject, environment, visual_style, lighting, composition e color_palette variam de forma independente.

Antes de entregar o template ao desenvolvimento, registre quatro pontos:

  1. Campos obrigatórios. Sem subject ou composition, a requisição não deve ser enviada.
  2. Valores permitidos. Se existem três ângulos aprovados, use um enum em vez de texto livre do CMS.
  3. Combinações proibidas. Uma embalagem transparente sobre espelho pode exigir outro template.
  4. Critérios de aceitação. A silhueta é legível, o logotipo não está deformado, o produto não foi cortado e o fundo serve ao layout final.

Mantenha o prompt ao lado de um contrato legível pela aplicação:

{ "template_id": "skincare_product_v3", "required_variables": [ "subject", "environment", "visual_style", "lighting", "composition", "color_palette" ], "output_size": "1024x1024" }

A versão em template_id permite reprodução. Se iluminação ou composição mudarem, as novas tarefas recebem outra versão; os arquivos já criados continuam ligados à anterior.

Etapa 2: conecte o template ao backend

Para o primeiro teste, você precisa do SDK oficial openai para Python, da sua própria BetterToken API Key e de um Model ID atual consultado na documentação da Image API. Guarde a chave e o modelo no ambiente:

python -m pip install openai export BETTERTOKEN_API_KEY="your_api_key_here" export BETTERTOKEN_IMAGE_MODEL="current_image_model_id"

Não coloque uma chave real no repositório, no prompt, em captura de tela ou logs. Em produção, use um gerenciador de segredos e chaves separadas para aplicações ou ambientes diferentes.

O exemplo renderiza o template, envia uma requisição e salva um PNG a partir de b64_json:

import base64 import os from pathlib import Path from typing import Mapping from openai import OpenAI client = OpenAI( base_url="https://www.bettertoken.ai/v1", api_key=os.environ["BETTERTOKEN_API_KEY"], ) def render_product_prompt(variables: Mapping[str, str]) -> str: return f""" Commercial studio product photography of {variables['subject']}. Environment: {variables['environment']} Visual style: {variables['visual_style']} Lighting: {variables['lighting']} Composition: {variables['composition']} Color palette: {variables['color_palette']} Crisp reflections, premium material texture, high-end commercial editorial photography. """.strip() product = { "subject": "frosted amber glass serum bottle with a minimalist gold dropper", "environment": "organic travertine pedestal surrounded by subtle water ripples", "visual_style": "high-end botanical skincare editorial", "lighting": "warm directional morning rim light with soft diffused fill", "composition": "centered 85mm macro product photography with shallow depth of field", "color_palette": "earthy amber, warm beige and subtle gold", } response = client.images.generate( model=os.environ["BETTERTOKEN_IMAGE_MODEL"], prompt=render_product_prompt(product), size="1024x1024", n=1, ) image_base64 = response.data[0].b64_json if not image_base64: raise RuntimeError("Image API response does not contain b64_json") output_path = Path("serum-product.png") output_path.write_bytes(base64.b64decode(image_base64)) print(f"Saved: {output_path}")

A chamada client.images.generate(...) e a decodificação de b64_json seguem o contrato atual do SDK. O modelo vem de BETTERTOKEN_IMAGE_MODEL, então ele pode mudar sem reescrever o template ou a lógica do negócio.

Ciclo mínimo de uma tarefa em lote

O bloco abaixo é pseudocódigo explícito de integração. save_job, generate_image e ApiError representam adaptadores do armazenamento e do cliente API; não são métodos extras do SDK.

MAX_ATTEMPTS = 3 RETRYABLE_STATUS = {429, 500, 502, 503, 504} for sku in sku_rows: variables = validate_variables(sku) # antes da chamada à API prompt = render_product_prompt(variables) job_id = uuid4().hex prompt_hash = sha256(prompt.encode()).hexdigest() save_job(job_id=job_id, sku_id=sku["id"], template_id="skincare_product_v3", prompt_hash=prompt_hash, status="pending") for attempt in range(1, MAX_ATTEMPTS + 1): save_job(job_id=job_id, status="running", attempt=attempt) try: result = generate_image(prompt) except ApiError as error: if error.status_code in {400, 401}: save_job(job_id=job_id, status="failed", error_code=error.status_code) break if error.status_code not in RETRYABLE_STATUS or attempt == MAX_ATTEMPTS: save_job(job_id=job_id, status="failed", error_code=error.status_code) break sleep(min(2 ** attempt, 8)) continue except TimeoutError: save_job(job_id=job_id, status="unknown", error_code="timeout") break # conferir Dashboard e armazenamento antes de reenviar if not result.b64_json: save_job(job_id=job_id, status="failed", error_code="empty_output") break output_path = persist_png(job_id, result.b64_json) save_job(job_id=job_id, status="succeeded", output_path=output_path, model=result.model, attempt=attempt) break

O job_id local relaciona SKU, template e arquivo, mas não torna a requisição remota idempotente. Depois de um timeout, mantenha unknown, procure pelo horário no Dashboard e verifique o armazenamento antes de decidir por um único reenvio.

Ordem de diagnóstico

SintomaVerificar primeiroCorreçãoNova verificação
400Variáveis obrigatórias, Model ID atual e size aceitoCorrigir dados ou parâmetro; não repetir automaticamenteRodar um SKU de controle e abrir o PNG
401Variável da chave carregada, propriedade da chave e protocoloSubstituir ou recriar a chave sem registrá-laEnviar a requisição mínima e localizar o status no Dashboard
429Concorrência e ritmo das tarefasParar novas tarefas, reduzir concorrência e usar backoff limitadoLiberar uma requisição e retomar a carga gradualmente
5xxHorário e número de tentativasRepetir apenas até MAX_ATTEMPTS; guardar horário e statusTestar uma requisição após pausa sem mudar o template
TimeoutDashboard e armazenamentoManter unknown; não assumir falhaSem registro nem arquivo, permitir um reenvio com o mesmo job_id local
b64_json vazio ou falha de decodificaçãoFormato de resposta, modelo e parâmetros atuaisGuardar erro sem dados da chave e corrigir leitura ou configuraçãoRepetir um SKU e confirmar que o PNG abre

O que adicionar antes da geração em lote

Valide os dados antes da requisição

Um material vazio, marcação inesperada em product_name ou texto livre no lugar de uma paleta aprovada altera o prompt. Verifique campos obrigatórios, comprimentos e valores permitidos. Salve o hash final do prompt, template_id e identificador do SKU junto à tarefa.

Limite as tentativas

Uma nova tentativa após timeout pode criar outra imagem mesmo que a aplicação não tenha recebido a primeira resposta. Defina um número finito, aplique espera progressiva e atribua um job_id. Não repita erros 400, 401 ou de configuração indefinidamente; corrija dados, chave ou configuração primeiro.

Separe aceitação técnica e visual

HTTP 200 e um PNG válido confirmam o sucesso técnico. Composição, deformação do produto e adequação à marca são verificações separadas. A tarefa automática salva o arquivo e os metadados; a etapa seguinte aplica os critérios visuais.

Confira a requisição com o uso

Após a geração de controle, localize a requisição no Dashboard pelo horário. Confira modelo, status e cobrança; os campos disponíveis mostram tokens de entrada, saída e cache. O Dashboard armazena metadados de uso e gasto, não o prompt nem a resposta completos. Use a página atual de modelos e preços para orçamento e o registro da requisição para o gasto real do teste.

Exemplo de fluxo para um catálogo

PIM / base de SKU ↓ categoria → template_id ↓ nome / material / cor / fundo ↓ validação de campos ↓ renderização do Prompt Template ↓ tarefa com job_id ↓ Image API ↓ armazenamento de objetos ↓ aceitação visual ↓ CMS / biblioteca de mídia

O prompt vira um objeto de produção versionado. Você pode identificar qual template criou cada arquivo, comparar rejeições por versão e reverter uma mudança sem refazer toda a integração.

Checklist antes de ativar a fila

  • O template foi testado com produtos típicos e casos extremos.
  • template_id, variáveis obrigatórias e critérios de aceitação estão definidos.
  • A API Key fica fora do código e dos logs.
  • O Model ID vem do ambiente ou da configuração.
  • Uma requisição de teste cria um arquivo válido no tamanho esperado.
  • Erros 400/401 exigem correção antes de outra tentativa.
  • Erros 429/5xx têm uma política de repetição limitada.
  • Cada tarefa se liga ao SKU, job_id, versão e local de armazenamento.
  • Verificação técnica e aceitação visual são etapas diferentes.
  • Modelo, status e gasto do teste foram conferidos no Dashboard.

Como a divisão de responsabilidades melhora a colaboração

O Genviso cuida do ciclo interativo: encontrar a direção visual, comparar prompts e validar o template antes da entrega aos desenvolvedores. O BetterToken cuida do ciclo de servidor: API Key, conexão compatível com OpenAI, chamada ao modelo disponível e registro de uso. As equipes compartilham um contrato: Prompt Template, variáveis, versão e critérios de aceitação.

Para levar o template aprovado a um backend funcional e medir o gasto com um SKU representativo, crie sua própria API Key, execute a menor requisição da referência da Image API e confira modelo, status e cobrança no Dashboard antes de conectar a fila.

Quer otimizar seu fluxo de trabalho com LLMs?

Conecte modelos por uma única API, gerencie chaves e controle os gastos com IA.