Avaliação de Prompts

A avaliação de prompts (prompt evaluation) é a disciplina de testar prompts como você testaria software: definir o comportamento esperado, medir resultados e detectar falhas antes que cheguem aos usuários. Como modelos de linguagem de grande porte (large language models) são probabilísticos (probabilistic) e sensíveis à redação, um prompt que “funciona” em uma demonstração ainda pode falhar sob paráfrases (paraphrases), casos de borda (edge cases), atualizações de modelo (model updates) ou entradas adversariais (adversarial inputs). Uma boa prática de avaliação foca em três objetivos:

  • Robustez (robustness): o prompt continua funcionando quando as entradas variam, estão ruidosas ou são adversariais?
  • Resistência a regressões (regression resistance): mudanças no prompt, no modelo, nas ferramentas ou no sistema ao redor degradam o desempenho?
  • Cobertura de tarefas (task coverage): você está testando toda a faixa de intenções do usuário e restrições que afirma suportar?

Este artigo explica fundamentos práticos e teóricos para avaliar prompts, com padrões concretos que você pode adotar na integração contínua (CI) e em produção.

Por que a avaliação de prompts é diferente da avaliação “normal” de modelos

Sistemas com prompts frequentemente se parecem com um pipeline (pipeline):

  1. Uma solicitação do usuário e o contexto são montados (prompt do sistema (system prompt), instruções, documentos recuperados, saídas de ferramentas).
  2. O modelo gera texto (saída estocástica (stochastic output)).
  3. O sistema faz pós-processamento (parsing, validação, chamadas de ferramentas, formatação).

Isso cria desafios de avaliação além de benchmarks clássicos de aprendizado de máquina (machine learning, ML):

  • Não determinismo (non-determinism): temperatura (temperature), amostragem (sampling) e até mudanças no back-end (backend) podem alterar as saídas.
  • Sensibilidade a instruções (instruction sensitivity): pequenas mudanças de redação podem causar grandes mudanças de comportamento.
  • Dependências ocultas (hidden dependencies): disponibilidade de ferramentas, qualidade de recuperação ou prompts do sistema podem dominar os resultados.
  • Correção subespecificada (underspecified correctness): muitas tarefas têm múltiplas respostas aceitáveis (resumos, conselhos, reescrita).

Um bom modelo mental é: um prompt é um programa; o modelo é um interpretador com comportamento estocástico. Seus testes devem combinar:

  • Verificações baseadas em especificação (specification-based checks) (formato, campos obrigatórios, regras de segurança)
  • Verificações baseadas em exemplos (example-based checks) (entradas/saídas de referência (golden inputs/outputs))
  • Verificações baseadas em propriedades (property-based checks) (invariantes que devem se manter sob variações)

Para padrões de design de prompts e modos de falha comuns, veja Padrões de Prompt e Armadilhas da Engenharia de Prompts.

O que avaliar: dimensões e métricas

Um prompt “bom” depende do produto. A maioria das avaliações combina várias dimensões:

Correção da tarefa (ela faz o trabalho?)

Para tarefas bem definidas (classificação, extração), você pode usar métricas padrão:

  • Acurácia (accuracy) / F1 para rótulos
  • Correspondência exata (exact match) ou acurácia por campo (field-level accuracy) para extração
  • Similaridade de strings (string similarity) (com cuidado) para saídas canônicas curtas

Para tarefas abertas (resumos, redação), a correção é mais difícil. Use:

  • Julgamentos humanos baseados em rubrica (rubric-based human judgments) (mais confiável)
  • Modelo de linguagem como avaliador (LLM-as-judge) com controles fortes (rápido, mas pode ser enviesado)
  • Preferência pareada (pairwise preference) (“A vs B”) em vez de pontuação absoluta

Conformidade de formato e contrato

Muitas falhas de prompt não são “respostas erradas”, mas forma errada:

  • JSON / YAML válido
  • Corresponde a um esquema
  • Inclui seções obrigatórias
  • Sem texto extra fora de um bloco

Essas verificações são ideais para automação.

Segurança e conformidade com políticas

Meça se o prompt:

  • Evita conteúdo proibido
  • Recusa quando necessário
  • Não vaza segredos do contexto
  • Resiste a conflitos de instruções e injeção de prompt (prompt injection)

Isso se sobrepõe a Segurança de Prompts, especialmente para agentes que usam ferramentas (tool-using agents).

Robustez sob variação

Teste o desempenho sob:

  • Paráfrases e sinônimos
  • Erros de digitação e gramaticais
  • Diferentes tamanhos (muito curto / muito longo)
  • Instruções conflitantes
  • Campos ausentes
  • Entradas multilíngues (se suportado)

