Retrieval
Retrieval é onde a busca vira resposta: dense, sparse, híbrido e reranking decidem se o contexto que chega no LLM é útil ou se é lixo disfarçado de evidência.
O que é
Retrieval é o passo que decide quais trechos da base viram contexto para o LLM. Em RAG, é a etapa onde a maior parte da qualidade se ganha ou se perde: contexto bom vira resposta boa, contexto errado vira resposta errada, mesmo com prompt perfeito e modelo excelente. Retrieval ruim não tem conserto depois.
Um sistema de retrieval tem três decisões: qual algoritmo usar (denso, esparso, híbrido), como rerankear o resultado bruto, e como fundir listas vindas de algoritmos diferentes. As três decisões dependem do tipo de pergunta e do tipo de corpus.
Dense, sparse e híbrido
Busca densa usa embeddings: a pergunta vira vetor, o corpus vira vetor, a similaridade é geométrica. É boa para paráfrases, perguntas conceituais e termos não técnicos. É fraca para siglas raras, identificadores, e termos literais que existem no documento mas não no vocabulário do modelo.
Busca esparsa usa frequência de termos ( é o padrão da prática). É boa para palavras exatas, nomes próprios e siglas. É fraca para paráfrases e consultas que misturam termos. BM25 pontua cada termo pelo TF (quantas vezes aparece no documento) e pelo IDF (quão raro é no corpus), e normaliza pelo tamanho do documento. O resultado é uma lista ranqueada por relevância lexical.
Busca híbrida roda as duas em paralelo, e funde as listas. O método de fusão mais comum é o RRF (Reciprocal Rank Fusion): cada lista atribui 1/(k + rank) a cada candidato, e os candidatos são reordenados pela soma. O resultado herda o melhor das duas buscas.
Reranking
Depois do top-fusão, ainda sobra ruído. O reranker entra para reordenar o top-N com um modelo que olha a pergunta e o candidato juntos. Cohere Rerank, BGE Reranker e ColBERT fazem isso por um modelo de linguagem menor que pontua cada par (pergunta, documento) com mais qualidade que .
O custo é proporcional ao número de candidatos rerankeados, então a lista de entrada é tipicamente 50 a 200 itens. O custo em latência fica dentro do orçamento porque reranker é menor e mais barato do que o LLM final.
Na prática
O exemplo junta dense retrieval (Qdrant), BM25 (Pyserini) e reranker Cross-Encoder em um único pipeline. A fusão é RRF, e o reranker corta os 50 melhores para os 5 finais.
from typing import Iterable
from qdrant_client import QdrantClient
from pyserini.search.lucene import LuceneSearcher
from sentence_transformers import CrossEncoder
qdrant = QdrantClient(url="http://localhost:6333")
searcher = LuceneSearcher.from_prebuilt_index("manual_pt")
reranker = CrossEncoder("cross-encoder/mmarco-mMiniLMv2-L12-H384-v1")
def rrf(ranks: Iterable[list[str]], k: int = 60) -> list[tuple[str, float]]:
scores: dict[str, float] = {}
for r in ranks:
for i, doc_id in enumerate(r):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + i + 1)
return sorted(scores.items(), key=lambda x: x[1], reverse=True)
def retrieve(query: str, embedding: list[float], top_k: int = 5):
# 1. dense (Qdrant, top 50)
dense_hits = qdrant.search(
collection_name="chunks",
query_vector=embedding,
limit=50,
with_payload=False,
)
dense_ids = [str(h.id) for h in dense_hits]
# 2. sparse (BM25, top 50)
bm25_hits = searcher.search(query, k=50)
bm25_ids = [h.docid for h in bm25_hits]
# 3. fusão RRF
fused = rrf([dense_ids, bm25_ids])
# 4. rerank dos 50 candidatos
candidates = [(doc_id, lookup_text(doc_id)) for doc_id, _ in fused[:50]]
pairs = [(query, text) for _, text in candidates]
scores = reranker.predict(pairs)
ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)
return [doc_id for (doc_id, _), _ in ranked[:top_k]]Pontos fortes
- cobertura dupla: híbrido cobre tanto paráfrase (densa) quanto termo exato (BM25), então os dois pontos cegos são mitigados
- reranqueação do top-N entrega expansão: o reranker pequeno filtra o que passou, então o LLM só vê o que realmente importa
- custo amortizado: rerank em top-50 sai barato, e o resto da lista bruta nem chega a ser processada
Limitações
- complexidade operacional: três subsistemas (vetor, BM25, reranker) precisam estar saudáveis juntos; um falha, o cluster cai
- fusão é heurística: RRF não aprende fusão ótima, e o k=60 padrão não é universal; tuning é trabalho de produção
- reranqueador vira tema único: o reranker atualiza por modelo, então tarefa de ver se um modelo novo bate o anterior é regressão obrigatória
conexões no mapa
- Vector DBconsultaRetrieval
- Retrievalalimenta contextoRAG - retrieval-augmented generation
atualizado em 14/10/2026 · fontes para aprofundar · reportar erro
Estude antes
Desbloqueia
teste o que entendeu
Carregando perguntas…