
Por que a Busca de Similaridade Ingênua Destruirá Seu Agente RAG (E O Que Fazer em Vez Disso)
Por Que a Busca de Similaridade Ingênua Destruirá Seu Agente RAG (E O Que Fazer em Vez Disso)
A maioria das implementações de RAG que vejo em produção usa busca de similaridade ingênua: incorpora a consulta, encontra os vetores mais próximos, os coloca no contexto, gera. Funciona em demonstrações. Falha na produção.
Veja por que – e aqui está o padrão que eu adotei após rodar agentes autônomos 24/7.
O Problema Com RAG Ingênuo
Considere o que a similaridade cosseno realmente mede: ela encontra pedaços cuja direção de incorporação é similar à direção de incorporação da sua consulta. Isso soa bem até você perceber:
Desajustes de palavras-chave. Se um usuário pergunta "qual é nossa política de reembolso?" mas seus documentos dizem "política de devolução," a similaridade cosseno pode classificar um documento completamente irrelevante sobre "atualizações de política" mais alto porque aconteceu de compartilhar tokens comuns no espaço de incorporação.
Sem diversidade. Você pode facilmente obter 5 pedaços quase idênticos da mesma seção do documento – todos pontuando 0.87 – quando você precisava de 5 diferentes perspectivas sobre o tópico.
Sem ponderação de frescor. Um documento de política de 2 anos atrás e um de semana passada classificam-se igualmente.
Alucinação silenciosa. Quando a recuperação retorna resultados de baixa qualidade, o LLM não diz "não consegui encontrar isso" – ele alucina. E você não saberá até que alguém reclame.
A pior parte: suas avaliações provavelmente parecem boas. RAGAS pode pontuar 0.8 em seu conjunto de testes. Então a produção chega e os casos extremos te matam.
O Padrão Que Realmente Funciona
Aqui está o que eu uso para agentes de produção. Você não precisa de tudo – comece com busca híbrida, adicione o resto conforme seu uso cresce.
Nível 1: Busca Híbrida (Densa + Espessa)
Isso é inegociável para qualquer sistema de produção. Vetores densos capturam similaridade semântica; BM25 captura correspondências exatas de palavras-chave. Nenhum deles sozinho é suficiente.
A combinação via Fusão de Classificação Recíproca (RRF):
def hybrid_retrieve(query, k=10, final_k=5, rrf_k=60):
query_vec = embed(query)
dense_results = vector_store.similarity_search(query_vec, k=k)
sparse_results = bm25_index.search(query, k=k)
scores = {}
for rank, result in enumerate(dense_results):
scores.setdefault(result['id'], {'data': result, 'rrf': 0})
scores[result['id']]['rrf'] += 0.7 * (1.0 / (rrf_k + rank + 1))
for rank, result in enumerate(sparse_results):
scores.setdefault(result['id'], {'data': result, 'rrf': 0})
scores[result['id']]['rrf'] += 0.3 * (1.0 / (rrf_k + rank + 1))
ranked = sorted(scores.values(), key=lambda x: x['rrf'], reverse=True)
return ranked[:final_k]
A divisão 70/30 densa/espessa funciona bem para a maioria dos domínios. Ajuste para espessa (40/60) para conteúdo técnico com terminologia exata, como códigos de produtos ou nomes de APIs.
Nível 2: Compressão Contextual
Uma vez que você recupera seus pedaços, não apenas coloque todos eles no contexto. Peça ao LLM para extrair apenas as partes relevantes:
def compress_chunk(query, chunks):
pass
Empresas brasileiras que utilizam agentes autônomos podem enfrentar problemas com a busca de similaridade ingênua, resultando em respostas imprecisas. A implementação de uma busca híbrida pode melhorar a relevância e a precisão das informações retornadas, aumentando a satisfação do cliente.