Eficiência e custo

Especialmente em produção:

  • Uso de tokens (prompt + completion)
  • Percentis de latência
  • Contagem de chamadas de ferramenta / tentativas (retries)
  • Taxa de falhas (timeouts, falhas de parsing)

Calibração e incerteza (quando relevante)

Se sua UX depende de confiança (por exemplo, “Não tenho certeza”), teste:

  • Se o modelo corretamente se abstém (abstains)
  • Se a confiança se correlaciona com correção
  • Se o prompt incentiva excesso de confiança

Construindo um conjunto de avaliação: cobertura primeiro, depois escala

Uma suíte de avaliação de prompts é tão boa quanto os exemplos que inclui. Busque cobertura representativa, não apenas volume.

1) Comece a partir de uma especificação de tarefa

Escreva:

  • Intenções suportadas (o que os usuários querem)
  • Entradas e restrições (campos, domínio, idioma)
  • Saídas obrigatórias (formato, tom, restrições de segurança)
  • Limites de falha (quando recusar ou fazer perguntas de esclarecimento)

Transforme isso em uma matriz de testes (test matrix): linhas são tipos de cenário, colunas são dimensões de avaliação (correção, formato, segurança, robustez).

2) Colete casos de teste de múltiplas fontes

Boas suítes combinam:

  • Logs reais de usuários (melhor realismo, mas exige tratamento de privacidade)
  • Casos de borda curados manualmente (raros, mas importantes)
  • Variações sintéticas (synthetic variations) (paráfrases, erros de digitação, prompts adversariais)
  • Casos de regressão (regression cases) (falhas observadas anteriormente)

Tenha cuidado para não sobreajustar (overfitting) a um conjunto interno estreito — este é um problema clássico descrito em Armadilhas da Engenharia de Prompts.

3) Separe conjuntos de desenvolvimento, validação e “retenção”

Prompts evoluem rapidamente, e é fácil ajustar ao seu conjunto de testes. Trate a avaliação como em aprendizado de máquina:

  • Conjunto de desenvolvimento (dev set): usado durante a iteração do prompt
  • Conjunto de validação (validation set): usado para bloquear/aprovar mudanças
  • Conjunto de retenção (holdout set): raramente tocado; usado para detectar sobreajuste

4) Rotulagem: defina o “comportamento esperado”

Para tarefas determinísticas, armazene o ground truth.

Para tarefas abertas, armazene:

  • Uma rubrica (rubric) (critérios e regras de pontuação)
  • Múltiplas referências aceitáveis (se possível)
  • Ou preferências pareadas entre prompts candidatos

Um exemplo de rubrica para resumos pode incluir:

  • Fidelidade (sem alucinações)
  • Cobertura dos pontos-chave
  • Clareza e estrutura
  • Comprimento apropriado

Métodos automatizados de avaliação (com exemplos práticos)

A automação é essencial para regressões e iteração rápida, mas deve ser desenhada em torno de o que você consegue medir de forma confiável.

Validação de esquema/formato (alto impacto)

Se o seu prompt deve produzir JSON, valide-o estritamente.

Exemplo: prompt de extração (modelo)

You are an information extraction system.
Extract fields from the input and output ONLY valid JSON matching this schema:
{
  "invoice_id": string,
  "date": string (YYYY-MM-DD),
  "total_amount": number,
  "currency": string (ISO 4217)
}
If a field is missing, use null. Do not include extra keys.

Input:
{{document_text}}

Ideia de test harness (test harness) (pseudocódigo em estilo Python (Python-like pseudocode))

import json
from jsonschema import validate

SCHEMA = {
  "type": "object",
  "properties": {
    "invoice_id": {"type": ["string", "null"]},
    "date": {"type": ["string", "null"]},
    "total_amount": {"type": ["number", "null"]},
    "currency": {"type": ["string", "null"]},
  },
  "required": ["invoice_id", "date", "total_amount", "currency"],
  "additionalProperties": False
}

def eval_case(model, prompt, doc_text):
    output = model.generate(prompt.render(document_text=doc_text), temperature=0)
    try:
        data = json.loads(output)
        validate(instance=data, schema=SCHEMA)
        return {"pass": True, "data": data}
    except Exception as e:
        return {"pass": False, "error": str(e), "raw": output}

Isso captura muitas falhas reais de produção:

  • Comentários extras (“Here is the JSON:”)
  • Vírgulas finais, aspas inválidas
  • Chaves obrigatórias ausentes
  • Tipos errados

Pontuação por correspondência exata e por campo

Quando você tem ground truth:

  • Correspondência exata: rígida, mas frágil (boa para IDs)
  • Acurácia por campo: mais informativa para extração estruturada
def field_accuracy(pred, gold):
    keys = gold.keys()
    correct = sum(pred.get(k) == gold.get(k) for k in keys)
    return correct / len(keys)

Modelo de linguagem como avaliador (use com cuidado)

Um modelo de linguagem pode avaliar saídas contra uma rubrica. Isso é útil para estilo e tarefas abertas, mas introduz riscos:

  • Viés do avaliador para certas formulações
  • Sensibilidade à redação do prompt
  • Potencial preferência por respostas mais longas
  • Correlação com a mesma família de modelos sendo avaliada

Boas práticas:

  • Prefira comparação pareada (A vs B) em vez de pontuação 1–10
  • Use múltiplos avaliadores (modelos ou seeds diferentes) e agregue
  • Mantenha o prompt do avaliador estável e versionado
  • Audite uma amostra com humanos

Prompt de juiz pareado (rascunho)

You are grading two answers to the same user request.

User request:
{{request}}

Rubric:
- Correctness with respect to the request
- Factuality (no unsupported claims)
- Follows constraints (tone/length/format)
- Clarity and usefulness

Choose the better answer: "A", "B", or "Tie".
Explain briefly referencing the rubric.

Answer A:
{{answer_a}}

Answer B:
{{answer_b}}

Testes metamórficos (metamorphic testing) (verificações baseadas em propriedades)

Testes metamórficos afirmam relações que devem se manter entre entradas transformadas, mesmo quando não há uma única saída “correta”.

Exemplos:

  • Invariância a paráfrase (paraphrase invariance): a classificação de intenção não deve mudar sob paráfrase.
  • Invariância à ordem (order invariance): extrair entidades de uma lista não deve depender da ordem da lista.
  • Consistência de unidade (unit consistency): converter “$10” vs “10 USD” deve produzir o mesmo valor normalizado.

Essa abordagem é poderosa para robustez porque evita depender de “texto dourado” frágil.

Testes de robustez: tornando prompts resilientes a entradas do mundo real

Robustez é sobre desempenho sob mudança de distribuição (distribution shift) — entradas que diferem dos seus exemplos de teste bem “arrumados”.

Testes comuns de robustez

1) Variação de paráfrase e estilo

Gere ou colete variações:

  • “Please summarize…” vs “Give me the gist…”
  • Linguagem formal vs casual

Avaliação:

  • Para classificação/extração: verificações de invariância
  • Para geração: qualidade baseada em rubrica deve permanecer acima de um limiar

2) Ruído e erros de digitação

Usuários reais produzem texto bagunçado:

  • Erros de ortografia
  • Pontuação ausente
  • Artefatos de OCR

Teste com injeção sintética de ruído (noise injection):

  • Trocas aleatórias de caracteres
  • Remoção de espaços em branco
  • Mistura de maiúsculas/minúsculas

3) Extremos de comprimento de contexto

O comportamento do prompt pode mudar com:

  • Entradas muito curtas (subespecificadas)
  • Entradas muito longas (truncamento (truncation), diluição de atenção (attention dilution))

Inclua testes próximos ao contexto máximo (max context) do seu sistema e garanta que:

  • O prompt instrui o que fazer quando o contexto é longo demais (resumir, fazer perguntas de esclarecimento, recusar)
  • A lógica de recuperação ou segmentação (chunking) se comporta como esperado (veja Geração Aumentada por Recuperação se aplicável)

4) Instruções conflitantes ou adversariais

Exemplos:

  • Usuário inclui “Ignore previous instructions…”
  • Instruções embutidas dentro de texto citado
  • Tentativas maliciosas de exfiltrar o prompt do sistema ou segredos

Esses testes pertencem à sua suíte de prompts mesmo que você também implemente mitigações em nível de sistema. Veja Segurança de Prompts.

5) Ambiguidade e subespecificação

Teste se o prompt:

  • Faz perguntas de esclarecimento quando necessário
  • Faz suposições seguras quando permitido
  • Evita alucinar detalhes ausentes

Pontuação de robustez: não dependa de uma única execução

Como as saídas podem variar, especialmente com temperatura > 0:

  • Execute N tentativas (trials) por teste (por exemplo, N=3–10)
  • Pontue usando taxa de aprovação (pass rate) (com que frequência atende aos requisitos)
  • Acompanhe o comportamento de pior caso (worst-case) para restrições críticas de segurança

