RAG no Claude Code: quando vale a pena e quando é perda de tempo

·

Essa pergunta aparece toda semana em grupo de dev: “vale a pena montar um RAG pro Claude Code?”. A resposta curta é não, na maioria dos casos — mas o motivo pelo qual as pessoas perguntam é mais interessante que a resposta.

A pergunta carrega duas confusões. A primeira é sobre o que “harness” significa. A segunda é achar que o Claude Code não faz retrieval — ele faz, o dia inteiro, só não do jeito que você está imaginando. Este artigo desfaz as duas, mostra os três casos em que RAG realmente compensa, e termina com a ordem do que dá ganho de verdade.

Existem dois “harness”, e eles não são a mesma coisa

Quando você pesquisa “harness”, encontra a definição clássica de engenharia de software: test harness. É o aparato que roda seu código automaticamente — a suíte de testes, o runner, o ambiente isolado. Isso existe desde muito antes de LLM.

Mas no jargão de agentes de código, agent harness é outra coisa. É todo o arcabouço que envolve o modelo: o loop de agente, o conjunto de ferramentas que ele pode chamar (ler arquivo, editar, rodar comando, buscar), o gerenciamento de contexto, o sistema de permissões, os subagentes e os hooks.

O Claude Code é o harness.

Por isso a pergunta “compensa usar harness no Claude Code?” não fecha. Você não adiciona um harness — você já está dentro de um. O que você adiciona é o loop de verificação: testes rápidos, lint, checagem de tipos. Coisas que o harness consegue executar e cujo resultado ele consegue ler. E isso compensa mais que qualquer outro item desta lista.

O Claude Code já faz retrieval — chama-se agentic search

Segunda confusão. As pessoas dizem “o Claude Code não usa RAG”. Isso é impreciso.

Olha o que ele faz quando você pede uma alteração: busca com grep, lista arquivos, lê os trechos relevantes, decide o que ler em seguida. Isso é retrieval augmented generation. É RAG. Só que o retriever não é um índice vetorial — é busca léxica mais o próprio modelo decidindo onde olhar. O nome disso é agentic search.

RAG vetorialAgentic search
Índice construído antesBusca feita no momento
Recupera chunks de ~512 tokensLê o arquivo real, com o contexto em volta
Similaridade aproximadaCorrespondência exata mais julgamento
O índice desatualizaSempre vê o estado atual do disco

A vantagem real não é “não ter RAG”. É que o retrieval fica just-in-time e verificável: o agente vê o arquivo de verdade, com as importações e o contexto em volta — não um pedaço picado no meio de uma função.

E tem um detalhe que quase ninguém menciona: o índice vetorial fica velho. Você edita o código e o índice continua descrevendo o que existia ontem. O grep não tem esse problema.

Onde RAG realmente compensa: os três casos

Sendo honesto: existe lugar onde RAG ganha. E não é “monorepo gigante”, que é a resposta que todo mundo dá.

1. Informação que não está no repositório

Jira, Notion, Confluence, a wiki interna. O agente não tem como dar grep nisso. Aqui a ponte é MCP: um servidor MCP expondo essa base é, na prática, RAG empacotado como ferramenta.

2. Memória entre sessões

Esse é o caso onde busca semântica realmente ganha da léxica — porque você não lembra o nome exato do que gravou há três semanas, você lembra do assunto. Grep exige que você acerte a palavra; embedding não.

3. Documentação mais nova que o corte de conhecimento do modelo

Framework que mudou a API depois do treinamento. Aí você precisa alimentar a doc atual de alguma forma.

Repara no padrão: os três casos são coisas fora do repositório. Dentro do repositório, o grep ganha.

O erro que quase todo CLAUDE.md comete

Agora a parte prática — e o motivo pelo qual quem pergunta sobre RAG normalmente tem outro problema. Um CLAUDE.md típico, bonito e organizado, costuma ter dois defeitos graves.

Problema um. A seção “Regras de segurança”: “não crie commits direto na main”, “não rode db:drop sem autorização”. Isso é texto num prompt. É um pedido. O modelo lê, normalmente respeita — e num dia ruim, não respeita.

Se o seu controle contra apagar o banco de produção é uma frase em markdown, você não tem controle: você tem esperança. O que garante isso é um hook. O hook não é lido pelo modelo — ele intercepta a chamada da ferramenta e devolve “bloqueado”. Não há negociação: a chamada simplesmente não acontece.

Markdown é sugestão. Hook é garantia.

Problema dois. O arquivo inteiro fica no contexto, toda hora, em toda tarefa. Você paga pela seção de arquitetura mesmo quando pediu para corrigir um typo no README. Para conteúdo que só vale às vezes existe Skill: uma pasta com um SKILL.md, onde só o nome e a descrição ficam no contexto e o corpo carrega quando a tarefa é sobre aquilo.

Três destinos para o seu CLAUDE.md

  • Fica no CLAUDE.md o que é verdade em toda tarefa: comandos, mapa de pastas, convenções de código. Tem que caber numa tela.
  • Vira Skill a arquitetura detalhada. A descrição é o que decide se o arquivo carrega — vale escrever bem: “use ao criar um módulo novo, mover código entre camadas, ou revisar se uma dependência é permitida”.
  • Vira hook o que é inegociável.

No exemplo do vídeo são dois hooks. O primeiro é PreToolUse, roda antes de cada comando de terminal: recebe o evento em JSON no stdin e o contrato é simples — sai com 0, libera; sai com 2, bloqueia e devolve o texto do stderr para o Claude ler. Ele barra db:drop, barra push --force, barra --no-verify, e checa a branch atual: se for main, master ou develop, não deixa commitar.

echo '{"tool_name":"Bash","tool_input":{"command":"npm run db:drop"}}' | node .claude/hooks/guard.mjs
# exit=2 → bloqueado

Repara: isso é testável fora do Claude Code. É só um script que lê stdin.

O segundo é PostToolUse, roda depois de cada edição: formata o arquivo e roda o lint. Se o lint reclamar, sai com 2, e o Claude recebe a saída do erro e corrige sozinho. Esse é o loop de verificação do começo do artigo, automatizado — o agente não precisa lembrar de rodar o lint. O lint roda nele.

Uma ressalva honesta: hook não é sandbox. Ele cobre a ferramenta que você mapeou no matcher e a regra que você escreveu. Um comando destrutivo escrito de um jeito que a regex não pega, passa. É uma trava boa, não uma garantia absoluta.

A ordem que importa

  1. Loop de verificação rápido. Se o teste demora quatro segundos, o agente valida o próprio trabalho e conserta antes de te entregar. Se demora quatro minutos, ele entrega no escuro. É o maior ganho isolado, e não tem nada a ver com prompt.
  2. Contexto determinístico. CLAUDE.md enxuto com comandos e convenções; Skills para o resto.
  3. Hooks para o que não pode depender da boa vontade do modelo.
  4. E só então RAG — para o que está fora do repositório.

Não é “RAG contra harness”. RAG é o quarto item de uma lista onde a maioria das pessoas nunca fez o primeiro.

Código e próximos passos

Os arquivos do exemplo — CLAUDE.md refatorado, a Skill de arquitetura e os dois hooks — estão em github.com/victorsantosbhz/claude-code-exemplos, na pasta rag-vs-harness.

Se o assunto que te interessou foi memória entre sessões, o caso 2 da lista, o vídeo sobre o Engram mostra isso funcionando. Se foi a parte dos hooks, tem um vídeo só sobre isso na playlist Ferramentas de IA.


CONTINUE PELO CANAL

Todo artigo daqui nasce de um vídeo. A série completa está na playlist Ferramentas de IA, e o código de cada um fica no monorepo da série.

Uma resposta para “RAG no Claude Code: quando vale a pena e quando é perda de tempo”

  1. […] O passo seguinte natural é combinar o grafo com memória persistente, para que os achados de uma sessão não se percam na próxima — é sobre isso o artigo do Engram. E se a sua dúvida era se valia a pena montar um RAG para o seu código, a resposta está em RAG no Claude Code: quando vale a pena. […]

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *