Pular para o conteúdo
Categoria: Desenvolvendo com IA13 min de leitura

Como avaliar aplicações de LLM (LLM evals)

Por Lucas Andrade ·

Aprenda métricas, datasets de avaliação, LLM-as-a-judge e técnicas práticas para medir se sua aplicação de IA realmente funciona antes e depois de ir para produção.

Como avaliar aplicações de LLM (LLM evals)

Construir uma aplicação com LLM é a parte fácil; saber se ela funciona de verdade é o desafio real. Diferente de software tradicional, onde um teste passa ou falha de forma binária, modelos de linguagem produzem saídas abertas, variáveis e frequentemente "quase certas". Este guia mostra como criar um processo de avaliação (evals) que substitui o "achismo" por evidência mensurável.

Por que avaliar LLMs é diferente de testar software comum

No software determinístico, a mesma entrada sempre produz a mesma saída, então um assert simples resolve. Com LLMs, a mesma pergunta pode gerar respostas diferentes a cada chamada, e duas respostas distintas podem estar ambas corretas. Isso quebra a noção clássica de teste unitário.

Os principais obstáculos são:

  • Não-determinismo: temperatura, amostragem e atualizações do modelo mudam a saída.
  • Saída aberta: não há um único gabarito; existem muitas respostas válidas.
  • Critérios subjetivos: "útil", "claro" e "seguro" são difíceis de codificar.
  • Custo e latência: cada avaliação consome tokens e tempo, então rodar milhares de casos tem preço.

Por isso, avaliar uma aplicação de IA é menos sobre "passou/falhou" e mais sobre medir distribuições de qualidade ao longo de muitos exemplos. Quando você está montando seu primeiro projeto, vale conferir Como construir um app do zero usando LLMs para entender onde a camada de avaliação se encaixa no fluxo.

Há ainda uma armadilha conceitual importante: avaliar o modelo não é o mesmo que avaliar a sua aplicação. Benchmarks acadêmicos como MMLU medem capacidades gerais do modelo, mas dizem pouco sobre se o seu chatbot de suporte responde corretamente sobre a sua política de devolução. A eval que importa para você é específica da sua tarefa, dos seus dados e dos seus critérios — não uma nota genérica de leaderboard.

Defina o que "bom" significa antes de medir

O erro número um é começar a medir sem definir o objetivo. Antes de escrever qualquer eval, escreva uma especificação de qualidade: o que uma resposta excelente, aceitável e inaceitável tem.

Pense em três dimensões:

  1. Correção: a resposta está factualmente certa e resolve a tarefa?
  2. Aderência ao formato: respeita o esquema (JSON, idioma, tom, tamanho)?
  3. Segurança e política: evita conteúdo proibido, vazamento de dados ou instruções perigosas?

Para uma aplicação de suporte ao cliente, por exemplo, "bom" pode significar: responde em pt-BR, cita a política correta, não inventa números de pedido e mantém tom cordial. Escrever isso explicitamente transforma critérios vagos em algo testável.

Uma técnica prática para chegar a esses critérios é a análise de erros. Antes de inventar métricas, colete algumas dezenas de saídas reais do seu sistema e leia uma a uma, anotando livremente o que deu errado. Padrões emergem: "o modelo erra o prazo", "o modelo divaga", "o modelo responde em inglês". Esses padrões viram exatamente as dimensões que você precisa medir. Métrica boa nasce de erro observado, não de checklist genérico.

Construa um dataset de avaliação

Uma eval sem dataset é só uma opinião. O dataset é o conjunto de casos contra os quais você mede o sistema repetidamente. Comece pequeno e cresça com o tempo.

# Exemplo de dataset mínimo (JSONL)
{"id": "1", "input": "Qual o prazo de devolução?", "expected": "30 dias corridos"}
{"id": "2", "input": "Posso devolver item em promoção?", "expected": "Sim, se dentro de 30 dias"}
{"id": "3", "input": "Como rastrear meu pedido?", "expected_contains": ["código de rastreio", "transportadora"]}

Boas práticas para montar o dataset:

  • Cubra o caminho feliz e os casos de borda: perguntas ambíguas, fora de escopo e adversariais.
  • Inclua exemplos reais: registre interações de produção (anonimizadas) e transforme falhas em novos casos.
  • Versione o dataset: trate-o como código, com histórico no Git.
  • Anote o "esperado": às vezes é uma resposta exata, às vezes apenas trechos que devem aparecer.

