A maioria dos tutoriais de RAG termina exatamente onde a produção começa. Você divide seus documentos em chunks de 512 tokens, os envia através de um único modelo de embedding e chama um banco de dados vetorial com uma simples recuperação top-k. Em uma demonstração, isso parece convincente. Pergunte ao bot sobre a política de licença da sua empresa e ele retornará um parágrafo coerente. Todos assentem com a cabeça. Infelizmente, demos mentem.
A produção expõe cada atalho. Chunks de tamanho fixo cortam contratos jurídicos no meio de cláusulas de indenização. A documentação de API se transforma em um ruído sobreposto que abafa o sinal que você realmente precisa. A latência aumenta gradualmente até que os usuários abandonem a consulta antes que a resposta chegue. Nós batemos nesse muro e tivemos que reconstruir tudo. Nossa camada de recuperação evoluiu de uma "busca semântica e esperança" para um pipeline mensurado e instrumentado. O resultado foi 95% de recall e uma redução de 40% na latência. Aqui está o que realmente funcionou.
Ajuste a estratégia de chunking ao documento
O padrão de 512 tokens persiste porque é fácil, não porque é correto. Diferentes documentos carregam significados de formas diferentes, e sua estratégia de chunking deve refletir isso.
Para contratos jurídicos, use chunking recursivo que respeite as fronteiras estruturais. A linguagem jurídica é aninhada. Uma cláusula depende da seção acima dela, e um corte fixo no meio de uma frase destrói a lógica de uma obrigação. O chunking recursivo tenta divisões em separadores naturais primeiro — parágrafos, depois frases — antes de impor um limite de tokens. Isso mantém as cláusulas de indenização ou de responsabilidade intactas.
Para documentação de API, use chunking orientado a funções. Desenvolvedores não buscam por parágrafos aleatórios; eles buscam por endpoints, parâmetros e assinaturas de erro. Um chunk deve conter a assinatura completa da função, sua descrição e o schema de retorno como uma única unidade lógica. Se você dividir esse bloco ao meio, o sistema de recuperação retornará metade do contexto e o modelo de geração alucinará o resto.
Para tickets de suporte, confie no chunking semântico que segue os turnos de conversa. Threads de suporte são lineares e repetitivas. Um cliente repete o problema, um agente pede logs, o cliente os anexa. Cada turno é sua própria unidade semântica. O chunking por turnos preserva quem disse o quê e quando, o que é importante quando o usuário pergunta: "O que o agente sugeriu na terça-feira?"
Para wikis internas, tente o chunking agêntico. Entregue uma seção a um LLM e peça para ele decidir onde um tópico termina e outro começa. Isso custa mais no tempo de ingestão, mas wikis são bagunçadas. As páginas contêm atualizações não relacionadas de diferentes equipes, e uma fronteira definida por humanos raramente ajuda. Deixar um modelo traçar fronteiras baseadas em mudanças de tópico reduz o ruído drasticamente.
Executar múltiplas estratégias em um único pipeline exige taguear os documentos por tipo na ingestão. Esse pequeno toque de disciplina no schema compensa imediatamente.
Combine métodos de busca, não escolha apenas um
A busca vetorial entende a intenção, mas falha rotineiramente em correspondências exatas. Peça um código de erro ERR_CONNECTION_REFUSED ou um SKU específico, e embeddings densos frequentemente retornam resultados conceitualmente similares, mas factualmente errados. O BM25, o clássico método de recuperação esparsa por palavras-chave, lida muito bem com strings exatas, mas perde a nuance semântica. Você precisa de ambos.
Use recuperação híbrida. Execute a busca vetorial e o BM25 em paralelo. Em seguida, combine-os com o Reciprocal Rank Fusion (RRF). O RRF recompensa documentos nos quais ambos os métodos concordam que são relevantes, ao mesmo tempo em que traz à tona candidatos fortes de qualquer uma das abordagens. A matemática é simples e o resultado é estável: nenhum método de recuperação único domina o ranking final.
Após a fusão, adicione um reranker de cross-encoder. O primeiro estágio — busca vetorial mais esparsa — é rápido e amplo. O cross-encoder então pontua cada par consulta-documento com atenção total, o que significa que ele realmente lê o candidato em relação à pergunta original. Sim, isso adiciona latência. No nosso caso, cerca de cinquenta a cem milissegundos. Mas o ganho em precisão é tão nítido que a troca vale a pena. Você não pode se dar ao luxo de pular isso se se importa com o recall.
Corrija a consulta antes de corrigir o índice
Os usuários não escrevem consultas para o seu mecanismo de busca. Eles as escrevem para humanos. "Não funciona" é uma consulta de suporte comum. Uma descrição vaga de um recurso é uma busca comum em wikis internas. Se você pesquisar no índice com essa entrada bruta, receberá lixo de volta.
Transforme a consulta antes que ela chegue ao recuperador (retriever).
Use query expansion para gerar múltiplas versões da pergunta do usuário. Se alguém digitar “servidor fora do ar”, seu sistema também deve buscar por “serviço indisponível”, “erro 502” e “timeout de conexão”. Cobrir essas variantes de intenção aumentou nosso recall de 78% para 96%. É uma etapa única e custa quase nada comparado ao ganho.
Use query decomposition para perguntas complexas. Quando um usuário pergunta algo como “Como faço a migração da API de faturamento legada para a nova e quais breaking changes afetam contas enterprise?”, divida em subperguntas. Uma subpergunta foca nos passos de migração. Outra foca nas breaking changes específicas para enterprise. Cada uma atinge uma parte diferente do índice. O modelo de linguagem downstream sintetiza a resposta final a partir de chunks bem recuperados, em vez de tentar adivinhar em uma janela de contexto ruidosa.
Pare de Chutar Hiperparâmetros
Uma vez que você tenha múltiplas estratégias de chunking, recuperação híbrida e transformação de consulta, você enfrentará um problema combinatório. Tamanho do chunk, sobreposição (overlap), pesos de fusão, profundidade do reranker e contagem de expansão interagem entre si. Ajustar um isoladamente quebra outro. Fazer uma busca em grade (grid search) por todo esse espaço é um desperdício de tempo e recursos.
Use otimização bayesiana em vez disso. Trate isso como uma tarefa de ajuste (tuning) de machine learning. Defina seu objetivo claramente: maximizar o recall mantendo a latência abaixo de um limite. Construa um golden dataset — algumas centenas de perguntas representativas onde você sabe precisamente quais chunks devem ser recuperados. Então, deixe a busca bayesiana explorar o espaço de configuração de forma eficiente. Ela constrói um modelo probabilístico do que funciona e testa as regiões mais promissoras em seguida.
Cada configuração candidata deve passar pelo golden dataset antes de chegar ao staging. Se um novo tamanho de chunk reduzir o recall ou um reranker mais pesado ultrapassar o limite de latência, a otimização detectará isso automaticamente. Isso remove a subjetividade da discussão. Você para de debater se 256 ou 512 tokens é “melhor” e começa a ler os resultados.
O Resultado
As mudanças no pipeline se acumularam exatamente como esperávamos.
- Recall@10 subiu de 78% para 95%.
- Latência P95 caiu de 850 ms para 320 ms.
- Taxa de alucinação caiu de 12% para 3%.
- Custo por consulta caiu 38%, em grande parte porque uma melhor recuperação nos permitiu usar um modelo de geração menor e menos tokens de prompt.
A redução da latência surpreendeu algumas pessoas da equipe. Adicionar rerankers e query expansion parece algo que deveria deixar as coisas mais lentas. Mas, como a qualidade da recuperação melhorou, o modelo de geração precisou de menos prompting, menos especulação e menos tentativas. Uma boa recuperação torna tudo o que vem depois mais barato.
Trate a Recuperação como Infraestrutura
A recuperação não é um notebook que você executa uma vez e esquece. É infraestrutura e deve ser gerenciada como código. Versionar suas estratégias de chunking. Quando a equipe jurídica lançar um novo modelo de contrato, teste seu splitter recursivo antes que ele chegue à produção. Mantenha seu golden dataset como documentos vivos, não como um CSV estático do último trimestre. Automatize suas avaliações no CI para que um pull request que modifique um modelo de embedding ou um peso de fusão receba um comentário com os números de recall e latência antes mesmo de um humano revisá-lo.
Seus usuários nunca perguntarão qual modelo de embedding você utiliza. Eles não se importarão com sua heurística de chunking ou com sua arquitetura de reranker. Eles se importam se a resposta está correta, se chega rápido e se podem confiar nela. Construa um pipeline que conquiste essa confiança, meça-o honestamente e pare de tratar a recuperação como algo secundário.
Fonte: Optimizing RAG At Scale
Participe da discussão: GyaanSetu AI Community
