Perché sono contrario al recupero solo tramite grep di Claude Code? Consuma semplicemente troppi token
Gli assistenti di coding basati sull’AI stanno esplodendo. Solo negli ultimi due anni, strumenti come Cursor, Claude Code, Gemini CLI e Qwen Code sono passati dall’essere curiosità a compagni quotidiani per milioni di sviluppatori. Ma dietro questa rapida ascesa si sta preparando uno scontro su qualcosa di ingannevolmente semplice: in che modo un assistente di coding AI dovrebbe effettivamente cercare contesto nella tua codebase?
Al momento, ci sono due approcci:
RAG basata su vector search (recupero semantico).
Ricerca per parole chiave con grep (corrispondenza letterale di stringhe).
Claude Code e Gemini hanno scelto quest’ultimo. Infatti, un ingegnere di Claude ha ammesso apertamente su Hacker News che Claude Code non usa affatto RAG. Invece, fa semplicemente grep del tuo repo riga per riga (quello che chiamano “agentic search”)—niente semantica, niente struttura, solo corrispondenza grezza di stringhe.
Quella rivelazione ha diviso la community:
I sostenitori difendono la semplicità di grep. È veloce, esatto e—soprattutto—prevedibile. Nella programmazione, sostengono, la precisione è tutto, e gli embedding di oggi sono ancora troppo imprecisi per essere affidabili.
I critici vedono grep come un vicolo cieco. Ti sommerge di corrispondenze irrilevanti, consuma token e blocca il tuo flusso di lavoro. Senza comprensione semantica, è come chiedere alla tua AI di fare debug bendata.
Entrambe le parti hanno ragione. E dopo aver costruito e testato la mia soluzione, posso dire questo: l’approccio RAG basato su vector search cambia le regole del gioco. Non solo rende la ricerca drasticamente più veloce e più accurata, ma riduce anche l’uso dei token del 40% o più. (Vai alla parte Claude Context per il mio approccio)
Quindi perché grep è così limitante? E come può la vector search offrire davvero risultati migliori nella pratica? Analizziamolo.
Cosa c’è che non va nella ricerca del codice solo con grep di Claude Code?
Mi sono imbattuto in questo problema mentre facevo debug di una questione spinosa. Claude Code ha lanciato query grep in tutto il mio repo, restituendomi enormi blocchi di testo irrilevante. Dopo un minuto, non avevo ancora trovato il file rilevante. Cinque minuti dopo, finalmente avevo le 10 righe giuste—ma erano sepolte in 500 righe di rumore.
Non è un caso limite. Scorrendo le issue GitHub di Claude Code si vedono molti sviluppatori frustrati che si imbattono nello stesso muro:
issue1: https://github.com/anthropics/claude-code/issues/1315
issue2: https://github.com/anthropics/claude-code/issues/4556
La frustrazione della community si riduce a tre punti dolenti:
Gonfiamento dei token. Ogni dump di grep riversa enormi quantità di codice irrilevante nell’LLM, facendo aumentare i costi che scalano in modo terribile con la dimensione del repo.
Tassa sul tempo. Resti bloccato ad aspettare mentre l’AI gioca a indovina chi con la tua codebase, uccidendo concentrazione e flusso.
Zero contesto. Grep trova corrispondenze di stringhe letterali. Non ha alcun senso del significato o delle relazioni, quindi stai di fatto cercando alla cieca.
Ecco perché il dibattito conta: grep non è solo “vecchia scuola”, sta attivamente frenando la programmazione assistita dall’AI.
Claude Code vs Cursor: perché quest’ultimo ha un contesto del codice migliore
Quando si parla di contesto del codice, Cursor ha fatto un lavoro migliore. Fin dal primo giorno, Cursor ha puntato sulla indicizzazione della codebase: suddividere il tuo repo in chunk significativi, incorporare quei chunk in vettori e recuperarli semanticamente ogni volta che l’AI ha bisogno di contesto. Questa è la classica Retrieval-Augmented Generation (RAG) applicata al codice, e i risultati parlano da soli: contesto più mirato, meno token sprecati e recupero più veloce.
Claude Code, al contrario, ha puntato ancora di più sulla semplicità. Niente indici, niente embedding—solo grep. Questo significa che ogni ricerca è una corrispondenza letterale di stringhe, senza alcuna comprensione della struttura o della semantica. In teoria è veloce, ma nella pratica gli sviluppatori spesso finiscono per setacciare mucchi di corrispondenze irrilevanti prima di trovare l’unico ago di cui hanno davvero bisogno.
| Claude Code | Cursor | |
|---|---|---|
| Accuratezza della ricerca | Mostra solo corrispondenze esatte—perde qualsiasi cosa nominata diversamente. | Trova codice semanticamente rilevante anche quando le parole chiave non corrispondono esattamente. |
| Efficienza | Grep riversa enormi blocchi di codice nel modello, facendo aumentare i costi in token. | Chunk più piccoli e con un segnale più alto riducono il carico di token del 30–40%. |
| Scalabilità | Riesegue grep sul repo ogni volta, il che rallenta man mano che i progetti crescono. | Indicizza una volta, poi recupera su larga scala con un ritardo minimo. |
| Filosofia | Restare minimale—nessuna infrastruttura extra. | Indicizzare tutto, recuperare in modo intelligente. |
Allora perché Claude (o Gemini, o Cline) non ha seguito l’esempio di Cursor? Le ragioni sono in parte tecniche e in parte culturali. Il recupero vettoriale non è banale—bisogna risolvere chunking, aggiornamenti incrementali e indicizzazione su larga scala. Ma, soprattutto, Claude Code è costruito attorno al minimalismo: niente server, niente indici, solo una CLI pulita. Embedding e vector DB non si adattano a questa filosofia di design.
Quella semplicità è attraente—ma limita anche il tetto massimo di ciò che Claude Code può offrire. La disponibilità di Cursor a investire in una vera infrastruttura di indicizzazione è il motivo per cui oggi appare più potente.
Claude Context: un progetto open-source per aggiungere la ricerca semantica del codice a Claude Code
Claude Code è uno strumento solido—ma ha un contesto del codice scarso. Cursor ha risolto questo problema con l’indicizzazione del codebase, ma Cursor è closed-source, bloccato dietro abbonamenti e costoso per singoli individui o piccoli team.
Questo divario è il motivo per cui abbiamo iniziato a costruire la nostra soluzione open-source: Claude Context.
Claude Context è un plugin MCP open-source che porta la ricerca semantica del codice a Claude Code (e a qualsiasi altro agente di coding AI che parli MCP). Invece di passare al setaccio il repo con grep, integra database vettoriali con modelli di embedding per fornire agli LLM un contesto profondo e mirato dall’intero codebase. Il risultato: recupero più preciso, meno spreco di token e un’esperienza di sviluppo nettamente migliore.
Ecco come lo abbiamo costruito:
Tecnologie che utilizziamo
🔌 Livello di interfaccia: MCP come connettore universale
Volevamo che funzionasse ovunque—non solo con Claude. MCP (Model Context Protocol) agisce come lo standard USB per gli LLM, permettendo agli strumenti esterni di collegarsi senza attriti. Impacchettando Claude Context come server MCP, funziona non solo con Claude Code ma anche con Gemini CLI, Qwen Code, Cline e persino Cursor.
🗄️ Database vettoriale: Zilliz Cloud
Come spina dorsale, abbiamo scelto Zilliz Cloud (un servizio completamente gestito costruito su Milvus). È ad alte prestazioni, cloud-native, elastico e progettato per carichi di lavoro AI come l’indicizzazione del codebase. Ciò significa recupero a bassa latenza, scalabilità quasi infinita e affidabilità solidissima.
🧩 Modelli di embedding: flessibili per designTeam diversi hanno esigenze diverse, quindi Claude Context supporta subito più provider di embedding:
OpenAI embeddings per stabilità e ampia adozione.
Voyage embeddings per prestazioni specializzate sul codice.
Ollama per deployment locali orientati alla privacy.
È possibile inserire modelli aggiuntivi man mano che i requisiti evolvono.
💻 Scelta del linguaggio: TypeScript
Abbiamo discusso tra Python e TypeScript. TypeScript ha vinto, non solo per la compatibilità a livello applicativo (plugin VSCode, strumenti web), ma anche perché Claude Code e Gemini CLI sono a loro volta basati su TypeScript. Questo rende l’integrazione fluida e mantiene coerente l’ecosistema.
Architettura del sistema
Claude Context segue un design pulito e stratificato:
I moduli core gestiscono il lavoro più pesante: parsing del codice, suddivisione in chunk, indicizzazione, recupero e sincronizzazione.
L’interfaccia utente gestisce le integrazioni: server MCP, plugin VSCode o altri adattatori.
Questa separazione mantiene il motore core riutilizzabile in ambienti diversi, consentendo al tempo stesso alle integrazioni di evolversi rapidamente man mano che emergono nuovi assistenti di coding AI.
Implementazione dei moduli core
I moduli core costituiscono la base dell’intero sistema. Astraggono database vettoriali, modelli di embedding e altri componenti in moduli componibili che creano un oggetto Context, abilitando diversi database vettoriali e modelli di embedding per scenari differenti.
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');
Risolvere le principali sfide tecniche
Costruire Claude Context non significava solo collegare embedding e un DB vettoriale. Il lavoro reale è consistito nel risolvere i problemi difficili che determinano il successo o il fallimento dell’indicizzazione del codice su larga scala. Ecco come abbiamo affrontato le tre sfide più grandi:
Sfida 1: Chunking intelligente del codice
Il codice non può essere semplicemente suddiviso per righe o caratteri. Questo crea frammenti disordinati e incompleti e rimuove la logica che rende il codice comprensibile.
Abbiamo risolto questo problema con due strategie complementari:
Chunking basato su AST (strategia principale)
Questo è l’approccio predefinito, che utilizza parser tree-sitter per comprendere la struttura sintattica del codice e suddividerlo lungo confini semantici: funzioni, classi, metodi. Questo offre:
Completezza sintattica – niente funzioni troncate o dichiarazioni spezzate.
Coerenza logica – la logica correlata rimane insieme per un migliore recupero semantico.
Supporto multi-linguaggio – funziona con JS, Python, Java, Go e altri linguaggi tramite le grammatiche tree-sitter.
Suddivisione del testo con LangChain (strategia di fallback)
Per i linguaggi che AST non riesce ad analizzare o quando il parsing fallisce, RecursiveCharacterTextSplitter di LangChain offre un backup affidabile.
// Use recursive character splitting to maintain code structure
const splitter = RecursiveCharacterTextSplitter.fromLanguage(language, {
chunkSize: 1000,
chunkOverlap: 200,
});
È meno “intelligente” di AST, ma altamente affidabile, garantendo che gli sviluppatori non restino mai bloccati. Insieme, queste due strategie bilanciano ricchezza semantica e applicabilità universale.
Sfida 2: Gestire le modifiche al codice in modo efficiente
La gestione delle modifiche al codice rappresenta una delle sfide più grandi nei sistemi di indicizzazione del codice. Reindicizzare interi progetti per piccole modifiche ai file sarebbe del tutto impraticabile.
Per risolvere questo problema, abbiamo costruito il meccanismo di sincronizzazione basato su Merkle Tree.
Merkle Tree: la base del rilevamento delle modifiche
I Merkle Tree creano un sistema gerarchico di "impronte digitali" in cui ogni file ha la propria impronta hash, le cartelle hanno impronte basate sui loro contenuti e tutto culmina in un’impronta unica del nodo radice per l’intera codebase.
Quando il contenuto dei file cambia, le impronte hash si propagano verso l’alto attraverso ogni livello fino al nodo radice. Ciò consente un rilevamento rapido delle modifiche confrontando le impronte hash livello per livello dalla radice verso il basso, identificando e localizzando rapidamente le modifiche ai file senza una reindicizzazione completa del progetto.
Il sistema esegue controlli di sincronizzazione handshake ogni 5 minuti utilizzando un processo semplificato in tre fasi:
Fase 1: Rilevamento fulmineo calcola l’hash della radice Merkle dell’intera codebase e lo confronta con lo snapshot precedente. Hash di radice identici significano che non si sono verificate modifiche: il sistema salta tutta l’elaborazione in millisecondi.
Fase 2: Confronto preciso si attiva quando gli hash di radice differiscono, eseguendo un’analisi dettagliata a livello di file per identificare esattamente quali file sono stati aggiunti, eliminati o modificati.
Fase 3: Aggiornamenti incrementali ricalcola i vettori solo per i file modificati e aggiorna di conseguenza il database vettoriale, massimizzando l’efficienza.
Gestione degli snapshot locali
Tutto lo stato di sincronizzazione persiste localmente nella directory ~/.context/merkle/ dell’utente. Ogni codebase mantiene il proprio file di snapshot indipendente contenente tabelle hash dei file e dati serializzati dell’albero Merkle, garantendo un recupero accurato dello stato anche dopo il riavvio del programma.
Questo design offre vantaggi evidenti: la maggior parte dei controlli si completa in millisecondi quando non esistono modifiche, solo i file realmente modificati attivano la rielaborazione (evitando un enorme spreco computazionale) e il recupero dello stato funziona impeccabilmente tra le sessioni del programma.
Dal punto di vista dell’esperienza utente, la modifica di una singola funzione attiva la reindicizzazione solo per quel file, non per l’intero progetto, migliorando drasticamente l’efficienza dello sviluppo.
Sfida 3: Progettazione dell’interfaccia MCP
Anche il motore di indicizzazione più intelligente è inutile senza un’interfaccia pulita rivolta agli sviluppatori. MCP era la scelta ovvia, ma ha introdotto sfide uniche:
🔹 Progettazione degli strumenti: mantenerla semplice
Il modulo MCP funge da interfaccia rivolta all’utente, rendendo l’esperienza utente la massima priorità.
La progettazione degli strumenti inizia con l’astrazione delle operazioni standard di indicizzazione e ricerca della codebase in due strumenti principali: index_codebase per indicizzare le codebase e search_code per cercare codice.
Questo solleva una domanda importante: quali strumenti aggiuntivi sono necessari?
Il numero di strumenti richiede un equilibrio attento: troppi strumenti creano sovraccarico cognitivo e confondono la selezione degli strumenti da parte degli LLM, mentre troppo pochi potrebbero non coprire funzionalità essenziali.
Ragionare a ritroso dai casi d’uso reali aiuta a rispondere a questa domanda.
Affrontare le sfide dell’elaborazione in background
Le codebase di grandi dimensioni possono richiedere molto tempo per essere indicizzate. L’approccio ingenuo di attendere sincronicamente il completamento costringe gli utenti ad aspettare diversi minuti, il che è semplicemente inaccettabile. L’elaborazione asincrona in background diventa essenziale, ma MCP non supporta nativamente questo pattern.
8.png
Il nostro server MCP esegue un processo in background all’interno del server MCP per gestire l’indicizzazione, restituendo immediatamente messaggi di avvio agli utenti, consentendo loro di continuare a lavorare.
9.png
Questo crea una nuova sfida: come fanno gli utenti a monitorare l’avanzamento dell’indicizzazione?
Uno strumento dedicato per interrogare l’avanzamento o lo stato dell’indicizzazione risolve elegantemente questo problema. Il processo di indicizzazione in background memorizza asincronamente nella cache le informazioni di avanzamento, consentendo agli utenti di controllare percentuali di completamento, stato di successo o condizioni di errore in qualsiasi momento. Inoltre, uno strumento manuale di cancellazione dell’indice gestisce le situazioni in cui gli utenti devono reimpostare indici inaccurati o riavviare il processo di indicizzazione.
Progettazione finale degli strumenti:
index_codebase - Indicizza la codebase
search_code - Cerca codice
get_indexing_status - Interroga lo stato dell’indicizzazione
clear_index - Cancella l’indice
Quattro strumenti che trovano il perfetto equilibrio tra semplicità e funzionalità.
🔹 Gestione delle variabili d’ambiente
La gestione delle variabili d'ambiente viene spesso trascurata, nonostante abbia un impatto significativo sull'esperienza utente. Richiedere una configurazione separata della chiave API per ogni Client MCP costringerebbe gli utenti a configurare le credenziali più volte quando passano da Claude Code a Gemini CLI.
Un approccio di configurazione globale elimina questo attrito creando un file ~/.context/.env nella directory home dell'utente:
# ~/.context/.env
OPENAI_API_KEY=your-api-key-here
MILVUS_TOKEN=your-milvus-token
Questo approccio offre vantaggi evidenti: gli utenti configurano una sola volta e usano ovunque su tutti i client MCP, tutte le configurazioni sono centralizzate in un'unica posizione per una manutenzione semplice, e le chiavi API sensibili non vengono disseminate in più file di configurazione.
Implementiamo anche una gerarchia di priorità a tre livelli: le variabili d'ambiente di processo hanno la priorità più alta, i file di configurazione globali hanno priorità media e i valori predefiniti fungono da fallback.
Questo design offre un'enorme flessibilità: gli sviluppatori possono usare le variabili d'ambiente per override temporanei durante i test, gli ambienti di produzione possono iniettare configurazioni sensibili tramite variabili d'ambiente di sistema per una maggiore sicurezza, e gli utenti configurano una sola volta per lavorare senza problemi su Claude Code, Gemini CLI e altri strumenti.
A questo punto, l'architettura di base del server MCP è completa, spaziando dal parsing del codice e dall'archiviazione vettoriale fino al recupero intelligente e alla gestione della configurazione. Ogni componente è stato progettato e ottimizzato con cura per creare un sistema tanto potente quanto facile da usare.
Test pratico
Quindi, come si comporta Claude Context nella pratica? L'ho testato esattamente nello stesso scenario di ricerca di bug che inizialmente mi aveva lasciato frustrato.
L'installazione ha richiesto un solo comando prima di avviare 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
Una volta indicizzata la mia codebase, ho fornito a Claude Code la stessa descrizione del bug che in precedenza lo aveva mandato in una caccia all'oca selvaggia basata su grep durata cinque minuti. Questa volta, tramite chiamate MCP claude-context, ha individuato immediatamente il file e il numero di riga esatti, con tanto di spiegazione del problema.
La differenza non era sottile: era come il giorno e la notte.
E non si trattava solo di caccia ai bug. Con Claude Context integrato, Claude Code ha prodotto costantemente risultati di qualità superiore in:
Risoluzione dei problemi
Refactoring del codice
Rilevamento di codice duplicato
Test completi
Il miglioramento delle prestazioni si vede anche nei numeri. Nei test affiancati:
L'uso dei token è diminuito di oltre il 40%, senza alcuna perdita di recall.
Questo si traduce direttamente in costi API inferiori e risposte più rapide.
In alternativa, con lo stesso budget, Claude Context ha fornito recuperi molto più accurati.
Abbiamo reso Claude Context open source su GitHub, e ha già ottenuto oltre 2,6K stelle. Grazie a tutti per il vostro supporto e i vostri like.
Puoi provarlo tu stesso:
Benchmark dettagliati e metodologia di test sono disponibili nel repo: ci piacerebbe ricevere il tuo feedback.
Guardando avanti
Quella che era iniziata come una frustrazione con grep in Claude Code è diventata una soluzione solida: Claude Context—un plugin MCP open source che porta la ricerca semantica basata su vettori in Claude Code e in altri assistenti di coding. Il messaggio è semplice: gli sviluppatori non devono accontentarsi di strumenti di IA inefficienti. Con RAG e il recupero vettoriale, puoi eseguire il debug più velocemente, ridurre i costi dei token del 40% e ottenere finalmente un'assistenza IA che comprende davvero la tua codebase.
E questo non si limita a Claude Code. Poiché Claude Context è basato su standard aperti, lo stesso approccio funziona perfettamente con Gemini CLI, Qwen Code, Cursor, Cline e oltre. Basta essere vincolati a compromessi dei fornitori che privilegiano la semplicità rispetto alle prestazioni.
Ci piacerebbe che tu facessi parte di quel futuro:
Prova Claude Context: è open-source e totalmente gratuito
Contribuisci al suo sviluppo
Oppure crea la tua soluzione usando Claude Context
👉 Condividi il tuo feedback, fai domande o ricevi aiuto entrando nella nostra community Discord.
Continua a leggere

Migrating from S3 Vectors to Zilliz Cloud: Unlocking the Power of Tiered Storage
Learn how Zilliz Cloud bridges cost and performance with tiered storage and enterprise-grade features, and how to migrate data from AWS S3 Vectors to Zilliz Cloud.

Creating Collections in Zilliz Cloud Just Got Way Easier
We've enhanced the entire collection creation experience to bring advanced capabilities directly into the interface, making it faster and easier to build production-ready schemas without switching tools.

Bringing AI to Legal Tech: The Role of Vector Databases in Enhancing LLM Guardrails
Discover how vector databases enhance AI reliability in legal tech, ensuring accurate, compliant, and trustworthy AI-powered legal solutions.



