Blog

Reranking em RAG: melhorar o retrieval sem trocar o modelo

Depois de cortar o documento bem e escolher um bom modelo de embedding, muita gente considera o retrieval resolvido: a busca vetorial devolve os vizinhos mais próximos e pronto. Mas há uma etapa entre "recuperar candidatos" e "montar o contexto" que quase todo pipeline pula e que decide se a resposta certa chega ao modelo: a reordenação dos candidatos por relevância real. A busca por similaridade de embedding é rápida e boa para varrer milhões de trechos, mas ela compara vetores comprimidos, não a pergunta contra o texto. O resultado é que o trecho que responde exatamente à pergunta muitas vezes está entre os recuperados, só que na sétima ou décima posição, e você corta o contexto nos três primeiros. O reranking existe para corrigir isso: recuperar um conjunto amplo e barato, e então reordenar com um modelo que de fato lê pergunta e trecho juntos, colocando a resposta certa no topo. Este artigo mostra por que o embedding erra a ordem, o que é um cross-encoder e como ele difere do bi-encoder, o padrão recuperar-amplo-reranquear-estreito, o custo e a latência que o reranking adiciona e como medir se ele está valendo a pena, tudo sem trocar o modelo de geração.

2026-07-17 / IA Aplicada / 13 min

01

Por que a busca por embedding erra a ordem dos trechos

A busca vetorial funciona assim: no momento da ingestão, cada trecho é transformado em um vetor por um modelo de embedding; no momento da consulta, a pergunta vira outro vetor e você busca os trechos cujo vetor está mais próximo. Isso é chamado de bi-encoder, porque pergunta e trecho são codificados separadamente, cada um sem ver o outro. É extremamente rápido, porque os vetores dos trechos são pré-calculados e a busca é só uma comparação de distância. O problema é justamente esse: pergunta e trecho nunca se olham. O embedding comprime todo o significado de um parágrafo num único vetor de algumas centenas de dimensões, e nessa compressão detalhes se perdem. Dois trechos que falam do mesmo assunto geral ficam próximos da pergunta, mesmo que só um responda de fato à pergunta específica.

O sintoma clássico é o trecho certo aparecer entre os recuperados, mas fora do topo. Você pede os 20 vizinhos mais próximos e a resposta exata está na posição 9. Se o pipeline monta o contexto com os 3 ou 5 primeiros, a resposta certa foi recuperada e depois descartada, e o modelo responde a partir de trechos que só tangenciam a pergunta. Não é falha do embedding em recuperar, é falha em ordenar. Recall alto e ordem ruim é exatamente o cenário em que o reranking mais rende: a informação está lá, só está na posição errada.

AspectoBi-encoder (embedding)Cross-encoder (reranker)
Como comparaVetor da pergunta contra vetor do trechoLê pergunta e trecho juntos, par a par
VelocidadeMuito rápida, vetores pré-calculadosLenta, um forward por par pergunta-trecho
EscalaMilhões de trechos por consultaDezenas de candidatos por consulta
Precisão da ordemBoa para triagem, fraca no topoAlta, entende a pergunta específica

A lição é que embedding e reranking não competem, eles se complementam. O embedding é a triagem barata que varre tudo e traz os candidatos plausíveis; o reranking é o segundo olhar caro que lê com atenção e decide a ordem final. Usar só o primeiro é rápido e impreciso no topo; o resto do artigo é sobre como encaixar o segundo sem estourar latência nem custo.

02

Cross-encoder: o modelo que lê pergunta e trecho juntos

O reranker é tipicamente um cross-encoder: em vez de codificar pergunta e trecho separadamente, ele recebe os dois concatenados na mesma entrada e produz um único número, a pontuação de relevância daquele par. Porque a pergunta e o trecho passam juntos pelo modelo, ele consegue capturar a interação entre eles, quais palavras da pergunta são de fato respondidas pelo trecho, e não só se os dois falam do mesmo tema. É essa leitura conjunta que o bi-encoder não faz e que corrige a ordem. O preço é que não dá para pré-calcular nada: cada par pergunta-trecho exige uma passada pelo modelo na hora da consulta. Por isso o cross-encoder é preciso demais para escanear o índice inteiro e barato o bastante para reordenar algumas dezenas de candidatos.