Cada bug encontrado em produção deve virar um novo caso no dataset. Assim, a eval cresce na direção dos problemas reais, e regressões ficam impossíveis de passar despercebidas.

Quantos casos são suficientes?

Não existe número mágico, mas a lógica é estatística: quanto mais raro o comportamento que você quer detectar, mais casos precisa para capturá-lo com confiança. Vinte exemplos servem para uma sanidade inicial; centenas começam a dar estabilidade; milhares permitem segmentar por categoria (perguntas de devolução vs. rastreamento) e ver onde o sistema falha. Mais importante que o volume bruto é a diversidade: cem variações da mesma pergunta valem menos que vinte perguntas genuinamente diferentes. Estratifique o dataset por tipo de tarefa, idioma, dificuldade e origem para que a média não esconda buracos.

Métricas: dos clássicos de NLP às abordagens modernas

Existem várias famílias de métricas, e a escolha depende do tipo de tarefa.

Métricas baseadas em referência comparam a saída com um gabarito:

  • Exact match: a resposta é idêntica ao esperado. Útil para classificação e extração.
  • BLEU / ROUGE: medem sobreposição de n-gramas. Vieram da tradução e do resumo, mas penalizam paráfrases válidas.
  • Similaridade de embeddings: compara o significado, não as palavras exatas. Mais tolerante a reformulações.

Métricas de tarefa medem se o objetivo foi atingido:

  • Accuracy / F1 para classificação.
  • Pass@k para geração de código (passou nos testes?).
  • Taxa de aderência ao schema para saídas estruturadas.

Para tarefas abertas, métricas de sobreposição são insuficientes. É aí que entram avaliadores baseados em modelo.

Comece pelas verificações determinísticas

Antes de recorrer a métricas sofisticadas, esgote o que pode ser medido com código simples e barato. Muitas falhas são objetivas e não precisam de modelo nenhum para serem pegas:

import json

def avaliar_formato(saida: str) -> dict:
    resultado = {"json_valido": False, "tem_campos": False, "idioma_pt": False}
    try:
        dados = json.loads(saida)
        resultado["json_valido"] = True
        resultado["tem_campos"] = {"resposta", "fonte"} <= dados.keys()
    except json.JSONDecodeError:
        return resultado
    # heurística simples de idioma
    resultado["idioma_pt"] = any(p in saida.lower() for p in [" não ", " você ", " está "])
    return resultado

Verificações como "o JSON é válido?", "o campo obrigatório está presente?", "a resposta tem o tamanho permitido?", "contém alguma palavra proibida?" são rápidas, determinísticas e baratíssimas. Elas pegam uma fatia grande de problemas sem gastar um token de avaliação. Reserve o LLM-as-a-judge para o que sobra: a qualidade subjetiva.

LLM-as-a-judge: usando um modelo para avaliar outro

A técnica mais usada hoje para saídas abertas é o LLM-as-a-judge: um modelo (geralmente forte) recebe a entrada, a saída do sistema e uma rubrica, e atribui uma nota ou veredito.

JUIZ_PROMPT = """Você avalia respostas de suporte. Critérios:
- Correção factual (cita a política certa?)
- Idioma (responde em pt-BR?)
- Tom (cordial e profissional?)

Pergunta: {pergunta}
Resposta do sistema: {resposta}

Responda em JSON: {{"nota": 1-5, "justificativa": "..."}}"""

Para que o juiz seja confiável:

  • Dê uma rubrica explícita, não um "avalie de 0 a 10" genérico.
  • Prefira comparações par a par ("A é melhor que B?") em vez de notas absolutas, que são mais ruidosas.
  • Calibre contra humanos: meça a concordância entre o juiz e anotadores humanos antes de confiar nele.
  • Cuidado com vieses: juízes tendem a preferir respostas longas e a favorecer a própria saída.

A ideia de alinhar modelos ao julgamento humano tem raízes no trabalho sobre aprendizado por feedback humano, em que humanos comparam saídas para treinar o modelo a seguir instruções (Ouyang et al., 2022). O LLM-as-a-judge é, em parte, uma automação dessa lógica de preferência.

Vieses conhecidos e como mitigá-los

