IA pra e-commerce: 7000 descrições SEO + imagens de produto em 1 madrugada (custo R$ 87)
Caso real de SaaS e-commerce brasileiro: gpt-4o-mini gerou descrições otimizadas + Flux Schnell criou imagens hero. Setup técnico, prompts em produção e estratégia de SEO.
Caso real (sob NDA): SaaS de e-commerce brasileiro com 1 catálogo migrado de fornecedor — 7000 SKUs sem descrição própria, sem imagem hero. Antes: copywriter pagaria R$ 8/SKU = R$ 56.000. Depois: bot Tokia gerou tudo em 1 madrugada por R$ 87. Quote do CEO: "7000 SKUs descritos. Custou R$ 87. Levei mais tempo pra revisar do que pra gerar."
Esse post mostra a stack completa, prompts em produção, e os 3 gotchas que vão queimar dinheiro se você não souber.
Por que e-commerce é caso #1 de IA em volume
3 problemas crônicos:
- Catálogo enorme: 5000-50000 SKUs em qualquer marketplace sério
- Descrição matter pra SEO: Google não ranking produto sem texto próprio, e copy gringa traduzida google translate = bounce 80%
- Imagem hero: fornecedor manda PNG fundo branco crap quality. Loja precisa hero com lifestyle/contexto
Solução típica anterior: terceiriza copywriter (R$ 8-15/SKU) e fotógrafo (R$ 30-100/foto). Pra 7000 SKUs = R$ 56.000-805.000. Inviável pra SaaS pequeno.
Com IA: 7000 descrições em ~40min + 7000 hero images em 8h. Custo total R$ 87. Reduce 99.8%.
Stack técnica completa
Banco SKUs (Postgres / MySQL / planilha CSV)
↓
Worker Node.js (BullMQ + 1000 workers concorrentes)
↓
Tokia API
├─→ gpt-4o-mini → descrição SEO 200 palavras
└─→ flux-schnell → imagem 1024×1024
↓
Upload imagem pra S3/R2
↓
UPDATE SKU com descricao + imagem_url
Código (Node.js + BullMQ + Tokia)
1. Worker que gera descrição
// workers/descricao-worker.ts
import { Worker, Queue } from "bullmq";
import OpenAI from "openai";
import { db } from "../lib/db.js";
const tokia = new OpenAI({
baseURL: "https://api.usetokia.com/v1",
apiKey: process.env.TOKIA_API_KEY,
});
const descricaoWorker = new Worker(
"descricao-sku",
async (job) => {
const { skuId, titulo, categoria, atributos } = job.data;
const response = await tokia.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: SYSTEM_PROMPT_DESCRICAO },
{
role: "user",
content: JSON.stringify({ titulo, categoria, atributos }),
},
],
max_tokens: 300,
});
const descricao = response.choices[0]!.message.content!;
await db.sku.update({
where: { id: skuId },
data: { descricao, descricao_gerada_em: new Date() },
});
},
{ connection: redis, concurrency: 50 },
);
2. System prompt que ranqueia em Google
const SYSTEM_PROMPT_DESCRICAO = `Você é copywriter especializado em SEO
pra e-commerce brasileiro. Recebe JSON com {titulo, categoria, atributos}
e gera descrição de produto em PT-BR.
REGRAS:
1. Tamanho: 150-220 palavras
2. Estrutura:
- Parágrafo 1 (3 frases): hook + benefício principal + pra quem é
- Parágrafo 2 (4-5 frases): especificações técnicas em prosa
- Parágrafo 3 (3 frases): contexto de uso + call-to-action sutil
3. SEO:
- Use o título exato 1x no primeiro parágrafo
- Inclui 3-5 palavras-chave long-tail derivadas dos atributos
- Nunca usa "comprar agora" / "melhor preço" (spam Google)
4. Tom: profissional, neutro, foca no produto (não em superlativos)
5. Brasileiro: usa "você" (não "tu"), preço em R$, medidas em cm/kg
6. PROIBIDO inventar atributo não presente no JSON. Se faltar info
importante (ex: voltagem em eletrônico), escreve "consultar
especificações técnicas".
EXEMPLOS DE TONS:
❌ Errado (genérico, salesy):
"O melhor smartphone do mercado! Não perca essa oferta imperdível!
Compre agora e tenha o celular dos seus sonhos!"
✅ Certo (informativo, SEO):
"O Smartphone X Modelo Y combina câmera de 50MP com bateria de 5000mAh
em um design fino de 7.5mm. Indicado pra quem busca celular intermediário
com câmera competente sem pagar preço de topo de linha. A tela AMOLED
6.4 polegadas oferece resolução Full HD+ e taxa de atualização de 90Hz,
adequada pra uso diário e jogos casuais. Conectividade 5G, leitor de
digital lateral, e processador octa-core completam a ficha técnica.
Disponível nas cores preto, azul e branco, é opção pra usuário que vai
fazer upgrade do seu Android atual em 2026."
`;
3. Worker que gera imagem hero
const imagemWorker = new Worker(
"imagem-sku",
async (job) => {
const { skuId, titulo, categoria, cor } = job.data;
// Flux Schnell — Fal.ai via Tokia
const response = await tokia.images.generate({
model: "flux-schnell",
prompt: buildPromptImagem(titulo, categoria, cor),
size: "1024x1024",
n: 1,
});
const imageUrl = response.data[0]!.url!;
// Download + upload pra R2/S3
const buf = await fetch(imageUrl).then((r) => r.arrayBuffer());
const key = `produtos/${skuId}.jpg`;
await s3.putObject({ Bucket: "loja-cdn", Key: key, Body: buf });
await db.sku.update({
where: { id: skuId },
data: { imagem_hero_url: `https://cdn.loja.com/${key}` },
});
},
{ connection: redis, concurrency: 10 }, // imagens são pesadas
);
function buildPromptImagem(titulo: string, categoria: string, cor: string) {
return `Product photography of ${titulo}, color ${cor}, on white seamless background, professional studio lighting, soft shadow, hero shot, high detail, commercial product image, 4K quality, photorealistic, no text, no logo, centered composition`;
}
4. Enqueue script (rodar 1x pra catálogo inteiro)
// scripts/enqueue-all.ts
import { Queue } from "bullmq";
import { db } from "../lib/db.js";
const queueDescricao = new Queue("descricao-sku", { connection: redis });
const queueImagem = new Queue("imagem-sku", { connection: redis });
const skus = await db.sku.findMany({
where: { descricao: null, ativo: true },
take: 10000,
});
console.log(`Enqueuing ${skus.length} SKUs...`);
await Promise.all([
queueDescricao.addBulk(
skus.map((sku) => ({
name: "descricao",
data: {
skuId: sku.id,
titulo: sku.titulo,
categoria: sku.categoria,
atributos: sku.atributos_json,
},
})),
),
queueImagem.addBulk(
skus.map((sku) => ({
name: "imagem",
data: {
skuId: sku.id,
titulo: sku.titulo,
categoria: sku.categoria,
cor: sku.cor_principal,
},
})),
),
]);
console.log("Done. Workers vão processar em background.");
Custos reais (7000 SKUs)
| Item | Cálculo | Valor | |---|---|---| | Descrições gpt-4o-mini | 7000 × 1200 tokens × $0.15/1M × 5.0 BRL × 2x markup | R$ 25 | | Imagens Flux Schnell | 7000 × $0.003/img × 5.0 BRL × 2.5x markup | R$ 26 | | Cloudflare R2 storage | 7000 × ~150KB = ~1GB armazenado | R$ 1 | | BullMQ + Redis local | VPS Hetzner CX22 | R$ 22/mês (rateado horas: R$ 0.50 pra 8h) | | Worker Node.js | Mesma VPS | R$ 0 | | Total geração | | ~R$ 87 one-shot |
Compare ao orçamento de copywriter humano:
- Copywriter freelancer BR: R$ 8/descrição = R$ 56.000
- Fotógrafo produto: R$ 30/foto = R$ 210.000
- Total humano: R$ 266.000 + 2-3 meses
- IA: R$ 87 + 8 horas
Os 3 gotchas que vão queimar dinheiro
1. Hallucination em atributos técnicos
Sintoma: produto "Mouse Logitech M170" e bot escreve "tem 6 botões DPI ajustável" (na verdade só 2 botões, sem DPI ajustável).
Fix: passa JSON ESTRUTURADO com atributos reais. NUNCA deixa bot inferir specs:
// ❌ Errado
const prompt = `Crie descrição pra Mouse Logitech M170`;
// ✅ Certo
const prompt = JSON.stringify({
titulo: "Mouse Logitech M170",
atributos: {
botoes: 2,
dpi: 1000,
conectividade: "USB sem fio",
cores: ["preto", "azul"],
bateria: "1 pilha AA",
},
});
2. Imagem com texto/logo (Flux NÃO sabe ler)
Sintoma: bot gera imagem com texto rabiscado tipo "Coca-Cwa", logo distorcido. Google penaliza imagem com texto fake.
Fix: prompt explícito "no text, no logo, no watermark". Pós-processa
com image-text-detector pra rejeitar imagens com texto:
import { TextDetector } from "@google-cloud/vision";
async function imagemTemTexto(imageUrl: string): Promise<boolean> {
const [result] = await visionClient.textDetection(imageUrl);
return (result.textAnnotations?.length ?? 0) > 0;
}
// Worker re-tenta até 3x se imagem tiver texto
let attempts = 0;
while (attempts < 3) {
const imageUrl = await gerarImagem(prompt);
if (!(await imagemTemTexto(imageUrl))) {
return imageUrl;
}
attempts++;
}
3. Rate limit upstream em batch grande
Sintoma: BullMQ enfileira 10000 jobs concorrentes, OpenRouter retorna 429 rate limit, todos os jobs falham.
Fix: configura concurrency baixo no worker (50 pra LLM, 10 pra
imagem) + retry com backoff:
const descricaoWorker = new Worker(
"descricao-sku",
async (job) => { /* ... */ },
{
connection: redis,
concurrency: 50,
settings: {
backoffStrategy: (attempts) => Math.min(60000, 1000 * 2 ** attempts),
},
},
);
Estratégia SEO pós-geração
Gerar descrição não basta. Pra ranquear:
- Indexar no Google: submeter sitemap.xml atualizado no GSC
- Schema.org Product em JSON-LD pra rich results (preço, disponibilidade)
- Alt text das imagens geradas (use a
descriçãomesmo) - URL slug otimizado:
/produto/mouse-logitech-m170-preto(não/produto?id=12345) - Open Graph + Twitter Card com hero image (compartilhamento social)
Próximos passos
- Cria conta Tokia + R$ 10 PIX
- Cria API key restrita a
gpt-4o-mini+flux-schnellem /dashboard/keys - Define budget cap R$ 200 nessa key (proteção contra bug)
- Roda enqueue script piloto com 50 SKUs primeiro
- Revisa 10 outputs random antes de aprovar pro catálogo
- Escala pro catálogo inteiro
ROI realista: 7000 SKUs com descrição/imagem boa = aumento ~40-60% de sessões orgânicas em 90 dias (long-tail keywords). Pra loja faturando R$ 100k/mês, isso são +R$ 40-60k de revenue mensal. Pagou R$ 87 vs revenue +R$ 40k = ROI 460x.
Posts relacionados:
Quer testar Tokia com R$ 10 via PIX?
Criar conta grátis →