// rerank/crossEncoder.js
// Reranking com cross-encoder: recebe a pergunta e a lista de candidatos
// vinda da busca vetorial, pontua cada par pergunta-trecho e devolve
// os candidatos reordenados do mais relevante ao menos relevante.

export async function rerank(query, candidates, { scoreFn, topN = 5 } = {}) {
  // Um forward do modelo por par (pergunta, trecho). Custa mais que a
  // busca vetorial, por isso roda so sobre os candidatos, nao sobre o indice.
  const scored = await Promise.all(
    candidates.map(async (c) => ({
      ...c,
      // scoreFn compara pergunta e trecho JUNTOS: quao bem este trecho
      // responde ESTA pergunta, nao so se falam do mesmo assunto.
      score: await scoreFn(query, c.text),
    })),
  );

  // Reordena por relevancia real e corta no topN que vai ao modelo.
  // O embedding fez a triagem; o cross-encoder decide a ordem final.
  return scored.sort((a, b) => b.score - a.score).slice(0, topN);
}

Você não precisa treinar um cross-encoder para começar: há modelos de reranking prontos, servidos por API ou rodando local, que recebem uma pergunta e uma lista de trechos e devolvem as pontuações. A decisão de engenharia não é qual arquitetura implementar do zero, é quantos candidatos mandar para o reranker e quantos entregar ao modelo depois. Esse é o coração do padrão que vem a seguir: recuperar amplo com o embedding, reranquear estreito com o cross-encoder.

03

O padrão: recuperar amplo, reranquear, entregar estreito

O reranking só ajuda se a resposta certa estiver entre os candidatos recuperados. Por isso a busca vetorial na frente deve pescar um conjunto amplo, bem maior do que o que vai ao modelo. Recuperar só os 3 mais próximos pelo embedding e reranquear esses 3 não adianta nada: se a resposta estava na posição 9, ela nem entrou na peneira. O padrão certo é recuperar largo (dezenas de candidatos), reranquear tudo isso com o cross-encoder e só então cortar nos poucos melhores que cabem na janela do modelo. O embedding maximiza recall barato; o reranker maximiza precisão no topo.

Recuperar amplo -> reranquear -> entregar estreito

  pergunta
     |
     v
  [ busca vetorial / embedding ]   <- barato, varre o indice inteiro
     |  recupera ~30 candidatos (recall alto, ordem fraca)
     v
  [ c9 c3 c17 c1 c22 ... ]         <- resposta certa esta aqui, mas na pos. 9
     |
     v
  [ cross-encoder reranker ]        <- caro, le pergunta+trecho par a par
     |  reordena por relevancia real
     v
  [ c9 c1 c3 ]                      <- top-N; a resposta certa subiu ao topo
     |
     v
  [ modelo de geracao ]             <- recebe so o contexto certo e enxuto

  recuperar 3 e reranquear 3 = inutil: se a resposta esta na pos. 9,
  nem entra na peneira. Recuperar amplo e o que da material ao reranker.

Há dois números para calibrar. O primeiro é quantos candidatos a busca vetorial recupera antes do reranking: amplo o bastante para conter a resposta certa com folga, sem virar um conjunto grande demais que encareça a etapa de reranking. O segundo é quantos trechos, depois de reordenados, vão ao modelo: enxuto o bastante para não diluir o contexto nem gastar janela à toa. O reranking permite ser generoso na recuperação e econômico na entrega, porque a reordenação garante que os poucos que sobrarem são os melhores, não só os primeiros que o vetor devolveu.

04

O custo real: latência e preço que o reranking adiciona

Reranking não é grátis. Cada candidato reranqueado é uma passada por um modelo, então reordenar 30 candidatos é 30 inferências que não existiam antes, seja em tempo de GPU local, seja em chamadas a uma API de reranking. Isso soma latência entre a busca vetorial e a geração, e soma custo por consulta. A conta é direta: quanto mais amplo o conjunto recuperado, maior a chance da resposta certa estar dentro, mas maior a fatura e o tempo do reranking. O trabalho de engenharia é achar o ponto em que ampliar mais o conjunto não melhora mais a resposta, só encarece.

  • Latência: o reranking entra no caminho crítico entre buscar e gerar; um reranker lento pode custar mais tempo que a própria geração. Meça o acréscimo, não assuma que é desprezível.
  • Custo por consulta: reranquear N candidatos é N inferências extras; num sistema de alto volume isso pode superar o custo da própria chamada de geração.
  • Retorno decrescente: dobrar o número de candidatos recuperados raramente dobra a qualidade; existe um platô a partir do qual só se paga mais sem ganhar recall.
  • Reranker local versus API: rodar local troca custo por chamada por custo de infraestrutura e engenharia; a API é mais simples mas cobra por trecho reranqueado.

A forma de domar o custo é não reranquear quando não é preciso. Se a busca vetorial já devolve um primeiro candidato com pontuação de similaridade muito alta e destacada dos demais, provavelmente a triagem já acertou e o reranking vai só confirmar. Reservar o cross-encoder para as consultas ambíguas, aquelas em que os candidatos têm pontuações parecidas e a ordem está de fato incerta, corta boa parte da conta sem perder o ganho onde ele importa. Reranking é um segundo olhar caro; aplicá-lo indiscriminadamente desperdiça o que ele tem de melhor.

05

Medir se o reranking está valendo a pena

O reranking mexe na ordem, então as métricas que importam são as que enxergam ordem, não só presença. Recall@k pergunta se o trecho certo está entre os k recuperados, e o reranking não muda isso: o mesmo conjunto entra e sai, só reordenado. O que o reranking melhora são as métricas sensíveis à posição, que penalizam a resposta certa por estar lá embaixo. A avaliação precisa isolar a camada: fixando chunking, embedding e busca, você liga e desliga o reranker e mede se a posição do trecho certo melhorou. Assim você separa ganho de reranking de qualquer outra mudança no pipeline.

MétricaO que revelaEfeito do reranking
Recall@kSe o trecho certo entrou nos k recuperadosNão muda: depende da busca, não da ordem
MRRQuão perto do topo está o primeiro trecho certoSobe quando o reranker puxa a resposta para cima
nDCG@kQualidade da ordem completa, com peso na posiçãoSobe quando os relevantes ficam antes dos ruidosos
Latência p95Tempo extra que o reranking adicionaSobe: é o preço a pesar contra o ganho de ordem

A pergunta prática é: o reranking sobe o suficiente as métricas de posição para justificar a latência e o custo que adiciona? Se o MRR e o nDCG mal se mexem, o embedding já estava ordenando bem e o reranker é peso morto. Se eles saltam, o reranking está pescando de volta respostas que o pipeline estava descartando por estarem fora do topo. Medir os dois lados, ganho de ordem contra custo de latência, é o que transforma "adicionei um reranker" numa decisão de engenharia em vez de um item de checklist.

06

Quando o reranking rende e quando não vale

Reranking não é ganho universal; ele rende em situações específicas. Onde o corpus é grande e cheio de trechos parecidos, o embedding traz muitos candidatos plausíveis e a ordem fica ruim, exatamente o terreno do cross-encoder. Onde a pergunta é sutil, com uma condição ou negação que muda a resposta, o bi-encoder tende a ignorar o detalhe e o reranker, que lê pergunta e trecho juntos, o captura. Já onde o corpus é pequeno e homogêneo, ou onde a busca vetorial já devolve o trecho certo em primeiro com folga, o reranking custa latência e dinheiro para confirmar uma ordem que já estava certa.

  1. Antes de adicionar reranking, confirme o recall: se o trecho certo nem entra nos candidatos, o problema é chunking ou embedding, e o reranker não tem o que reordenar.
  2. Recupere amplo o suficiente para a resposta certa caber na peneira; recuperar estreito e reranquear estreito não resolve a ordem, só a confirma.
  3. Comece com um reranker pronto (API ou modelo local) antes de pensar em treinar; a decisão de engenharia é quantos candidatos entram e quantos saem.
  4. Meça posição, não só presença: MRR e nDCG dizem se a resposta subiu ao topo; recall sozinho não enxerga o ganho do reranking.
  5. Pese o ganho de ordem contra a latência p95 e o custo por consulta; reserve o reranking para as consultas ambíguas se o volume apertar a conta.