Pesquisas que estudaram o uso de LLMs como juízes documentaram vieses sistemáticos que você precisa conhecer (Zheng et al., 2023):

  • Viés de posição: ao comparar A e B, o juiz tende a preferir a opção que aparece primeiro. Mitigação: rode a comparação nas duas ordens e só conte como vitória quando o resultado for consistente.
  • Viés de verbosidade: respostas longas parecem mais completas mesmo quando não são. Mitigação: deixe a rubrica explícita sobre concisão e penalize divagação.
  • Viés de autopreferência: um modelo tende a gostar mais de saídas geradas por ele mesmo. Mitigação: use, quando possível, um juiz de família diferente do sistema avaliado.

A medida que separa um juiz confiável de um gerador de números aleatórios é a concordância com humanos. Anote manualmente uma amostra, rode o juiz sobre os mesmos casos e calcule o quanto eles concordam. Só depois de validar essa concordância você pode escalar o juiz para milhares de casos com alguma tranquilidade.

Avaliando dimensões específicas: alucinação e RAG

Algumas falhas merecem evals dedicadas. A mais crítica é a alucinação, quando o modelo afirma algo falso com confiança. Pesquisas mostram que esse é um problema estrutural da geração de linguagem natural, presente em resumo, diálogo e tradução (Ji et al., 2023). Para combatê-la, vale ler O que é alucinação em IA e como reduzi-la e medir explicitamente:

  • Faithfulness (fidelidade): a resposta é sustentada pelo contexto fornecido?
  • Groundedness: cada afirmação tem uma fonte rastreável?

Quando sua aplicação usa recuperação de documentos, a eval precisa cobrir duas etapas separadas. Em RAG na prática: dê memória e contexto ao seu LLM você vê o pipeline completo; na avaliação, separe:

  1. Qualidade da recuperação: os documentos certos foram trazidos? (precision/recall de contexto)
  2. Qualidade da geração: dado o contexto, a resposta o usa corretamente?

Avaliar as duas etapas em conjunto esconde a causa raiz. Se a recuperação falha, melhorar o prompt não resolve nada.

Para a etapa de recuperação, métricas clássicas de recuperação de informação ajudam a quantificar o problema. Recall@k mede se os documentos relevantes estão entre os k recuperados; precision@k mede quanto do que foi trazido é de fato relevante; e o MRR (Mean Reciprocal Rank) premia trazer o documento certo nas primeiras posições. Como a recuperação é determinística para uma dada base, ela é mais fácil de medir do que a geração — e costuma ser onde está a causa raiz de respostas ruins. Comece por ela.

def recall_at_k(recuperados, relevantes, k):
    topo = set(recuperados[:k])
    return len(topo & set(relevantes)) / len(relevantes)

Avaliando agentes e tarefas com múltiplos passos

Quando a aplicação não é uma única chamada, mas um agente que encadeia raciocínio, chamadas de ferramentas e várias rodadas, a avaliação muda de natureza. Não basta julgar a resposta final: é preciso avaliar a trajetória. Um agente pode chegar à resposta certa por sorte depois de três chamadas erradas de ferramenta, ou falhar mesmo tendo raciocinado bem. Algumas dimensões específicas de agentes:

  • Acerto da ferramenta: o agente escolheu a ferramenta certa e passou os argumentos corretos?
  • Eficiência: quantos passos e quantos tokens foram gastos para concluir? Loops e idas e vindas custam caro.
  • Conclusão da tarefa: o objetivo de ponta a ponta foi atingido, não apenas um passo intermediário?
  • Recuperação de erro: quando uma ferramenta falha, o agente se recupera ou trava?

Avaliar trajetórias normalmente combina checagens determinísticas sobre as chamadas de ferramenta (que são estruturadas e fáceis de inspecionar) com um juiz para a qualidade do raciocínio. Registrar o traço completo de cada execução é pré-requisito: sem ele, não há como saber onde a cadeia quebrou.

Integre evals ao seu ciclo de desenvolvimento

Uma eval só gera valor se rodar com frequência. O objetivo é transformá-la em uma rede de segurança, como testes automatizados.

  • Eval offline: roda no CI a cada mudança de prompt, modelo ou código, contra o dataset versionado.
  • Eval online: amostra interações reais de produção e mede qualidade ao vivo.
  • Guardrails: verificações rápidas em tempo de execução (formato, palavras proibidas) que bloqueiam saídas ruins.

Defina limiares de regressão: se a nota média cair abaixo de X, o deploy é barrado. Isso é o que permite trocar de modelo ou ajustar o prompt sem medo. Técnicas mais profundas, como Engenharia de contexto: o novo prompt engineering e Fine-tuning de LLMs: quando e como ajustar um modelo, só fazem sentido quando você consegue medir o efeito de cada mudança — caso contrário, você está otimizando às cegas.

