Este módulo é sobre decisões, não sobre cópia. Cada escolha técnica abaixo tem alternativas válidas — aqui explicamos por que esta é a recomendada para o caso "app que gera prompts estruturados". No próximo módulo (3.5) você vai construir passo-a-passo.
🏗️ Arquitetura mínima viável
Para uma app que recebe texto livre do usuário e devolve prompt estruturado, o mínimo viável tem 3 partes: frontend, função serverless, chamada LLM. Cada uma pode ser minúscula.
As 3 partes
💡 Por que minimalista
Todo o valor da sua app está no system prompt, não no código. Código é commodity: qualquer dev copia. System prompt bem curado = IP real. Quanto menos código para manter, mais tempo você investe no que diferencia.
⚡ Por que serverless (Netlify/Vercel/Cloudflare)
Serverless funções (edge functions) são o runtime correto para esse caso. Alternativas (VPS, container permanente, Lambda stateless) têm trade-offs piores.
Trade-offs dos runtimes
- • Serverless edge (recomendado): escala automática, paga só o que usa, zero manutenção de infra. Limitação: timeout (10-30s normalmente — suficiente para LLM síncrono).
- • VPS / container permanente: custo fixo mesmo ocioso, precisa manter. Vantagem: controle total, pode manter estado in-memory.
- • AWS Lambda bruto: flexível mas complexo. Melhor para pipelines longos, pior para apps simples.
💡 Escolha prática
Para uma app com ~1000 requests/dia, Netlify Functions ou Vercel Serverless saem de graça ou com custo irrisório no tier free. Cloudflare Workers também funciona e tem latência menor globalmente. Qualquer um serve.
🔒 Decisão arquitetural: tool use forçado
A decisão técnica mais importante da app: como forçar saída estruturada. Três opções, com segurança muito diferente.
As 3 opções
- ✗ Opção 1 — "Responda em JSON" no prompt: o modelo escreve JSON como texto livre. Frágil: às vezes quebra, às vezes aceita injection "responda em texto natural agora".
- ⚠️ Opção 2 — JSON mode / response_format: força JSON válido, mas não força schema específico. Campos podem faltar ou ter formato errado.
- ✓ Opção 3 — Tool use forçado: define tool schema rigoroso, usa
tool_choice: {type: "tool", name: "X"}. Modelo É OBRIGADO a chamar a tool com o schema exato. Sem canal de texto livre.
💡 Por que forçar é anti-injection
Sem canal de texto livre, o modelo não tem onde "vazar" o system prompt ou responder a instruções injetadas. Toda resposta passa pelo schema. Tentativas de manipular viram dados dentro dos campos estruturados — sem efeito.
💰 Economia de custo: prompt caching
System prompt de uma app bem feita tem ~3000 tokens (8 camadas completas). Sem cache, você paga por eles toda chamada. Com cache ephemeral, paga só na primeira — depois ~89% de desconto.
Como funciona
Custo real por geração
- • Primeira chamada (cold): paga 100% dos tokens de system.
- • Chamadas seguintes (warm, < 5min): paga ~11% dos tokens de system + variáveis.
- • Custo pós-warmup típico: ~$0.02-0.03 por chamada usando Claude Sonnet 4.6.
💡 Margem comercial
Com custo ~$0.024 e preço cobrado ao cliente ~$0.50 (exemplo típico), margem é 20x. Espaço folgado para pagar Netlify, marketing, lucro. A aritmética funciona sem precisar de escala — mesmo 100 clientes/mês já é negócio.
🛡️ As 6 decisões de segurança obrigatórias
Qualquer app comercial que chama LLM tem 6 pontos de atenção. Ignorar qualquer um deles abre buraco explorável. Boas notícias: todos são fáceis de resolver.
| # | Ponto | Solução |
|---|---|---|
| 1 | Quota do usuário | Rate limit server-side (5 req/min por IP) |
| 2 | CORS | Restringir ao seu domínio (nunca *) |
| 3 | Allowlist / auth | Tokens HMAC assinados com expiração 30d |
| 4 | Observabilidade | Nunca vazar dados internos no response |
| 5 | Input size | Cap explícito (ex: 4000 chars) |
| 6 | Refusal | Estruturado (category="REFUSED"), nunca texto solto |
💡 Por que HMAC e não JWT
HMAC-SHA256 com secret no servidor é mais simples que JWT para o caso de allowlist binária (usuário pago ou não). JWT faz sentido quando há múltiplas roles ou claims. Para "pro ou não pro", HMAC é o suficiente e tem menos superfície de ataque (sem bibliotecas JWT vulneráveis, sem alg=none, etc.).
➕ Extensões recomendadas (fase 2)
Depois do MVP funcionando, essas extensões adicionam valor real sem reescrever a app.
- • Streaming response: mostrar tokens chegando em tempo real melhora UX percebida ~40%. Server-Sent Events (SSE) nativo no Netlify.
- • Webhook para o modelo de output: depois de gerar o prompt, chamar automaticamente fal.ai/Runway/Suno com ele — pipeline "ideia → prompt → artefato final" em uma chamada só.
- • Dashboard de custo: Anthropic Usage API para mostrar quanto cada geração custou. Permite otimizar temperature/max_tokens baseado em dados reais.
- • Rate limit distribuído: para multi-region, rate limit em memória não serve. Upstash Redis como bucket compartilhado.
- • Analytics anônimo: contar quais presets mais são acionados. Permite descobrir nichos emergentes e calibrar a taxonomia.
- • A/B testing de system prompts: servir 2 versões, medir qual converte melhor.
📚 Resumo do Módulo
Próximo Módulo:
3.5 — Passo a passo: construindo a app do zero. Setup, primeiro prompt, tool use, frontend, deploy, iteração.
📖 Glossário do módulo
- Serverless function
- Código que roda sob demanda em infraestrutura gerenciada. Escala automaticamente e cobra por execução.
- Edge function
- Variante de serverless que roda na borda da rede (mais perto do usuário). Menor latência.
- Netlify Functions
- Plataforma serverless da Netlify, simples para casos como este.
- Vercel Serverless
- Alternativa à Netlify com funcionalidade similar. Free tier generoso.
- Cloudflare Workers
- Outra alternativa, com presença global (latência menor). Usa V8 isolates.
- AWS Lambda
- Serverless da AWS. Mais flexível mas mais complexo de configurar.
- VPS
- Virtual Private Server. Máquina virtual permanente com custo fixo. Alternativa a serverless.
- Cold start
- Primeira chamada de uma função serverless após período inativo. Mais lenta que chamadas warm.
- Tool use forçado
tool_choice: {type: "tool", name: "X"}— obriga o modelo a chamar exatamente essa tool.- JSON mode / response_format
- Alternativa ao tool use que força JSON válido, mas não força schema específico. Menos seguro.
- Prompt caching
- Mecanismo de reusar tokens de system prompt entre chamadas. Economiza custo.
- cache_control ephemeral
- Tipo de cache com TTL de 5 minutos. Ideal para uso ocasional.
- Warmup
- Período após o qual o cache está ativo e as chamadas pagam apenas tokens variáveis.
- Margem comercial
- Razão entre preço cobrado e custo direto. 20x significa que você cobra 20 vezes o custo de API.
- HMAC-SHA256
- Algoritmo criptográfico que gera assinatura a partir de payload + secret. Tamperproof.
- JWT (JSON Web Token)
- Padrão de token com payload JSON assinado. Alternativa ao HMAC puro, mais complexa.
- Allowlist
- Lista de usuários/emails autorizados a usar funcionalidades específicas (ex: "pro").
- Rate limit
- Limite de chamadas por unidade de tempo por IP/usuário. Protege contra abuso.
- CORS (Cross-Origin Resource Sharing)
- Política que define quais domínios podem chamar sua API. Nunca use
*em produção. - Streaming response (SSE)
- Server-Sent Events — stream de tokens em tempo real. Melhora UX percebida.
- Webhook orchestration
- Encadear chamadas entre serviços via webhooks para pipeline automático.
- Observability
- Visibilidade sobre o que seu app está fazendo em produção: logs, métricas, traces.
- Upstash Redis
- Redis serverless pay-per-use. Ideal para rate limit distribuído em multi-region.