O reranking é uma das alavancas mais baratas de qualidade de RAG justamente porque não pede trocar o modelo de geração nem reindexar o corpus: você mantém o embedding e a base como estão e insere uma etapa de reordenação entre a busca e a montagem do contexto. Quando o sintoma é "a informação estava lá, mas a resposta veio errada", quase sempre o culpado é a ordem, e a ordem é o que o reranking conserta. É o segundo olhar que faz o trecho certo, que já tinha sido recuperado, finalmente chegar ao modelo no topo.

FAQ

Perguntas frequentes

Qual a diferença entre a busca por embedding e o reranking?

A busca por embedding usa um bi-encoder: pergunta e trecho são transformados em vetores separadamente, sem se olharem, e a busca compara distâncias entre esses vetores. É rápida porque os vetores dos trechos são pré-calculados, então serve para varrer milhões de trechos, mas comprime o significado e erra a ordem fina. O reranking usa um cross-encoder: recebe pergunta e trecho juntos na mesma entrada e produz uma pontuação de quão bem aquele trecho responde àquela pergunta específica. Ele lê a interação entre os dois, o que o embedding não faz, mas é lento porque exige uma inferência por par. Por isso o embedding faz a triagem ampla e barata, e o reranking reordena com precisão os poucos candidatos que sobraram.

Reranking melhora o recall do meu RAG?

Não. O reranking não muda quais trechos foram recuperados, só reordena os que a busca vetorial já trouxe. O mesmo conjunto entra e sai, apenas em ordem diferente. Se o trecho certo não estava entre os candidatos recuperados, o reranking não tem como pescá-lo de volta, e o problema está antes, no chunking ou no embedding. O que o reranking melhora é a posição: ele pega a resposta certa que estava recuperada mas na nona posição e a puxa para o topo, onde o contexto do modelo é montado. Por isso as métricas que mostram o ganho são as de ordem, como MRR e nDCG, e não o recall, que fica igual com ou sem reranker.

Vale a pena o custo e a latência do reranking?

Depende de quanto a ordem estava ruim. Cada candidato reranqueado é uma inferência extra, então o reranking soma latência no caminho crítico e custo por consulta. Ele vale a pena quando o corpus é grande e cheio de trechos parecidos, ou quando as perguntas têm condições e negações que o embedding ignora, situações em que a resposta certa costuma chegar recuperada mas fora do topo. Não vale quando o corpus é pequeno e homogêneo ou quando a busca já entrega o trecho certo em primeiro com folga: nesses casos o reranker só confirma uma ordem que já estava boa, pagando latência à toa. A forma de decidir é medir: se MRR e nDCG saltam ao ligar o reranking, o ganho justifica o custo; se mal se mexem, o embedding já ordenava bem.

Reranking é o segundo olhar que coloca a resposta certa no topo

A qualidade do RAG não depende só de recuperar o trecho certo, mas de entregá-lo ao modelo na ordem certa. Recuperar amplo com o embedding, reordenar com um cross-encoder e entregar estreito coloca a resposta que já estava recuperada no topo do contexto, sem trocar o modelo de geração nem reindexar o corpus. Posso desenhar essa camada de reranking no seu sistema de IA, calibrando quantos candidatos entram, quantos vão ao modelo e medindo o ganho de ordem contra a latência, para que o retrieval entregue a resposta certa inteira e na frente.