Avaliação de RAG: faithfulness, relevance e precision
"Parece que está funcionando bem" é o pior critério de avaliação que existe para um sistema RAG. Você só descobre que não estava funcionando quando o cliente liga reclamando de uma resposta errada. Este artigo apresenta 8 métricas concretas, como montar um golden dataset do zero e como colocar avaliação automática no seu pipeline de deploy.
"Parece que funciona" não é avaliação — e o custo de descobrir tarde
A maioria dos projetos RAG passa por três fases de avaliação informal:
- Demo phase: o desenvolvedor faz 5–10 perguntas que ele mesmo sabe as respostas. O sistema responde bem. "Está funcionando."
- Beta phase: usuários fazem perguntas mais variadas. O sistema responde bem para ~70% e inventa para o resto. "Ainda tem uns ajustes."
- Produção: volume real de queries, corpus atualizado, LLM trocado para economizar. As métricas que ninguém estava medindo despencam. O cliente liga.
O problema é que LLMs são muito bons em soar confiantes. Uma resposta alucinada frequentemente parece mais bem escrita que uma resposta factualmente correta e hesitante. Sem métricas, você não distingue qualidade de aparência de qualidade.
Veja como funciona o pipeline RAG para entender quais etapas as métricas abaixo estão avaliando.
As 8 métricas essenciais de RAG
Cada métrica avalia uma parte diferente do pipeline. Algumas medem o retrieval (a busca), outras medem a geração (o LLM), e algumas medem o sistema como um todo.
| Métrica | O que mede | Como calcular | Meta típica | Etapa do pipeline |
|---|---|---|---|---|
| Faithfulness | Proporção de afirmações na resposta que estão factualmente suportadas pelo contexto recuperado | LLM-as-judge: para cada claim na resposta, verifica se está presente nos chunks de contexto. Score = claims_suportados / total_claims | ≥ 0,85 | Geração (LLM) |
| Answer Relevancy | Se a resposta de fato responde à pergunta feita (mesmo que verdadeira, pode ser irrelevante) | Embedding da resposta vs. embedding da pergunta + LLM-as-judge para perguntas abertas | ≥ 0,80 | Geração (LLM) |
| Context Recall | Proporção da resposta correta que está coberta pelos chunks recuperados (quantos fatos necessários estavam no contexto) | Compara resposta do golden dataset com chunks recuperados. Requer ground truth. Score = fatos_cobertos / total_fatos_necessários | ≥ 0,80 | Retrieval (busca) |
| Context Precision | Proporção dos chunks recuperados que são de fato relevantes para a pergunta (sem ruído) | Para cada chunk recuperado: relevante ou não? Score = chunks_relevantes / total_chunks_recuperados | ≥ 0,75 | Retrieval (busca) |
| RAGAS Score | Média harmônica de Faithfulness, Answer Relevancy, Context Recall e Context Precision — score único do sistema | Calculado pelo framework RAGAS (pip install ragas). Automatizável. | ≥ 0,75 | Sistema completo |
| Latência P95 | Tempo de resposta do 95º percentil — o que 1 em cada 20 usuários experimenta no pior caso | Medir tempo wall-clock de query a resposta. P95 = percentil 95 da distribuição ao longo de um período. | ≤ 4.000ms | Sistema completo |
| Custo por Query | Custo médio em USD de tokens de entrada + saída do LLM + chamadas de embedding + reranking por query | Somar tokens de contexto + query + resposta × preço por token do modelo. Incluir embedding e reranking se externos. | ≤ US$ 0,05 | Sistema completo |
| Taxa de Fallback | Proporção de queries em que o sistema retorna "não encontrei informação" ou resposta vazia — seja por retrieval ruim ou query fora do escopo | Contar respostas com padrões de fallback ("não tenho informação sobre", "não encontrei") dividido pelo total de queries | ≤ 10% | Sistema completo |
Framework RAGAS: avaliação automatizada com LLM-as-judge
O RAGAS (Retrieval Augmented Generation Assessment) é um framework open-source que automatiza o cálculo das principais métricas usando um LLM como juiz. A premissa: se você não tem humanos avaliando cada resposta (e não vai ter em produção), use um LLM mais capaz para avaliar o LLM menor.
# Instalação
pip install ragas langchain openai
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_recall,
context_precision
)
from datasets import Dataset
# Estrutura esperada pelo RAGAS
dados = {
"question": ["Qual o prazo de entrega padrão?", "Como cancelo um pedido?"],
"answer": [resposta_sistema_1, resposta_sistema_2],
"contexts": [[chunks_recuperados_1], [chunks_recuperados_2]],
"ground_truth": ["5 dias úteis", "Pelo portal em até 24h após o pedido"]
}
dataset = Dataset.from_dict(dados)
resultado = evaluate(
dataset,
metrics=[faithfulness, answer_relevancy, context_recall, context_precision]
)
print(resultado)
# Output: {'faithfulness': 0.87, 'answer_relevancy': 0.82,
# 'context_recall': 0.79, 'context_precision': 0.73}
Custo de rodar RAGAS: cada par (pergunta, resposta, contexto) consome ~2.000–5.000 tokens de LLM para avaliação. Com GPT-4o-mini (~US$ 0,15/M tokens de entrada), avaliar 100 pares custa cerca de US$ 0,30–0,75. Viável para rodar a cada PR ou deploy.
Como montar um golden dataset do zero
O golden dataset é o ativo mais valioso para avaliação de RAG. Ele não pode ser gerado automaticamente (pelo menos não na sua totalidade) — requer conhecimento do domínio.
Processo de criação
- Identifique os casos de uso principais: quais perguntas o sistema precisa responder bem? Categorize: perguntas simples (fato único), perguntas de comparação, perguntas multi-hop, perguntas fora do escopo.
- Colete perguntas reais: se o sistema já está em uso (mesmo beta), analise os logs. Perguntas reais de usuários são muito melhores que perguntas inventadas.
- Defina as respostas esperadas: um especialista do domínio (não o desenvolvedor) deve escrever a resposta correta e indicar o trecho do documento que a suporta.
- Documente o chunk de origem: para cada par, registre qual chunk (ou trecho) contém a resposta. Isso permite calcular Context Recall de forma precisa.
- Inclua casos negativos: perguntas que o sistema não deve responder (fora do escopo, dados que não existem na base). Mede se o sistema alucina quando não deveria responder.
Tamanho mínimo viável
- 50 pares: suficiente para detectar problemas grandes. Use para validação rápida durante desenvolvimento.
- 100–200 pares: recomendado para produção. Cobre variações de vocabulário e edge cases.
- 500+ pares: para sistemas críticos (saúde, jurídico, financeiro) onde erros têm consequências sérias.
Automação de avaliação em CI/CD: bloqueando regressões
O objetivo é que nenhuma mudança no corpus de documentos, no código de retrieval ou no modelo LLM passe para produção sem que as métricas sejam verificadas automaticamente.
# .github/workflows/avaliacao-rag.yml (exemplo simplificado)
name: Avaliação RAG
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
avaliar:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Instalar dependências
run: pip install ragas pytest
- name: Rodar avaliação no golden dataset
run: python scripts/avaliar_rag.py --dataset golden_dataset.json
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
VECTOR_STORE_URL: ${{ secrets.VECTOR_STORE_URL }}
- name: Verificar thresholds
run: |
python scripts/verificar_thresholds.py \
--faithfulness 0.85 \
--context-recall 0.80 \
--context-precision 0.75 \
--ragas-score 0.75
Se qualquer métrica cair abaixo do threshold, o pipeline falha e o PR é bloqueado. Isso é especialmente importante quando:
- Novos documentos são adicionados ao corpus (podem introduzir chunks conflitantes)
- O modelo de embedding é atualizado (muda toda a geometria do espaço vetorial)
- O LLM é substituído por versão mais barata (pode ter faithfulness menor)
- O chunk size ou overlap é alterado
Para ver como integrar avaliação com a estratégia de busca, veja como busca híbrida e reranking impactam as métricas de RAG.
Métricas operacionais: latência e custo também são qualidade
Times de produto às vezes tratam latência e custo como "preocupações de infra", não de qualidade. Mas para o usuário, um sistema que responde corretamente em 8 segundos é menos útil que um que responde com 90% de acurácia em 2 segundos.
Monitore em produção:
- Latência P50, P95, P99: o P50 não basta — o P95 revela o que usuários ocasionais experimentam nos dias ruins.
- Custo por query por modelo: se o contexto médio crescer (mais chunks, chunks maiores), o custo por query sobe sem que ninguém perceba até a fatura chegar.
- Taxa de timeout: queries que ultrapassam o limite de tempo configurado e retornam erro. Comum quando o corpus cresce e a busca não está otimizada.
- Taxa de fallback por categoria de pergunta: o sistema pode ter alta taxa de fallback apenas para um tipo de pergunta — sinal de gap no corpus, não no sistema todo.
Para conectar métricas de avaliação com o ciclo completo de desenvolvimento, veja ciclo de vida de uma aplicação LLM em produção.