Torna al Blog🇬🇧 Read in English

Code Graph: come l'AI può davvero capire il tuo codice

Perché i code graph basati su AST battono grep per gli agent AI, e come il nostro resta aggiornato a ogni modifica tramite hook restando interrogabile direttamente dagli agent via MCP.

Gli LLM leggono il codice come testo. Questo è il problema.

Chiedi a un assistente "chi chiama validate_token?" La maggior parte fa un grep. Funziona per match letterali, fallisce quando le chiamate passano per decoratori, dispatch dinamica, re-export, collisioni di nome tra moduli.

Il problema è semplice. Un language model vede il codice come token. Non comprende nativamente che una funzione ha chiamanti, una classe estende un'altra, un modulo importa un simbolo, o che quella HTTP call parla con quel servizio. Può inferire. L'inferenza costa tempo di debug.

AST e tree-sitter, il substrato standard

Un Abstract Syntax Tree è la vista strutturata del codice sorgente: ogni nodo è un costrutto reale del programma — una definizione di funzione, una chiamata a metodo, un import, un'annotazione di tipo. Si percorre l'albero, si estraggono entità, le si collegano, e si ottiene un code graph.

Tree-sitter è lo standard di fatto per produrre questi alberi. Veloce, incrementale, tollerante agli errori, oltre 40 linguaggi con un'unica toolchain. GitHub lo utilizza per Semantic. Cursor, Zed, Claude Code, Codex, Gemini CLI ci si appoggiano. Lo facciamo anche noi — questa parte non è un differenziatore, è il livello base.

Ciò che distingue le implementazioni di code graph è tutto quanto sta sopra l'AST: come il grafo viene mantenuto sincrono con le modifiche, come viene esposto agli agent AI, e quali tipi di entità cattura.

Cosa rende il nostro diverso

Tre elementi concreti, nessuno in qualsiasi concorrente cloud o standalone.

1. Il grafo si aggiorna da solo mentre scrivete codice. Un hook PostToolUse (code-graph-incremental.sh) scatta su ogni agent write a Python, JavaScript o TypeScript. Il file va in coda, code-graph-updater lo rianalizza incrementalmente, il grafo è aggiornato in secondi. Nessun code-graph-analyze manuale. Nessuna domanda "il grafo è stale?".

2. Gli agent AI interrogano il grafo direttamente. Due strumenti MCP: search_code_graph(query, scope, expand_hops) per ricerca semantica con espansione opzionale, e query_code_structure(type, target) per query strutturali. Cody e Augment sono superfici che i developer interrogano. La nostra è un'interfaccia che gli agent interrogano: classe di integrazione diversa. Un agent debugging può chiedere i chiamanti di una funzione, seguire gli archi due salti, recuperare le interazioni cross-service in un passo di ragionamento.

3. Cinque tipi di entità; uno che nessun concorrente traccia. CodeModule, CodeClass, CodeFunction, CodeAPI sono standard. Il quinto, CodeInteraction, cattura le chiamate cross-service: protocol, endpoint, confidence, direction. Il servizio A che chiama B su HTTP/gRPC diventa un arco interrogabile nel grafo via query_code_structure("interactions", "module.py"). Cursor, Cody, Augment si concentrano su comprensione intra-repo; i confini cross-service non modelano nei loro.

A chiudere il cerchio, le primitive di query precostituite: callers, dependencies, methods, extends, interactions, path (BFS fino a profondità 6 tra due funzioni), composes, composed_by, type_users. Un agent le richiama per nome, senza scripting.

Embeddings: default e alternative più leggere

Default: CodeSage-Large-v2 (2048-dim, Apache 2.0, FastAPI porta 11438, GPU-accelerato). Non sosteniamo che 2048-dim sia universale: più denso, più sfumature, storage/query più caro. Per CPU-only o progetti piccoli, Jina v2 code-embed (768-dim) è alternativa drop-in. Entrambi Apache 2.0, locali. Scegliete quello che il vostro hardware supporta.

Integrazione Joern (opzionale, consigliata)

Joern costruisce un Code Property Graph — AST + Control Flow Graph + Program Dependence Graph fusi — per Java, Python, JavaScript, Kotlin e altri. È Apache 2.0 e basato su JVM (~600MB).

L'installer rileva Joern sul PATH. Se presente, l'analyzer aggiunge due campi extra per funzione: cfg_summary (metriche su branch / loop / profondità — utili per "trova le funzioni più complesse da rifattorizzare") e data_flow_vars (variabili che attraversano la funzione — utili per "cosa tocca davvero questa funzione"). Se Joern non c'è, l'installer offre di scaricarlo tramite lo script ufficiale. Decline e il resto del code graph (Tree-sitter AST + 5 tipi di entità + embedding CodeSage + interazioni cross-service) funziona esattamente come prima.

Per ora non incapsuliamo le query CPGQL né eseguiamo analisi di taint inter-procedurali. È un'integrazione più profonda sulla roadmap. Joern oggi aggiunge metriche, non nuove primitive di query.

Dove si colloca davvero ciascuno strumento

Ogni tool in questo spazio ottimizza per una forma di lavoro diversa.

ToolTarget di ottimizzazioneLocale?Aggiornato auto a ogni edit?Chiamabile da agent AI?
VibeCoded OrchestratorFreshness via hook + grafo cross-service + MCPSì (hook)Sì (MCP)
Augment CodeRetrieval su monorepo da 100k+ fileNo (cloud)Sì (lato cloud)Via UI
Sourcegraph CodyRicerca semantica su intero repoNo (cloud)Sì (lato cloud)Via UI
GitHub Copilot workspaceIndicizzazione del workspaceNoParzialeVia UI
JoernAST + CFG + PDG (CPG)No (manuale)Integrazione opzionale per metriche
SemgrepPattern matching a regoleA scansioneNo
TabNineModello di autocomplete localen/aParziale

Quel che combiniamo: grafo locale, aggiornato senza run manuali, interrogabile da agent AI via MCP stabile, archi cross-service come dato di prima classe. Quattro proprietà, uno stack.

Come averlo

L'intero stack di code graph è incluso in VibeCoded Orchestrator — gratuito, AGPL-3.0, gira sulla vostra macchina. Stessi dati, stessi hook, stessi strumenti MCP sia nel base gratuito sia in Pro.

Date un'occhiata all'Orchestrator — code graph completo incluso, nessun gating per tier.

Fonti