Pular para o conteúdo
ZYNQORALABS

Avalie a recuperação antes da geração: como medir um sistema RAG

A maior parte dos erros de um sistema RAG nasce na recuperação, não no modelo. Como montar um conjunto de avaliação e medir recall, MRR e fidelidade no CI.

Por ZynqoraLabs · · 4 min de leitura

CompartilharLinkedInXWhatsApp

Quando um assistente baseado em RAG (geração aumentada por recuperação) responde algo errado, a reação comum é trocar o modelo ou reescrever o prompt. Na prática, boa parte desses erros acontece um passo antes: o trecho que continha a resposta nunca chegou ao modelo. Um modelo excelente com contexto errado produz uma resposta errada, só que mais bem escrita.

Por isso, a primeira coisa que medimos em um sistema RAG não é a resposta final. É a recuperação.

Separe o sistema em duas perguntas

Um pipeline RAG responde a duas perguntas diferentes, e cada uma precisa de uma métrica própria:

  1. A recuperação encontrou a evidência certa? Isso depende de chunking, embeddings, busca textual, filtros de permissão e reranking.
  2. A geração usou essa evidência corretamente? Isso depende do modelo, do prompt e das regras de citação.

Se você mede apenas a resposta final, não sabe qual das duas falhou. Uma queda de qualidade depois de mudar a estratégia de chunking aparece igual a uma queda causada por um prompt pior.

Monte o conjunto de avaliação antes do sistema

O conjunto de avaliação é uma lista de perguntas reais com a indicação de quais trechos dos documentos contêm a resposta. Ele não precisa ser enorme para ser útil: algumas dezenas de perguntas bem escolhidas já revelam a maioria das regressões, e ele cresce com o tempo.

Três cuidados fazem diferença:

  • Perguntas de usuários reais, não perguntas escritas por quem conhece o documento de cor. Usuários usam sinônimos, abreviações e formulações vagas.
  • Perguntas sem resposta. Inclua casos em que o documento não contém a informação. O comportamento correto é recusar, e isso também precisa ser medido.
  • Identificadores estáveis. Cada trecho precisa de um ID que não mude quando você reprocessa os documentos, senão o conjunto de avaliação quebra a cada mudança de pipeline.
eval/contracts.jsonl (uma linha)
{"id": "q-017", "question": "Qual é a multa por rescisão antecipada?", "relevant": ["contrato-0442/§14.2"], "answerable": true}

Métricas de recuperação

Com o conjunto em mãos, duas métricas simples cobrem a maior parte das necessidades.

Recall@k mede a fração de perguntas em que pelo menos um trecho relevante apareceu entre os k primeiros resultados. Se o recall@5 é 0,70, em 30% das perguntas o modelo nunca viu a evidência e, na melhor das hipóteses, vai recusar.

MRR (mean reciprocal rank) mede quão alto o primeiro trecho relevante aparece. Ele importa porque modelos dão mais peso ao que vem primeiro no contexto, e porque você pode querer reduzir k para economizar tokens.

eval/retrieval.py
def recall_at_k(results: dict[str, list[str]], gold: dict[str, set[str]], k: int) -> float:
    hits = sum(1 for q, ranked in results.items() if gold[q] & set(ranked[:k]))
    return hits / len(results)
 
 
def mean_reciprocal_rank(results: dict[str, list[str]], gold: dict[str, set[str]]) -> float:
    total = 0.0
    for q, ranked in results.items():
        for position, chunk_id in enumerate(ranked, start=1):
            if chunk_id in gold[q]:
                total += 1.0 / position
                break
    return total / len(results)

Calcule as métricas apenas sobre perguntas respondíveis. As não respondíveis entram na avaliação da geração.

Métricas de geração

Para a geração, três medidas cobrem os riscos principais:

  • Fidelidade: cada afirmação da resposta é sustentada pelos trechos fornecidos? Pode ser avaliada por revisão humana em amostras e, em escala, por um modelo avaliador com instruções estritas.
  • Validade das citações: toda citação aponta para um trecho que de fato foi enviado ao modelo? Isso é verificável por código, sem modelo nenhum, e deve bloquear a resposta quando falha.
  • Taxa de recusa correta: nas perguntas sem resposta, o sistema recusou? E nas respondíveis, recusou indevidamente?

Avaliadores automáticos baseados em LLM são úteis, mas têm vieses: tendem a favorecer respostas longas e podem concordar com erros plausíveis. Calibre o avaliador contra uma amostra revisada por pessoas antes de confiar nos números.

Coloque a avaliação no CI

A avaliação só protege o sistema se rodar sempre. Tratamos o conjunto de avaliação como um teste de regressão: toda mudança em chunking, embeddings, modelo ou prompt executa a suíte e compara com a linha de base.

Dois detalhes evitam frustração:

  1. Limiares com margem. Pequenas variações são normais, especialmente na geração. Falhe o build em quedas relevantes, não em ruído.
  2. Relatório por pergunta. Uma média esconde onde está o problema. Guarde quais perguntas mudaram de acerto para erro, porque é ali que está o diagnóstico.

Quando o recall está baixo

Algumas causas aparecem com frequência:

  • Termos exatos. Números de cláusula, códigos de produto e nomes próprios são mal representados por embeddings. Busca híbrida, combinando vetores com busca textual, costuma resolver.
  • Chunks que cortam o conteúdo. Janelas fixas de tokens separam uma regra da sua exceção. Segmentar pela estrutura do documento ajuda.
  • Filtros de permissão aplicados tarde. Se você filtra depois de recuperar os k primeiros, pode sobrar zero resultado. Aplique o filtro na própria consulta.

Resumo

Medir a recuperação separadamente transforma a melhoria de um sistema RAG de tentativa e erro em engenharia. Com um conjunto de avaliação versionado, métricas de recall e fidelidade e execução contínua, cada mudança vira uma decisão informada, e uma troca de modelo deixa de ser uma aposta.