O problema real
Seu prompt funciona no ChatGPT. Você copia para Python. Funciona também. Aí em produção com 10 mil requisições, o LLM às vezes retorna JSON quebrado, às vezes ignora instruções, às vezes acha que é um poeta. Você tenta vários prompts no terminal e um deles funciona. Mas qual? Como você versionaria? E quando o modelo muda de versão no mês que vem, você quer testar tudo de novo?
A engenharia de prompt não é magia: é estrutura. Um prompt de produção tem papel definido, contexto claro, tarefa precisa, formato declarado, exemplos (few-shot) e restrições explícitas. Sem isso, é sorte.
Anatomia de um prompt de produção
Um prompt eficaz em produção tem sete componentes:
1. Papel (ou system prompt)
Quem é o LLM? Isso define o tom e o viés.
Você é um assistente de suporte técnico especializado em AWS,
com 10 anos de experiência. Você é conciso, objetivo e cita
sempre a documentação oficial.
Não:
Você é um assistente.
2. Contexto
O que o LLM precisa saber para fazer o trabalho?
Contexto: Você está respondendo a clientes de uma SaaS de
hospedagem de IA que usa sa-east-1 (São Paulo). O SLA garante
99,9% uptime. A latência máxima aceitável é 200ms.
3. Tarefa
O que você quer que ele faça? Seja específico.
Dado o relato de um cliente sobre um problema de desempenho,
classifique entre: CRÍTICO (sistema parado), ALTO (degradação > 50%),
MÉDIO (degradação 10-50%), BAIXO (< 10%), FALSO_ALARME (não é bug).
Não:
Ajude o cliente.
4. Formato de saída
Como ele deve responder? Use JSON, Markdown, ou lista.
Retorne um JSON:
{
"severidade": "CRÍTICO|ALTO|MÉDIO|BAIXO|FALSO_ALARME",
"reasoning": "explicação em 1-2 frases",
"proximos_passos": ["ação 1", "ação 2"]
}
5. Restrições
O que ele NOT deve fazer?
NÃO invente soluções que não existem. NÃO prometa SLA
fora do contrato. NÃO sugira trocar de provider.
6. Exemplos (few-shot)
Mostre exemplos de entrada e saída esperada. Dois a três são o máximo; mais que isso polui o contexto.
EXEMPLO 1:
Entrada: "O servidor tá lento, leva 5 segundos pra carregar"
Saída:
{
"severidade": "ALTO",
"reasoning": "Latência > 200ms em sa-east-1",
"proximos_passos": ["Verificar CPU da instância", "Revisar logs de erro"]
}
EXEMPLO 2:
Entrada: "Às vezes aparece um aviso estranho"
Saída:
{
"severidade": "FALSO_ALARME",
"reasoning": "Aviso não impacta funcionamento",
"proximos_passos": ["Ignorar"]
}
7. Instruções de fallback
O que fazer se ele não souber? Fale.
Se não tiver certeza, diga "não tenho dados suficientes"
em vez de adivinhar.
Mão na massa: estruturando um prompt
Vamos montar um prompt completo para classificação de tickets:
from openai import OpenAI
import json
def create_ticket_classifier_prompt():
"""Cria o prompt estruturado para classificação de tickets."""
system_prompt = """Você é um especialista em suporte técnico com 10 anos de experiência.
Seu trabalho é classificar tickets de clientes por severidade real, não pelo que o cliente acha.
CONTEXTO:
- SaaS de hospedagem de IA em sa-east-1 (São Paulo)
- SLA: 99,9% uptime (máx. 43 min/mês de downtime)
- Latência aceitável: < 200ms
- Horário de pico: 9-12h e 18-20h
TAREFA:
Classifique cada ticket por severidade. Considere:
1. Impacto no negócio do cliente (sistema parado vs. lento)
2. Número de usuários afetados
3. Se há workaround
FORMATO DE SAÍDA:
Retorne um JSON válido:
{
"severidade": "<CRÍTICO|ALTO|MÉDIO|BAIXO|INFORMACAO>",
"justificativa": "string com 1-2 frases",
"tempo_resposta_estimado": "string (ex: 'imediato', '1 hora', '24 horas')",
"checklist_tecnico": ["item1", "item2"],
"requer_escalacao": true|false
}
RESTRIÇÕES:
- NÃO classifique como CRÍTICO baseado apenas na emoção do cliente
- NÃO prometa tempo de resolução se não tiver certeza
- NÃO sugira que o cliente mude de provider
- Se não souber, diga "Preciso de mais contexto sobre..."
EXEMPLOS:
EXEMPLO 1 - CRÍTICO:
Ticket: "Nossas 1.200 requisições/segundo estão em fila. Sistema offline para os usuários."
Saída:
{
"severidade": "CRÍTICO",
"justificativa": "Sistema parado, 1.200 usuários afetados",
"tempo_resposta_estimado": "imediato",
"checklist_tecnico": ["Verificar CPU do cluster", "Revisar erros de OOM", "Resetar load balancer"],
"requer_escalacao": true
}
EXEMPLO 2 - MÉDIO:
Ticket: "Algumas requisições levam 600ms. Normalmente são 150ms."
Saída:
{
"severidade": "MÉDIO",
"justificativa": "Degradação de 4x, mas sistema funciona",
"tempo_resposta_estimado": "2 horas",
"checklist_tecnico": ["Revisar query time do banco", "Verificar cache", "Analisar logs de erro"],
"requer_escalacao": false
}
EXEMPLO 3 - INFORMACAO:
Ticket: "Como ativo autoscaling?"
Saída:
{
"severidade": "INFORMACAO",
"justificativa": "Dúvida operacional, não é incidente",
"tempo_resposta_estimado": "24 horas",
"checklist_tecnico": ["Enviar link da documentação", "Oferecer onboarding"],
"requer_escalacao": false
}
"""
return system_prompt
def classify_ticket(ticket_text: str) -> dict:
"""Classifica um ticket usando o prompt estruturado."""
client = OpenAI()
system_prompt = create_ticket_classifier_prompt()
response = client.chat.completions.create(
model="gpt-4o-mini", # Use o modelo mais barato que atenda
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"Classifique este ticket:\n\n{ticket_text}"}
],
temperature=0.3, # Baixo para ser mais consistente
response_format={"type": "json_object"} # Força JSON válido
)
# Parse do response
classification = json.loads(response.choices[0].message.content)
return classification
# Teste
ticket = """
A gente tem um ambiente que de repente começou a ficar muitooooo lento.
Antes era rápido, agora tá horrível. Perdemos uns 5 clientes já!
Vocês precisam resolver AGORA!!!
"""
result = classify_ticket(ticket)
print(json.dumps(result, indent=2, ensure_ascii=False))
Testando prompts
Um prompt é bom só se passar nos seus testes. Crie um dataset de casos reais:
test_cases = [
{
"input": "Sistema parado para 500 usuários",
"expected_severity": "CRÍTICO"
},
{
"input": "Página carrega em 350ms em vez de 150ms",
"expected_severity": "MÉDIO"
},
{
"input": "Como faço backup?",
"expected_severity": "INFORMACAO"
}
]
def evaluate_prompt(test_cases: list) -> float:
"""Avalia acurácia do prompt em um dataset."""
correct = 0
for case in test_cases:
result = classify_ticket(case["input"])
if result["severidade"] == case["expected_severity"]:
correct += 1
else:
print(f"FALHA: esperava {case['expected_severity']}, "
f"got {result['severidade']}")
acuracy = correct / len(test_cases)
print(f"Acurácia: {acuracy * 100:.1f}%")
return acuracy
accuracy = evaluate_prompt(test_cases)
Versionando prompts
Em produção, você quer rastrear qual prompt gerou qual resposta. Use uma simples versão:
def create_prompt_version(version: str, system_prompt: str):
"""Guarda versão do prompt com metadados."""
import hashlib
prompt_hash = hashlib.sha256(system_prompt.encode()).hexdigest()[:8]
return {
"version": version,
"hash": prompt_hash,
"timestamp": "2026-08-01T10:00:00Z",
"prompt": system_prompt
}
# Ao fazer a chamada:
current_prompt_version = create_prompt_version("v1.2", create_ticket_classifier_prompt())
Forçando JSON estruturado
LLMs às vezes quebram JSON. Use response_format:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[...],
response_format={"type": "json_object"} # Força JSON válido
)
Isso garante que o modelo retorna JSON válido, mas você ainda precisa validar:
import json
from pydantic import BaseModel, ValidationError
class ClassificationOutput(BaseModel):
severidade: str
justificativa: str
tempo_resposta_estimado: str
checklist_tecnico: list[str]
requer_escalacao: bool
def classify_with_validation(ticket_text: str) -> ClassificationOutput:
"""Classifica e valida schema."""
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[...],
response_format={"type": "json_object"}
)
try:
data = json.loads(response.choices[0].message.content)
# Valida contra schema
return ClassificationOutput(**data)
except ValidationError as e:
print(f"Erro de schema: {e}")
raise
Armadilhas comuns
Prompt gigante
1.000 exemplos e seu prompt fica do tamanho de um livro. Isso aumenta latência e custo. Use máximo 3-4 exemplos bem escolhidos.
Instrução contraditória
"Seja conciso e detalhe tudo." Não funciona. Escolha um.
Exemplo que enviesa
ERRADO:
"Exemplos de CRÍTICO que vimos:"
[casos que você quer que sejam CRÍTICO]
CERTO:
[casos reais, balanceados, sem enviesamento]
Não testar com o modelo real
Você testou com GPT-4 mas vai usar GPT-3.5 em produção? Testa com o modelo que vai usar.
Prompt vazando dados sensíveis
Se você joga dados do cliente no prompt, eles são armazenados (exceto com opt-out de retenção OpenAI). Remova dados sensíveis antes de enviar.
Quando não usar engenharia de prompt complexa
- Você tem < 10 casos por dia: Um prompt simples é suficiente.
- A variação de entrada é muito grande: Fine-tuning pode ser melhor.
- Você precisa garantir 100% de precisão: Prompts têm limite de confiabilidade (~95%). Combine com validação manual ou regras.
Próximos passos
- Leia sobre RAG na prática para estruturar contexto de forma escalável.
- Compare com RAG, fine-tuning ou prompt? Guia de decisão para saber quando parar com prompts.
- Jogue Mestre Prompt para treinar estrutura de prompts.
Resumo: checklist de prompt em produção
- Defini um papel claro (system prompt)
- Contexto é específico (não genérico)
- Tarefa é precisa (não ambígua)
- Formato de saída é declarado (JSON, Markdown, etc)
- Tenho 2-3 exemplos reais
- Restrições estão explícitas (NÃO confundir com regras)
- Testei em 10+ casos reais
- Versionei o prompt (commit, tag, ou hash)
- Força JSON se precisa estruturado
- Temperatura definida (0.3 para determinístico, 0.7+ para criativo)
Pronto. Seu prompt agora é robusto.