{"slug": "quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada", "title": "Quando o RAG erra, quase nunca é o LLM: 4 falhas de recuperação e como logar cada uma", "summary": "A developer explains that most RAG failures are not caused by the LLM but by retrieval issues, and shares four common failure types along with logging strategies. The developer recommends hybrid search and rerankers over embedding swaps, and emphasizes logging retrieval scores before tuning the pipeline.", "body_md": "Todo problema de RAG parece problema do modelo. Quase nunca é.\n\nDemorei pra aceitar isso. Ficava trocando modelo de embedding, mexendo no prompt, achando que o Claude tava inventando coisa. O que estava quebrado era o que eu entregava pra ele, e só ficou óbvio quando comecei a logar o que voltava da recuperação.\n\nDepois que instrumentei, os erros se separaram em quatro tipos bem diferentes.\n\nA pergunta simplesmente não tem resposta na base. Quase ninguém checa. Um piso resolve:\n\n```\nq_emb = vo.embed([question], model=\"voyage-3.5\", input_type=\"query\").embeddings[0]\n\ncur.execute(\n    \"SELECT content, 1 - (embedding <=> %s) AS score \"\n    \"FROM documents ORDER BY embedding <=> %s LIMIT %s\",\n    (q_emb, q_emb, top_k)\n)\nrows = cur.fetchall()\n\nif not rows or rows[0][1] < 0.7:\n    return \"Não tenho essa informação na base.\"\n```\n\nFeio, mas corta a maior parte das respostas inventadas com cara de certeza. O 0.7 não é sagrado: é o ponto onde, na minha base, o chunk deixava de ter relação com a pergunta. Loga o score por uma semana e você acha o teu.\n\n\"como resetar senha\" trazendo \"como resetar produto\". Vetorialmente colado, na prática inútil.\n\nEsse foi o que mais me irritou, porque parece bug do modelo e não é: busca vetorial pura não separa as duas coisas. Os dois chunks falam de resetar algo, com estrutura de frase quase idêntica, e a diferença inteira mora numa palavra que o vetor dilui.\n\nHybrid search (vetor + BM25) rendeu mais aqui do que qualquer troca de embedding que eu tinha tentado antes, porque o BM25 dá peso ao token literal \"senha\" — justamente o que o vetor perdeu. Reranker com cross-encoder na frente ataca o mesmo problema por outro lado.\n\nO retrieval acertou e o modelo extrapolou mesmo assim. Isso é instrução, não recuperação: o system prompt precisa proibir na cara dura e pedir citação do trecho.\n\n```\nSYSTEM = (\n    \"Responda APENAS com base no contexto fornecido. \"\n    \"Cite o trecho que embasa cada afirmação. \"\n    \"Se a resposta não estiver no contexto, diga que não sabe.\"\n)\n```\n\nÓbvio depois de escrito. Passei semanas culpando o retrieval por isso.\n\nTabela partida, bloco de código sem fechamento. Chunking por contagem de token faz isso o tempo todo:\n\n``` python\ndef chunk_text(text, size=500, overlap=50):\n    words = text.split()\n    return [\" \".join(words[i:i + size])\n            for i in range(0, len(words), size - overlap)]\n```\n\nFunciona pra prosa corrida e destrói documentação técnica. E o estrago é silencioso: o modelo responde bonito em cima de um pedaço mutilado, sem sinal nenhum de que faltou metade da tabela. Respeitar a estrutura do documento (header de markdown, seção do PDF) dá mais trabalho pra escrever e se paga na primeira semana.\n\nSe fosse começar de novo, a primeira coisa que eu escreveria não era o pipeline, era o log. Score de cada chunk, quais entraram, tamanho de cada um. Sem isso você fica trocando peça no escuro, e trocar modelo de embedding é caro, demorado e quase nunca era o problema.\n\nEscrevi o passo a passo completo no blog, com o pipeline em Python usando pgvector, Voyage e Claude, as 4 estratégias de chunking e a comparação com fine-tuning: [https://www.techknow.com.br/post/o-que-e-rag](https://www.techknow.com.br/post/o-que-e-rag)\n\nQuem já tem isso em produção: o ganho maior veio de mexer no chunking ou de botar um reranker na frente?", "url": "https://wpnews.pro/news/quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada", "canonical_source": "https://dev.to/wildrik/quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada-uma-3ljm", "published_at": "2026-08-15 02:09:44+00:00", "updated_at": "2026-08-15 02:41:48.816022+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-products", "developer-tools"], "entities": ["Voyage", "Claude", "pgvector", "BM25", "techknow.com.br"], "alternates": {"html": "https://wpnews.pro/news/quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada", "markdown": "https://wpnews.pro/news/quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada.md", "text": "https://wpnews.pro/news/quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada.txt", "jsonld": "https://wpnews.pro/news/quando-o-rag-erra-quase-nunca-e-o-llm-4-falhas-de-recuperacao-e-como-logar-cada.jsonld"}}