Avanzato 16 minRAG

GraphRAG locale: RAG attraverso un grafo di conoscenze (guida avanzato)

Il classico RAG vettoriale risponde molto bene a domande puntuali, ma crolla non appena occorre collegare più documenti tra loro per ricavarne una sintesi. GraphRAG affronta questo problema costruendo un grafo di conoscenze — entità, relazioni, comunità — a partire dal tuo corpus, per poi interrogare questo grafo anziché un semplice database vettoriale. Questa guida mostra come configurare un RAG a grafo locale con un LLM tramite Ollama, senza chiamare alcuna API remota, e soprattutto quando questo approccio supera davvero la ricerca vettoriale.

Di Mohamed Meguedmi·Agg. 2026-08-27·Testato su Windows, macOS e Linux

#Perché GraphRAG?

Immagina il corpus di uno studio legale: 200 contratti, 500 email, 80 decisioni. Poni la domanda: «Quali sono i principali rischi giuridici menzionati nei nostri contratti con i clienti negli ultimi tre anni, e con quali clienti ricorrenti?». Un RAG vettoriale classico cerca 5 o 10 chunk «pertinenti», li fornisce al LLM e quest'ultimo risponde… con una visione parziale. Non coglie i pattern trasversali.

GraphRAG, invece di restituire solo passaggi grezzi, ragiona su una struttura: chi menziona cosa, quali entità ricorrono, quali relazioni le collegano. Per questo tipo di domanda di sintesi (« globale ») su un corpus, il grafo supera l'approccio vettoriale: è precisamente ciò che dimostrava l'articolo originale di Microsoft Research nel 2024.

i
A chi si rivolge questa guida
Hai già un RAG vettoriale locale che funziona (ChromaDB, LlamaIndex, AnythingLLM…), e ti blocchi sulle domande di sintesi. Altrimenti, inizia con un RAG classico prima di affrontare questo.

#GraphRAG vs RAG vettoriale: la vera differenza

Il kit RAG Locale

I tuoi documenti, la tua IA: un RAG locale affidabile sui tuoi PDF, sulle tue note e sulle tue email — senza inviare nulla nel cloud.

  • Spazio online a vita
  • PDF + file
  • Aggiornamenti a vita

I due approcci condividono un obiettivo: iniettare contesto esterno nel prompt del LLM per limitare le allucinazioni. Ma non recuperano la stessa cosa.

RAG vettoriale
Divide il corpus in chunk, calcola un embedding per ogni chunk e li memorizza in un database vettoriale (ChromaDB, Qdrant, FAISS). Al momento della query, recupera i k chunk più vicini secondo la similarità del coseno.
GraphRAG
Chiede a un LLM di estrarre entità e relazioni da ogni chunk, costruisce un grafo, raggruppa le entità in comunità e riassume ogni comunità. Quando riceve una query, percorre il grafo o aggrega i riassunti delle comunità.
Punti di forza del RAG vettoriale
Rapido da indicizzare (pochi minuti per 10 MB di testo), poco costoso, eccellente per domande mirate («Qual è la clausola di recesso nel contratto Acme?»).
Punti di forza di GraphRAG
Eccellente per domande globali («quali sono i temi ricorrenti?», «quali entità sono più connesse?»), tracciabilità dettagliata tramite gli archi, multi-hop nativo.
Limite dell'approccio vettoriale
Perde i collegamenti tra documenti. Una domanda che chiede di unire 3 documenti semanticamente distanti non restituisce i blocchi corretti.
Debolezza GraphRAG
Indicizzazione onerosa: bisogna far passare ogni chunk attraverso un LLM. Su un corpus di 10 MB, metti in conto diverse ore e molta VRAM, mentre l'indicizzazione vettoriale termina in 5 minuti.
→
L'approccio ibrido spesso vince
In pratica, i migliori stack combinano i due approcci: grafo per le domande globali e la navigazione, ricerca vettoriale (o BM25) per le query mirate. Vedi anche la ricerca ibrida BM25 + vettoriale per un'altra forma di combinazione.

#Come funziona internamente