Em produção, complemente os números com observabilidade. Registre cada chamada (entrada, saída, modelo, latência, custo, documentos recuperados) para conseguir reproduzir e investigar falhas depois. Sem rastreamento, uma reclamação de usuário vira um mistério impossível de depurar. Com rastreamento, ela vira um novo caso de teste no seu dataset. Esse ciclo — produção gera traços, traços viram casos, casos protegem contra regressão — é o que mantém a qualidade subindo ao longo do tempo.

Um pipeline mínimo de eval

def rodar_eval(sistema, dataset, juiz):
    notas = []
    for caso in dataset:
        saida = sistema(caso["input"])
        # 1. checagens determinísticas e baratas primeiro
        if not formato_valido(saida):
            notas.append(0); continue
        # 2. juiz apenas para qualidade subjetiva
        nota = juiz(caso["input"], saida)
        notas.append(nota)
    media = sum(notas) / len(notas)
    p10 = sorted(notas)[len(notas)//10]  # olhe a cauda, não só a média
    return {"media": media, "p10": p10, "n": len(notas)}

Repare no p10: olhar apenas a média esconde os piores casos. Um sistema com média 4,5 mas com 5% de respostas catastróficas pode ser pior, na prática, que um sistema mais consistente de média 4,2.

Erros comuns ao avaliar LLMs

  • Dataset minúsculo: cinco exemplos não representam a realidade. Busque diversidade.
  • Confiar cegamente no juiz: sem calibração humana, você só troca um viés por outro.
  • Medir só a média: olhe a cauda. Um sistema com média alta pode ter falhas catastróficas raras.
  • Esquecer o custo: evals caras viram evals que ninguém roda. Equilibre profundidade e velocidade.
  • Não fechar o ciclo: encontrar falhas sem convertê-las em novos casos de teste desperdiça o aprendizado.
  • Avaliar geração e recuperação juntas: misturar as duas etapas no RAG esconde a causa raiz.
  • Vazamento do dataset de teste no prompt: se os exemplos de avaliação foram usados para ajustar o prompt, a nota está inflada. Mantenha um conjunto de teste separado.

Perguntas frequentes

Preciso de um juiz de modelo grande e caro? Nem sempre. Para checagens objetivas, use verificações determinísticas (custo zero). Para qualidade subjetiva, um modelo de tamanho médio bem instruído com rubrica clara costuma bastar. Reserve o modelo mais caro para os casos ambíguos e para calibração.

Quantos casos preciso para começar? Comece com 20 a 50 casos representativos para ter uma sanidade. Cresça à medida que descobre falhas em produção, convertendo cada uma em um novo caso.

LLM-as-a-judge substitui avaliação humana? Não totalmente. Ele escala o julgamento, mas precisa ser calibrado contra humanos periodicamente. Humanos continuam sendo a referência de verdade, especialmente para decisões sensíveis.

Como evito que minha eval fique obsoleta? Trate o dataset como vivo: versione no Git, adicione casos vindos de falhas reais e revise periodicamente os critérios à medida que o produto evolui.

Conclusão

Avaliar aplicações de LLM é o que separa um protótipo impressionante de um produto confiável. Comece definindo o que "bom" significa, construa um dataset versionado com casos reais, esgote as verificações determinísticas baratas, combine métricas automáticas com LLM-as-a-judge calibrado contra humanos e integre tudo ao seu ciclo de desenvolvimento. Trate evals como cidadãos de primeira classe: cada falha vira um caso de teste, cada mudança passa pelo crivo do dataset. Com isso, você ganha a liberdade de iterar rápido sem quebrar o que já funcionava.

Referências

  • Ouyang, L., Wu, J., Jiang, X., Almeida, D., et al. (2022). Training Language Models to Follow Instructions with Human Feedback. NeurIPS.
  • Ji, Z., Lee, N., Frieske, R., Yu, T., Su, D., Xu, Y., Ishii, E., Bang, Y., Madotto, A., Fung, P. (2023). Survey of Hallucination in Natural Language Generation. ACM Computing Surveys.
  • Zheng, L., Chiang, W., Sheng, Y., Zhuang, S., et al. (2023). Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena. NeurIPS Datasets and Benchmarks.

Leituras relacionadas

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly