Por que sou contra a recuperação apenas por grep do Claude Code? Ela simplesmente consome tokens demais
Os assistentes de programação com IA estão explodindo. Em apenas dois anos, ferramentas como Cursor, Claude Code, Gemini CLI e Qwen Code passaram de curiosidades a companheiros do dia a dia para milhões de desenvolvedores. Mas por trás dessa ascensão rápida há uma disputa se formando sobre algo enganosamente simples: como um assistente de programação com IA deve de fato pesquisar contexto na sua base de código?
No momento, há duas abordagens:
RAG com busca vetorial (recuperação semântica).
Busca por palavras-chave com grep (correspondência literal de strings).
Claude Code e Gemini escolheram a segunda. Na verdade, um engenheiro da Claude admitiu abertamente no Hacker News que o Claude Code não usa RAG de forma alguma. Em vez disso, ele simplesmente faz grep no seu repositório linha por linha (o que eles chamam de “busca agêntica”)—sem semântica, sem estrutura, apenas correspondência bruta de strings.
Essa revelação dividiu a comunidade:
Apoiadores defendem a simplicidade do grep. É rápido, exato e—mais importante—previsível. Com programação, argumentam, precisão é tudo, e os embeddings de hoje ainda são difusos demais para se confiar.
Críticos veem o grep como um beco sem saída. Ele afoga você em correspondências irrelevantes, consome tokens e trava seu fluxo de trabalho. Sem compreensão semântica, é como pedir à sua IA para depurar de olhos vendados.
Ambos os lados têm razão. E depois de construir e testar minha própria solução, posso dizer isto: a abordagem RAG baseada em busca vetorial muda o jogo. Ela não só torna a busca dramaticamente mais rápida e mais precisa, como também reduz o uso de tokens em 40% ou mais. (Pule para a parte Claude Context para ver minha abordagem)
Então, por que o grep é tão limitante? E como a busca vetorial pode realmente entregar melhores resultados na prática? Vamos analisar.
O que há de errado com a busca de código somente com grep do Claude Code?
Deparei-me com esse problema ao depurar uma questão espinhosa. O Claude Code disparou consultas grep por todo o meu repositório, despejando enormes blocos de texto irrelevante de volta para mim. Um minuto depois, eu ainda não tinha encontrado o arquivo relevante. Cinco minutos depois, finalmente tinha as 10 linhas certas—mas elas tinham sido enterradas em 500 linhas de ruído.
Isso não é um caso isolado. Uma olhada nas issues do GitHub do Claude Code mostra muitos desenvolvedores frustrados batendo na mesma parede:
issue1: https://github.com/anthropics/claude-code/issues/1315
issue2: https://github.com/anthropics/claude-code/issues/4556
A frustração da comunidade se resume a três pontos críticos:
Inchaço de tokens. Cada despejo de grep enfia quantidades enormes de código irrelevante no LLM, elevando custos que escalam de forma terrível com o tamanho do repositório.
Custo de tempo. Você fica preso esperando enquanto a IA brinca de vinte perguntas com sua base de código, matando o foco e o fluxo.
Contexto zero. Grep corresponde strings literais. Ele não tem noção de significado nem de relações, então você está efetivamente pesquisando às cegas.
É por isso que o debate importa: grep não é apenas “old school”, ele está ativamente atrasando a programação assistida por IA.
Claude Code vs Cursor: por que o segundo tem melhor contexto de código
Quando se trata de contexto de código, o Cursor fez um trabalho melhor. Desde o primeiro dia, o Cursor apostou em indexação de base de código: dividir seu repositório em chunks significativos, incorporar esses chunks em vetores e recuperá-los semanticamente sempre que a IA precisar de contexto. Isso é Retrieval-Augmented Generation (RAG) clássico aplicado ao código, e os resultados falam por si: contexto mais enxuto, menos tokens desperdiçados e recuperação mais rápida.
Claude Code, por outro lado, apostou ainda mais na simplicidade. Sem índices, sem embeddings—apenas grep. Isso significa que toda busca é uma correspondência literal de strings, sem compreensão de estrutura ou semântica. Em teoria, é rápido, mas, na prática, os desenvolvedores muitas vezes acabam vasculhando montes de correspondências irrelevantes antes de encontrar a agulha de que realmente precisam.
| Claude Code | Cursor | |
|---|---|---|
| Precisão da Busca | Exibe apenas correspondências exatas—perde qualquer coisa nomeada de forma diferente. | Encontra código semanticamente relevante mesmo quando as palavras-chave não correspondem exatamente. |
| Eficiência | Grep despeja enormes blocos de código no modelo, aumentando os custos de tokens. | Trechos menores e com maior sinal reduzem a carga de tokens em 30–40%. |
| Escalabilidade | Executa grep novamente no repositório a cada vez, o que fica mais lento à medida que os projetos crescem. | Indexa uma vez e depois recupera em escala com atraso mínimo. |
| Filosofia | Manter o mínimo—sem infraestrutura extra. | Indexar tudo, recuperar de forma inteligente. |
Então, por que Claude (ou Gemini, ou Cline) ainda não seguiu o exemplo do Cursor? As razões são em parte técnicas e em parte culturais. A recuperação vetorial não é trivial—é preciso resolver chunking, atualizações incrementais e indexação em larga escala. Mas, mais importante, Claude Code é construído em torno do minimalismo: sem servidores, sem índices, apenas uma CLI limpa. Embeddings e bancos de dados vetoriais não se encaixam nessa filosofia de design.
Essa simplicidade é atraente—mas também limita o teto do que Claude Code pode entregar. A disposição do Cursor em investir em infraestrutura real de indexação é o motivo pelo qual ele parece mais poderoso hoje.
Claude Context: um Projeto Open-Source para Adicionar Busca Semântica de Código ao Claude Code
Claude Code é uma ferramenta forte—mas tem contexto de código ruim. Cursor resolveu isso com indexação de codebase, mas Cursor é closed-source, preso a assinaturas e caro para indivíduos ou equipes pequenas.
Essa lacuna é o motivo pelo qual começamos a construir nossa própria solução open-source: Claude Context.
Claude Context é um plugin MCP open-source que traz busca semântica de código para Claude Code (e qualquer outro agente de codificação de IA que fale MCP). Em vez de forçar brutalmente seu repositório com grep, ele integra bancos de dados vetoriais com modelos de embedding para dar aos LLMs contexto profundo e direcionado de todo o seu codebase. O resultado: recuperação mais precisa, menos desperdício de tokens e uma experiência de desenvolvedor muito melhor.
Veja como o construímos:
Tecnologias que Usamos
🔌 Camada de Interface: MCP como o Conector Universal
Queríamos que isso funcionasse em todos os lugares—não apenas no Claude. MCP (Model Context Protocol) age como o padrão USB para LLMs, permitindo que ferramentas externas se conectem perfeitamente. Ao empacotar Claude Context como um servidor MCP, ele funciona não apenas com Claude Code, mas também com Gemini CLI, Qwen Code, Cline e até Cursor.
🗄️ Banco de Dados Vetorial: Zilliz Cloud
Para a espinha dorsal, escolhemos Zilliz Cloud (um serviço totalmente gerenciado construído sobre Milvus). Ele é de alto desempenho, cloud-native, elástico e projetado para cargas de trabalho de IA como indexação de codebase. Isso significa recuperação de baixa latência, escala quase infinita e confiabilidade sólida.
🧩 Modelos de Embedding: Flexíveis por DesignEquipes diferentes têm necessidades diferentes, então Claude Context oferece suporte nativo a vários provedores de embedding:
OpenAI embeddings para estabilidade e ampla adoção.
Voyage embeddings para desempenho especializado em código.
Ollama para implantações locais com privacidade em primeiro lugar.
Modelos adicionais podem ser encaixados conforme os requisitos evoluem.
💻 Escolha da Linguagem: TypeScript
Debatemos Python vs. TypeScript. TypeScript venceu — não apenas pela compatibilidade no nível da aplicação (plugins do VSCode, ferramentas web), mas também porque o Claude Code e o Gemini CLI são, eles próprios, baseados em TypeScript. Isso torna a integração fluida e mantém o ecossistema coerente.
Arquitetura do Sistema
O Claude Context segue um design limpo e em camadas:
Módulos principais lidam com o trabalho pesado: análise de código, fragmentação, indexação, recuperação e sincronização.
Interface do usuário lida com integrações — servidores MCP, plugins do VSCode ou outros adaptadores.
Essa separação mantém o mecanismo principal reutilizável em diferentes ambientes, ao mesmo tempo em que permite que as integrações evoluam rapidamente à medida que novos assistentes de codificação com IA surgem.
Implementação dos Módulos Principais
Os módulos principais formam a base de todo o sistema. Eles abstraem bancos de dados vetoriais, modelos de embedding e outros componentes em módulos componíveis que criam um objeto Context, permitindo diferentes bancos de dados vetoriais e modelos de embedding para diferentes cenários.
import { Context, MilvusVectorDatabase, OpenAIEmbedding } from '@zilliz/claude-context-core';
// Initialize embedding provider
const embedding = new OpenAIEmbedding(...);
// Initialize vector database
const vectorDatabase = new MilvusVectorDatabase(...);
// Create context instance
const context = new Context({embedding, vectorDatabase});
// Index your codebase with progress tracking
const stats = await context.indexCodebase('./your-project');
// Perform semantic search
const results = await context.semanticSearch('./your-project', 'vector database operations');
Resolvendo os Principais Desafios Técnicos
Construir o Claude Context não foi apenas uma questão de conectar embeddings e um banco de dados vetorial. O trabalho real veio ao resolver os problemas difíceis que podem viabilizar ou comprometer a indexação de código em escala. Veja como abordamos os três maiores desafios:
Desafio 1: Fragmentação Inteligente de Código
O código não pode simplesmente ser dividido por linhas ou caracteres. Isso cria fragmentos confusos e incompletos e remove a lógica que torna o código compreensível.
Resolvemos isso com duas estratégias complementares:
Fragmentação Baseada em AST (Estratégia Principal)
Esta é a abordagem padrão, usando parsers tree-sitter para entender a estrutura sintática do código e dividir ao longo de limites semânticos: funções, classes, métodos. Isso oferece:
Completude sintática – sem funções cortadas ou declarações quebradas.
Coerência lógica – a lógica relacionada permanece junta para uma melhor recuperação semântica.
Suporte a múltiplas linguagens – funciona em JS, Python, Java, Go e mais por meio das gramáticas do tree-sitter.
Divisão de Texto do LangChain (Estratégia de Fallback)
Para linguagens que a AST não consegue analisar ou quando a análise falha, o RecursiveCharacterTextSplitter do LangChain fornece uma alternativa confiável.
// Use recursive character splitting to maintain code structure
const splitter = RecursiveCharacterTextSplitter.fromLanguage(language, {
chunkSize: 1000,
chunkOverlap: 200,
});
É menos “inteligente” do que a AST, mas altamente confiável — garantindo que os desenvolvedores nunca fiquem desamparados. Juntas, essas duas estratégias equilibram riqueza semântica com aplicabilidade universal.
Desafio 2: Lidar com Alterações no Código de Forma Eficiente
Gerenciar alterações no código representa um dos maiores desafios em sistemas de indexação de código. Reindexar projetos inteiros por pequenas modificações em arquivos seria completamente impraticável.
Para resolver esse problema, criamos o mecanismo de sincronização baseado em Merkle Tree.
Merkle Trees: A Base da Detecção de Alterações
Merkle Trees criam um sistema hierárquico de "impressões digitais" em que cada arquivo tem seu próprio hash de impressão digital, pastas têm impressões digitais com base em seu conteúdo, e tudo culmina em uma impressão digital única do nó raiz para toda a base de código.
Quando o conteúdo do arquivo muda, as impressões digitais de hash se propagam para cima por cada camada até o nó raiz. Isso permite a detecção rápida de alterações comparando impressões digitais de hash camada por camada a partir da raiz para baixo, identificando e localizando rapidamente modificações em arquivos sem reindexação completa do projeto.
O sistema realiza verificações de sincronização por handshake a cada 5 minutos usando um processo simplificado de três fases:
Fase 1: Detecção Ultrarrápida calcula o hash raiz Merkle de toda a base de código e o compara com o snapshot anterior. Hashes raiz idênticos significam que nenhuma alteração ocorreu — o sistema ignora todo o processamento em milissegundos.
Fase 2: Comparação Precisa é acionada quando os hashes raiz diferem, realizando uma análise detalhada em nível de arquivo para identificar exatamente quais arquivos foram adicionados, excluídos ou modificados.
Fase 3: Atualizações Incrementais recalcula vetores apenas para arquivos alterados e atualiza o banco de dados vetorial de acordo, maximizando a eficiência.
Gerenciamento de Snapshot Local
Todo o estado de sincronização persiste localmente no diretório ~/.context/merkle/ do usuário. Cada base de código mantém seu próprio arquivo de snapshot independente contendo tabelas de hash de arquivos e dados serializados da árvore Merkle, garantindo recuperação precisa do estado mesmo após reinicializações do programa.
Este design oferece benefícios óbvios: a maioria das verificações é concluída em milissegundos quando não há alterações, apenas arquivos genuinamente modificados acionam reprocessamento (evitando desperdício computacional massivo), e a recuperação de estado funciona perfeitamente entre sessões do programa.
Da perspectiva da experiência do usuário, modificar uma única função aciona a reindexação apenas desse arquivo, não de todo o projeto, melhorando drasticamente a eficiência do desenvolvimento.
Desafio 3: Projetando a Interface MCP
Mesmo o mecanismo de indexação mais inteligente é inútil sem uma interface limpa voltada para desenvolvedores. MCP era a escolha óbvia, mas introduziu desafios únicos:
🔹 Design de Ferramentas: Mantenha Simples
O módulo MCP serve como a interface voltada para o usuário, tornando a experiência do usuário a principal prioridade.
O design de ferramentas começa abstraindo operações padrão de indexação e busca de bases de código em duas ferramentas principais: index_codebase para indexar bases de código e search_code para pesquisar código.
Isso levanta uma pergunta importante: quais ferramentas adicionais são necessárias?
A quantidade de ferramentas requer um equilíbrio cuidadoso — ferramentas demais criam sobrecarga cognitiva e confundem a seleção de ferramentas pelo LLM, enquanto ferramentas de menos podem deixar de cobrir funcionalidades essenciais.
Trabalhar de trás para frente a partir de casos de uso do mundo real ajuda a responder a essa pergunta.
Enfrentando Desafios de Processamento em Segundo Plano
Bases de código grandes podem levar um tempo considerável para indexar. A abordagem ingênua de esperar sincronamente pela conclusão força os usuários a aguardar vários minutos, o que é simplesmente inaceitável. O processamento assíncrono em segundo plano torna-se essencial, mas o MCP não oferece suporte nativo a esse padrão.
8.png
Nosso servidor MCP executa um processo em segundo plano dentro do servidor MCP para lidar com a indexação enquanto retorna imediatamente mensagens de inicialização aos usuários, permitindo que continuem trabalhando.
9.png
Isso cria um novo desafio: como os usuários acompanham o progresso da indexação?
Uma ferramenta dedicada para consultar o progresso ou status da indexação resolve isso de forma elegante. O processo de indexação em segundo plano armazena em cache de forma assíncrona as informações de progresso, permitindo que os usuários verifiquem percentuais de conclusão, status de sucesso ou condições de falha a qualquer momento. Além disso, uma ferramenta manual de limpeza de índice lida com situações em que os usuários precisam redefinir índices imprecisos ou reiniciar o processo de indexação.
Design Final das Ferramentas:
index_codebase - Indexar base de código
search_code - Pesquisar código
get_indexing_status - Consultar status da indexação
clear_index - Limpar índice
Quatro ferramentas que alcançam o equilíbrio perfeito entre simplicidade e funcionalidade.
🔹 Gerenciamento de Variáveis de Ambiente
O gerenciamento de variáveis de ambiente muitas vezes é negligenciado, apesar de impactar significativamente a experiência do usuário. Exigir configuração separada de chave de API para cada MCP Client obrigaria os usuários a configurar credenciais várias vezes ao alternar entre Claude Code e Gemini CLI.
Uma abordagem de configuração global elimina esse atrito ao criar um arquivo ~/.context/.env no diretório home do usuário:
# ~/.context/.env
OPENAI_API_KEY=your-api-key-here
MILVUS_TOKEN=your-milvus-token
Essa abordagem oferece benefícios claros: os usuários configuram uma vez e usam em todos os lugares, em todos os clientes MCP; todas as configurações ficam centralizadas em um único local para fácil manutenção; e chaves de API sensíveis não ficam espalhadas por vários arquivos de configuração.
Também implementamos uma hierarquia de prioridade em três níveis: variáveis de ambiente do processo têm a prioridade mais alta, arquivos de configuração global têm prioridade média, e valores padrão servem como fallbacks.
Esse design oferece enorme flexibilidade: desenvolvedores podem usar variáveis de ambiente para substituições temporárias de teste, ambientes de produção podem injetar configurações sensíveis por meio de variáveis de ambiente do sistema para maior segurança, e usuários configuram uma vez para trabalhar sem problemas com Claude Code, Gemini CLI e outras ferramentas.
Neste ponto, a arquitetura central do servidor MCP está completa, abrangendo análise de código e armazenamento vetorial, passando por recuperação inteligente e gerenciamento de configuração. Cada componente foi cuidadosamente projetado e otimizado para criar um sistema que seja ao mesmo tempo poderoso e fácil de usar.
Testes práticos
Então, como o Claude Context realmente se sai na prática? Eu o testei contra o mesmo cenário de caça a bugs que inicialmente me deixou frustrado.
A instalação foi apenas um comando antes de iniciar o Claude Code:
claude mcp add claude-context -e OPENAI_API_KEY=your-openai-api-key -e MILVUS_TOKEN=your-zilliz-cloud-api-key -- npx @zilliz/claude-context-mcp@latest
Depois que minha base de código foi indexada, dei ao Claude Code a mesma descrição de bug que anteriormente o havia levado a uma caçada infrutífera de cinco minutos movida a grep. Desta vez, por meio de chamadas MCP do claude-context, ele identificou imediatamente o arquivo e o número da linha exatos, junto com uma explicação do problema.
A diferença não foi sutil — foi da água para o vinho.
E não foi apenas caça a bugs. Com o Claude Context integrado, o Claude Code produziu consistentemente resultados de maior qualidade em:
Resolução de issues
Refatoração de código
Detecção de código duplicado
Testes abrangentes
O ganho de desempenho também aparece nos números. Em testes lado a lado:
O uso de tokens caiu mais de 40%, sem nenhuma perda em recall.
Isso se traduz diretamente em custos de API menores e respostas mais rápidas.
Alternativamente, com o mesmo orçamento, o Claude Context entregou recuperações muito mais precisas.
Abrimos o código do Claude Context no GitHub, e ele já conquistou mais de 2,6 mil estrelas. Obrigado a todos pelo apoio e pelos likes.
Você pode experimentar por conta própria:
Benchmarks detalhados e a metodologia de teste estão disponíveis no repositório — adoraríamos receber seu feedback.
Olhando para o futuro
O que começou como uma frustração com o grep no Claude Code se transformou em uma solução sólida: Claude Context — um plugin MCP de código aberto que traz busca semântica, impulsionada por vetores, para Claude Code e outros assistentes de programação. A mensagem é simples: desenvolvedores não precisam se contentar com ferramentas de IA ineficientes. Com RAG e recuperação vetorial, você pode depurar mais rápido, reduzir custos de tokens em 40% e finalmente obter assistência de IA que realmente entende sua base de código.
E isso não se limita ao Claude Code. Como o Claude Context é construído com base em padrões abertos, a mesma abordagem funciona perfeitamente com Gemini CLI, Qwen Code, Cursor, Cline e além. Chega de ficar preso a concessões de fornecedores que priorizam a simplicidade em vez do desempenho.
Adoraríamos que você fizesse parte desse futuro:
Experimente Claude Context: é open-source e totalmente gratuito
Contribua para seu desenvolvimento
Ou crie sua própria solução usando o Claude Context
👉 Compartilhe seu feedback, faça perguntas ou obtenha ajuda entrando na nossa comunidade no Discord.
Continue lendo

Introducing Loon: A New Storage Engine for Vector Data That Never Stops Changing
Loon is a new storage engine for Milvus 3.0 and Zilliz Vector Lakebase, built to manage evolving vector datasets with ColumnGroups, row ID alignment, and Manifests.

Milvus 2.6.x Now Generally Available on Zilliz Cloud, Making Vector Search Faster, Smarter, and More Cost-Efficient for Production AI
Milvus 2.6.x is now GA on Zilliz Cloud, delivering faster vector search, smarter hybrid queries, and lower costs for production RAG and AI applications.

Zilliz Cloud Introduces Advanced BYOC-I Solution for Ultimate Enterprise Data Sovereignty
Explore Zilliz Cloud BYOC-I, the solution that balances AI innovation with data control, enabling secure deployments in finance, healthcare, and education sectors.