Por exemplo, para extração em JSON você pode exigir:

  • ≥ 99% de saídas válidas no esquema a temperatura 0
  • ≥ 95% de saídas válidas no esquema a temperatura 0.2 (se você usar isso em algum momento)

Testes de regressão: evitando que mudanças no prompt quebrem o comportamento

Prompts evoluem. Modelos atualizam. APIs de ferramentas mudam. Testes de regressão são como você evita o “estava funcionando ontem”.

O que pode causar regressões?

  • Editar o texto do prompt (óbvio)
  • Trocar modelo/versão/provedor
  • Ajustar temperature/top_p/max_tokens
  • Modificar o prompt do sistema ou instruções de desenvolvedor
  • Alterar recuperação (documentos, embeddings, ranking)
  • Alterar esquemas de ferramentas ou disponibilidade de ferramentas
  • Mudanças de pós-processamento (parsers, validadores)

Estrutura de uma suíte de testes de regressão

Uma suíte prática geralmente inclui:

  1. Testes de fumaça (smoke tests): conjunto pequeno, rápido, roda a cada commit
  2. Benchmark central (core benchmark): conjunto moderado, roda na CI em PRs
  3. Suíte estendida de robustez: grande e cara, roda à noite
  4. Suíte de segurança/red team (red-team suite): casos adversariais direcionados, roda antes de releases

Testes dourados vs testes “comportamentais”

  • Testes de saída dourada (golden output tests) (testes de snapshot (snapshot testing)) comparam o texto de saída exatamente. São frágeis, mas úteis para saídas rigidamente formatadas.
  • Testes comportamentais (behavioral tests) verificam propriedades (validade do esquema, contém campos obrigatórios, comportamento de recusa) e toleram variação inofensiva.

Na prática, combine ambos:

  • Testes de snapshot para saída estruturada e chamadas de ferramenta
  • Testes comportamentais para geração aberta

Lidando com diffs e critérios de aceitação

Quando uma mudança melhora alguns casos e piora outros, você precisa de regras claras:

  • Defina uma métrica primária (por exemplo, taxa de sucesso da tarefa) e métricas de salvaguarda (guardrail metrics) (segurança, conformidade de formato)
  • Exija que as salvaguardas nunca regridam além de uma pequena tolerância
  • Use comparações pareadas ao avaliar prompt A vs prompt B nos mesmos casos

Estatisticamente, para resultados passa/falha você pode usar:

  • Intervalos de confiança por bootstrap (bootstrap confidence intervals)
  • Teste do sinal (sign test) / teste de McNemar (McNemar’s test) para desfechos binários pareados

Até relatórios simples ajudam: “+2,1% de sucesso de tarefa (IC 95% ±0,8%), conformidade de formato inalterada, recusas de segurança +0,3%.”

Versionamento e rastreabilidade

Trate prompts como artefatos versionados:

  • Armazene prompts em controle de versão
  • Inclua uma versão do prompt em logs/telemetria (telemetry)
  • Registre nome do modelo, parâmetros de amostragem, versão de recuperação e versões de ferramentas para cada execução

Isso é crucial ao investigar regressões após o deploy.

Cobertura de tarefas: testando o que os usuários realmente fazem (e o que não deveriam)

Cobertura é sobre se sua suíte de avaliação representa o espaço de tarefas e restrições que seu sistema afirma lidar.

Defina famílias de tarefas e sub-habilidades

Por exemplo, um “assistente de suporte ao cliente” pode precisar de:

  • Detecção de intenção (cobrança vs técnico)
  • Respostas ancoradas em políticas
  • Resumo da conversa anterior
  • Extração de detalhes da conta (com regras de privacidade)
  • Uso de ferramentas (criação de ticket, consulta de status)

Cada sub-habilidade merece testes.

Técnicas de cobertura

1) Mapeamento de requisitos para testes

Mantenha um mapeamento de requisitos do produto para casos de teste. Para cada requisito, garanta que você tenha:

  • Caso típico
  • Caso de borda
  • Caso adversarial
  • Caso negativo (deve recusar / deve pedir esclarecimento)

2) Cobertura por segmento de usuário e localidade

Se você atende múltiplas localidades, inclua:

  • Variantes de idioma
  • Formatos de data/número
  • Diferenças culturais nas expectativas de tom (se relevante)

3) Cobertura de conteúdo e domínio

Inclua jargão e formatos específicos do domínio:

  • Abreviações médicas (se permitido)
  • Cláusulas legais
  • Trechos de código
  • Tabelas e listas com marcadores

4) Cobertura de cauda longa via amostragem

A partir de logs, amostre:

  • Intenções frequentes (head)
  • Intenções raras, mas críticas (tail)
  • Padrões recentes e novos (comportamento emergente)

Uma prática útil é atualizar mensalmente uma parte da suíte a partir de logs de produção (com salvaguardas de privacidade).

Avaliando prompts em sistemas com uso de ferramentas e sistemas agentivos

Quando prompts conduzem chamadas de ferramenta (busca, consultas a banco de dados, execução de código), a avaliação deve incluir correção do processo (process correctness), não apenas o texto final.

O que testar:

  • Seleção correta de ferramenta (chama a ferramenta certa para a tarefa)
  • Argumentos corretos (válidos no esquema, seguros)
  • Comportamento correto de parada (não entra em loop)
  • Comportamento robusto de recusa quando ferramentas falham
  • Nenhum vazamento de segredos em entradas/saídas de ferramentas

Dica prática: registre um rastro estruturado (structured trace) (chamadas de ferramenta, argumentos, resultados). Em seguida, execute asserções como:

  • “Nunca enviar informações de identificação pessoal (PII, personally identifiable information) para a ferramenta de busca”
  • “Nunca chamar ferramentas de ‘delete’ a menos que o usuário tenha confirmado explicitamente”

Isso é intimamente relacionado a Segurança de Prompts.

Fluxo de trabalho prático de avaliação (o que as equipes realmente fazem)

Um fluxo maduro se parece com isto:

  1. Definir critérios de sucesso (sucesso da tarefa + salvaguardas)
  2. Criar uma suíte de avaliação em camadas (fumaça/central/robustez/segurança)
  3. Automatizar verificações baratas (validação de esquema, padrões de recusa, restrições por palavras-chave)
  4. Adicionar avaliação baseada em rubrica para tarefas abertas (avaliador por modelo de linguagem + auditorias humanas)
  5. Executar na CI para cada mudança de prompt
  6. Executar à noite para robustez estendida e acompanhamento de custo
  7. Monitorar em produção com canários (canaries) e telemetria

Exemplo de política de bloqueio/aprovação na CI

  • Merge permitido se:
    • Suíte central com sucesso de tarefa ≥ baseline − 0,5%
    • Validade do esquema JSON ≥ 99,5%
    • Suíte de segurança: 0 falhas críticas
    • Custo de tokens ≤ baseline + 5%

Isso força autores de prompts a tratar confiabilidade como requisito, não como esperança.

Armadilhas comuns de avaliação (e como evitá-las)

  • Sobreajuste ao conjunto de avaliação: mantenha um conjunto de retenção; rotacione regularmente novos casos. (Veja Armadilhas da Engenharia de Prompts.)
  • Testar apenas “caminhos felizes” (happy paths): adicione entradas adversariais, ambíguas e bagunçadas.
  • Usar correspondência exata para tarefas abertas: prefira rubricas, preferência pareada e verificações por propriedades.
  • Ignorar o não determinismo: execute múltiplas tentativas; avalie taxas de aprovação.
  • Não versionar o contexto: registre versões de modelo, estado de recuperação e prompts do sistema, não apenas o prompt do usuário.
  • Confundir qualidade do prompt com qualidade do sistema: avalie prompt + recuperação + ferramentas como um sistema integrado quando for isso que você entrega.

Checklist: uma suíte forte de avaliação de prompts

  • Especificação

    • Definição clara do comportamento desejado e condições de recusa
    • Contrato de saída (formato/esquema) documentado
  • Cobertura

    • Matriz de testes entre tarefas, segmentos de usuários e casos de borda
    • Exemplos realistas a partir de logs (com privacidade garantida)
  • Robustez

    • Testes de paráfrase, erro de digitação/ruído, contexto longo, ambiguidade
    • Testes adversariais/injeção de prompt (veja Segurança de Prompts)
  • Regressão

    • Suítes em camadas (fumaça/central/noturna)
    • Prompts versionados e métricas acompanhadas ao longo do tempo
    • Comparação estatística para mudanças A/B de prompt quando necessário
  • Automação

    • Validação de esquema e invariantes como verificações de primeira classe
    • Modelo de linguagem como avaliador usado com comparações pareadas e auditorias humanas periódicas

Avaliar prompts é, em última instância, transformar “artesanato de prompt” em uma disciplina de engenharia: requisitos mensuráveis, testes repetíveis e releases controladas. Quando bem feito, isso torna sistemas baseados em prompts muito mais confiáveis — especialmente à medida que modelos, ferramentas e comportamento do usuário evoluem.