Una pipeline GraphRAG completa comprende 5 fasi in sequenza. Tutte utilizzano il LLM (tranne il clustering).

  1. 01
    Chunking
    Il corpus viene suddiviso in passaggi da 500 a 1500 token, come in un RAG classico. La loro lunghezza ha un impatto diretto sulla qualità dell'estrazione: se un passaggio è troppo breve, il LLM non coglie alcune relazioni; se è troppo lungo, ne dimentica alcune.
  2. 02
    Estrazione di entità e relazioni
    Ogni chunk viene inviato a un LLM con un prompt strutturato del tipo: «Estrai tutte le entità (persona, organizzazione, luogo, concetto) e le relazioni tra di loro. Formato JSON.» Questa è la fase costosa: una chiamata al LLM per chunk.
  3. 03
    Costruzione del grafo
    Le entità estratte diventano nodi, le relazioni archi. Le entità identiche che appaiono in più chunk vengono fuse (risoluzione delle entità, spesso tramite embedding o una regola di normalizzazione).
  4. 04
    Rilevazione di comunità
    Un algoritmo di clustering (Leiden nella soluzione di Microsoft, un algoritmo più semplice in nano-graphrag) raggruppa i nodi fortemente connessi in comunità. Queste comunità sono la chiave del ragionamento «globale».
  5. 05
    Riepilogo delle comunità
    L'LLM produce un riassunto testuale di ogni comunità a partire dalle entità e dalle relazioni che contiene. Questi riassunti diventano le unità di recupero per le domande globali.

Quando viene interrogato, GraphRAG distingue due modalità: locale (ricerca di un'entità specifica e del suo vicinato nel grafo) e globale (aggregazione dei riassunti delle comunità). Il LLM combina quindi il contesto recuperato e la domanda per produrre la risposta finale.

#Strumenti disponibili per un deploy locale

Microsoft GraphRAG
L'implementazione di riferimento (github.com/microsoft/graphrag). Completa, curata, ma pesante: originariamente pensata per Azure OpenAI, richiede pazienza per l'adattamento a Ollama. Indicizzazione molto costosa in termini di token.
nano-graphrag
Implementazione minima (~1000 righe) compatibile nativamente Ollama (github.com/gusye1234/nano-graphrag). Questo è ciò che utilizzeremo qui: 10 volte meno codice da capire, e lo stesso concetto.
LightRAG
Variante più recente, ottimizzata per la latenza di interrogazione. Compatibile con Ollama. Più semplice di Microsoft GraphRAG, più strutturata di nano-graphrag.
LlamaIndex KnowledgeGraphIndex
Se sei già su LlamaIndex, l'integrazione è immediata, ma l'approccio è più rudimentale (nessuna comunità).
i
Scelta pedagogica
Questa guida utilizza nano-graphrag perché tutto è contenuto in due file Python che si possono leggere, modificare e sottoporre a debug. Una volta padroneggiato il concetto, passare a Microsoft GraphRAG o LightRAG in produzione diventa banale.

#Prerequisiti

Ollama installato e funzionante
Se non è così, segui prima la nostra guida all'installazione di Ollama.
Un LLM con solide capacità di ragionamento (14-24B)
L'estrazione di entità richiede potenza. gpt-oss 20B, Mistral Small 24B o Qwen 3.5 9B (limite inferiore) funzionano bene. Sotto gli 8B, il JSON prodotto è spesso malformato.
Un modello di embedding locale
nomic-embed-text tramite Ollama, o bge-m3 / multilingual-e5-large tramite sentence-transformers
Almeno 16 GB di VRAM
12 GB possono bastare in caso di necessità con un 8-9B in Q4 (Qwen 3.5 9B), ma l'indicizzazione sarà lenta. 16 GB possono ospitare gpt-oss 20B o Mistral Small 24B; 24 GB (RTX 4090, M-Max) offrono un buon margine.
Python 3.10+
nano-graphrag e la maggior parte dei framework RAG moderni richiedono la versione 3.10 o una successiva.

#1. Indicizzare un corpus con nano-graphrag

Prepara prima i modelli in Ollama. Per questo tutorial, usiamo gpt-oss 20B (quantizzazione MXFP4 predefinita, ~14 GB) e nomic-embed-text per gli embedding.

Terminale
ollama pull gpt-oss:20b
ollama pull nomic-embed-text
ollama serve  # si pas déjà en service

Installa successivamente nano-graphrag in un venv dedicato.

Terminale
python -m venv .venv
source .venv/bin/activate  # Linux/macOS
pip install nano-graphrag

Lo script di indicizzazione sta in una ventina di righe. Lo colleghi a Ollama tramite l'endpoint compatibile con OpenAI sulla porta 11434.

index.py
import asyncio
from nano_graphrag import GraphRAG, QueryParam
from nano_graphrag.llm import ollama_model_if_cache, ollama_embedding

WORKING_DIR = "./graphrag_cache"

async def main():
    rag = GraphRAG(
        working_dir=WORKING_DIR,
        best_model_func=ollama_model_if_cache,
        cheap_model_func=ollama_model_if_cache,
        embedding_func=ollama_embedding,
        best_model_kwargs={"model_name": "gpt-oss:20b"},
        cheap_model_kwargs={"model_name": "gpt-oss:20b"},
    )

    with open("corpus.txt", encoding="utf-8") as f:
        text = f.read()

    await rag.ainsert(text)

if __name__ == "__main__":
    asyncio.run(main())

Avvia l'indicizzazione. A seconda delle dimensioni del corpus e della GPU, considera da pochi minuti (1 MB di testo) a diverse ore (50 MB).

Terminale
python index.py
!
Pazienza: è lento per natura
Per un corpus di 5 MB con gpt-oss 20B su RTX 4090, metti in conto circa 2 ore. nano-graphrag elabora i chunk sequenzialmente per impostazione predefinita. È normale: il costo è quello dell'estrazione tramite LLM, non di un calcolo di embedding.

Alla fine, la cartella graphrag_cache/ contiene il grafo serializzato, gli embedding e i riassunti delle comunità.

#2. Interrogare il grafo

Una volta indicizzato il corpus, l'interrogazione è rapida (pochi secondi per richiesta) perché il LLM legge soltanto il contesto recuperato dal grafo, non più l'intero corpus.

query.py
import asyncio
from nano_graphrag import GraphRAG, QueryParam
from nano_graphrag.llm import ollama_model_if_cache, ollama_embedding

async def main():
    rag = GraphRAG(
        working_dir="./graphrag_cache",
        best_model_func=ollama_model_if_cache,
        cheap_model_func=ollama_model_if_cache,
        embedding_func=ollama_embedding,
        best_model_kwargs={"model_name": "gpt-oss:20b"},
        cheap_model_kwargs={"model_name": "gpt-oss:20b"},
    )

    # Mode global : synthèse à partir des résumés de communautés
    print(await rag.aquery(
        "Quels sont les thèmes principaux du corpus ?",
        param=QueryParam(mode="global")
    ))

    # Mode local : recherche centrée sur des entités
    print(await rag.aquery(
        "Quelle est la position de l'entreprise X sur le sujet Y ?",
        param=QueryParam(mode="local")
    ))

asyncio.run(main())
→
Scegliere la modalità giusta
Domanda che inizia con «quali sono i principali…», «quali tendenze…», «fai una sintesi…» → modalità globale. Domanda relativa a un'entità precisa → modalità locale. Se non sai, prova entrambe: le risposte spesso differiscono radicalmente.

#Costo del calcolo in locale: cosa aspettarsi

È la parte che sorprende tutti la prima volta. Indicizzare 5 MB di testo con GraphRAG richiede circa da 50 a 200 volte più risorse di calcolo rispetto a un RAG vettoriale sullo stesso corpus. Ecco alcuni riferimenti concreti, espressi come ordini di grandezza.

Corpus 1 MB (~300 pagine)
gpt-oss 20B (MXFP4) su RTX 4090: circa 25 minuti di indicizzazione. Su RTX 3060 12 GB (offload parziale): circa 3 ore. Su Mac M3 Max 64 GB: circa 40 minuti.
Corpus 5 MB (~1500 pagine)
RTX 4090: circa 2 ore. M4 Pro 48 GB: circa 3 ore. Oltre questo volume, prevedi di lasciare l'elaborazione in esecuzione durante la notte.
Picco di utilizzo della VRAM
Il modello gpt-oss 20B (MXFP4) occupa circa 14 GB in modo permanente. Gli embedding nomic aggiungono circa 1 GB. Con meno di 16 GB di VRAM, aspettati uno swap verso la CPU (offload parziale).
Costo di una richiesta
Qualche secondo in modalità locale, da 5 a 30 s in modalità globale (aggregazione di più comunità). Un costo trascurabile rispetto all'indicizzazione.
Riindexazione incrementale
nano-graphrag al momento non è in grado di aggiornare correttamente un grafo esistente. Aggiungere il 10% di nuovi documenti = ripetere un'indicizzazione parziale o completa. Microsoft GraphRAG gestisce meglio questo aspetto.
!
La trappola di un LLM troppo piccolo
Sei tentato di usare Granite 4.2 3B o Qwen 3.5 2B per andare più veloce? L'estrazione JSON sarà incoerente, le entità avranno nomi errati e il grafo sarà inutilizzabile. È proprio l'errore in cui un'indicizzazione rapida produce un grafo che non si può sfruttare. Investi in un modello da almeno 8B, idealmente gpt-oss 20B o Mistral Small 24B.

#Quando GraphRAG supera davvero la ricerca vettoriale

GraphRAG non è un sostituto universale del RAG vettoriale. In alcuni casi d'uso lo supera di gran lunga, mentre in altri offre prestazioni nettamente inferiori.

Sintesi su corpus
« Quali sono i 5 temi principali discussi nelle nostre 200 email sull'argomento X? » → GraphRAG vince a mani basse. L'approccio vettoriale recupera solo 5-10 email, mentre il grafo aggrega le comunità.
Domande multi-hop
«Quali fornitori lavorano sia con Acme sia con Beta Corp?» → GraphRAG risolve la domanda percorrendo gli archi del grafo. L'approccio vettoriale deve recuperare i segmenti corretti e affidarsi al LLM per eseguire il join.
Esplorazione delle relazioni
«Chi sono le persone più menzionate in relazione al progetto Atlas?» → GraphRAG gestisce questo caso in modo nativo (centralità, vicinato). La ricerca vettoriale non contempla il concetto di relazione.
Domande e risposte fattuali mirate
«Qual è la durata del preavviso nel contratto Acme del 12 marzo 2024?» → Il RAG vettoriale vince: più veloce, più preciso, meno costoso da indicizzare.
Corpus in rapida evoluzione
Se aggiungi documenti ogni giorno, il costo della reindicizzazione di GraphRAG diventa proibitivo. Rimani su una ricerca vettoriale oppure su una ricerca vettoriale + BM25.
Corpus < 500 kB
Non serve un grafo: il LLM può leggere tutto nel contesto se hai 32k+ token. GraphRAG si giustifica solo per corpus troppo grandi per rientrare nel contesto.
→
La regola pratica
Se i tuoi utenti pongono soprattutto domande del tipo «cerca questa informazione precisa», rimani sulla ricerca vettoriale. Se il valore sta nella sintesi, nell'esplorazione di pattern o nell'analisi trasversale di un corpus stabile, GraphRAG vale il costo di indicizzazione.

#Per approfondire

GraphRAG è un ambito in piena attività: le implementazioni evolvono rapidamente, così come i benchmark. Ecco alcuni spunti per proseguire.

RAG locale: introduzione
Se alcuni concetti del RAG vettoriale ti sono ancora poco chiari, la guida introduttiva è una buona base prima di mettere GraphRAG in produzione.
Strategie di chunking
La qualità di estrazione delle entità dipende direttamente dalla dimensione e dalla coerenza dei chunk. Questo manuale approfondisce le buone pratiche.
Ricerca ibrida BM25 + vettoriale
Per combinare GraphRAG con un retrieval classico, guarda prima la ricerca ibrida: stessa logica di unione dei segnali.
Scegliere la GPU per l'IA locale
L'indicizzazione di GraphRAG richiede molte risorse. Se oggi usi una GPU da 8–12 GB, passare a 16–24 GB cambia radicalmente la velocità di elaborazione.
Questa guida ti è stata utile?

Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.