Agentic RAG in locale: quando vale la peine
L'agentic RAG affida a un modello la guida della ricerca: decide cosa cercare, legge ciò che ha trovato, poi rilancia una query se gli manca qualcosa. Questo ciclo ha un prezzo, soprattutto su una macchina locale, dove ogni giro si paga in tempo di generazione. Questa guida spiega cosa cambia rispetto a un RAG classico e in quali casi questo costo aggiuntivo è giustificato, e mostra un esempio completo con un modello servito da Ollama e LangGraph.
#L'agentic RAG in breve
Un RAG classico segue un percorso fisso: la domanda avvia una ricerca, i passaggi trovati finiscono nel prompt, il modello risponde. L'agentic RAG sostituisce questo percorso con un ciclo. Il modello dispone di strumenti di ricerca e sceglie da solo se chiamarli, con quale query e quante volte, finché non ritiene di poter rispondere o di dover rinunciare.
Il corso AI Agents for Beginners di Microsoft lo descrive come un funzionamento in cui il modello pianifica i passaggi successivi mentre recupera informazioni da fonti esterne, con un ciclo di tipo «maker-checker»: produrre, verificare, correggere. Lo stesso corso ricorda il limite di questa autonomia: si esercita all'interno del compito e degli strumenti che hai fornito.
La conclusione pratica sta in una frase. Se il tuo RAG fallisce perché una sola ricerca non riesce a raccogliere tutta la risposta, un loop può aiutare. Se fallisce perché l'ingestione o il chunking sono fatti male, non farà che ripetere il problema, più lentamente.
#Agentic RAG o RAG in un solo passaggio: la differenza
Approfitta della nostra esperienza e di un percorso guidato per costruire il tuo RAG locale e lavorare con i tuoi documenti.
- Spazio online a vita
- PDF + file
- Garanzia di rimborso di 30 giorni
I componenti di base restano gli stessi: embedding, database vettoriale, modello di generazione. Se non ti sono familiari, inizia dall'introduzione al RAG locale. Ciò che cambia è chi decide la sequenza. In un RAG classico è il tuo codice; in un RAG agentico è il modello, entro i limiti che il codice gli impone.
- Query
- RAG classico: la domanda dell'utente, talvolta riscritta una volta. Agentico: il modello formula le proprie query e può scomporre una domanda in più domande.
- Numero di ricerche
- RAG classico: una, nota in anticipo. Agentico: variabile da una domanda all'altra, entro un limite che fissi tu.
- Fonti
- RAG classico: in genere un solo indice. Agentico: più strumenti possibili (indice vettoriale, ricerca per parole chiave, database SQL), tra cui il modello sceglie.
- Controllo del risultato
- RAG classico: nessuno, il modello scrive con ciò che ha ricevuto. Agentico: il modello può giudicare insufficienti i passaggi e rilanciare la ricerca, il che non è una garanzia: può anche sbagliare questo giudizio.
- Requisito per il modello
- RAG classico: qualsiasi modello in grado di scrivere a partire da estratti. Agentico: un modello che gestisce correttamente la chiamata di strumenti.
- Prevedibilità
- RAG classico: tempo di risposta abbastanza regolare. Agentico: tempo variabile e percorso da controllare nelle tracce.
Il ciclo è composto da tre meccanismi. La pianificazione: scomporre la domanda in sotto-domande. L'uso degli strumenti: tradurre ogni sotto-domanda in una chiamata. Il rilancio: leggere il risultato e decidere se riformulare o concludere. Per l'architettura generale di un agente (memoria, misure di sicurezza, supervisione), consulta la guida dedicata: qui ci interessa solo il ciclo di ricerca.
Esiste anche una via di mezzo che spesso si dimentica: la pipeline a fasi fisse. Una riscrittura della query, una ricerca ibrida e poi un reranker vengono eseguiti sempre nello stesso ordine, senza decisioni del modello. Non è agentico, ed è spesso la prima cosa da provare.
#Quando vale la pena usare l'agentic RAG
Il criterio giusto riguarda la forma delle tue domande, non il livello di sofisticazione desiderato. Guarda i fallimenti reali del tuo RAG attuale, poi classificali.
- Domande multi-hop
- La risposta a una prima ricerca determina la seconda: trovare il fornitore di un contratto, poi la clausola che si applica a quel fornitore.
- Confronti tra documenti
- «Confronta il preavviso dei contratti A e B» richiede due ricerche distinte. Una sola query può restituire cinque passaggi dello stesso contratto.
- Più fonti di natura diversa
- Un dato numerico in un database SQL e una spiegazione nei PDF. Il modello sceglie lo strumento in base alla domanda, come descrive il corso di Microsoft per le interazioni complesse con un database.
- Tolleranza all'attesa
- Ricerca documentale, preparazione di un dossier, elaborazione in background: qualche decina di secondi in più non disturba nessuno se il risultato viene riletto.
- Correttezza prioritaria rispetto alla velocità
- Quando una risposta incompleta costa cara, una fase di verifica è difendibile, a condizione di mantenere una revisione umana sulle decisioni impegnative.
Al contrario, resta su un RAG semplice in queste situazioni:
- FAQ e domande con una sola fonte
- La risposta si trova in un passaggio: basta una ricerca, un ciclo aggiunge solo attesa.
- Assistente conversazionale su hardware modesto
- L'utente si aspetta una risposta rapida e il modello gira già vicino ai suoi limiti.
- Ricerca che non trova i passaggi giusti
- Correggi prima la suddivisione, gli embedding e la ricerca ibrida. Rilanciare una ricerca mal configurata produce altri risultati scadenti.
- Calcolo esatto su dati strutturati
- Una query SQL scritta e testata è più affidabile di un agente che ne improvvisa una.
- Collegamenti multipli tra entità su tutto il corpus
- Se l'esigenza è esplorare relazioni su larga scala, un approccio basato su grafi risponde a un altro problema: vedi la guida GraphRAG.
#Il costo in latenza e in modello
Nel cloud, ogni giro del ciclo si vede in fattura. In locale, si vede sull'orologio e nella memoria. Contano tre voci.
#La latenza si moltiplica
Per N ricerche, il modello genera N + 1 volte: una volta prima di ogni ricerca, un'ultima per la risposta. Un RAG a passaggio singolo genera una volta sola. Poiché il prompt si allunga a ogni giro, ogni generazione rilegge più testo, tranne ciò che la cache di contesto del runtime permette di riutilizzare. Il tempo totale dipende dal modello, dalla quantizzazione e dalla macchina; misuralo sul tuo sistema invece di fidarti di un dato generico.
#Il contesto si riempie in fretta
Calcolo illustrativo: 4 passaggi da 1 200 caratteri rappresentano circa 1 400 token, considerando da 3 a 4 caratteri per token. Cinque ricerche aggiungono quindi circa 7 000 token, senza contare la domanda, le istruzioni e i ragionamenti del modello. Con num_ctx a 8192, il margine è quasi scomparso. Ollama tronca allora il contesto, e i primi risultati, talvolta le istruzioni, possono uscire dalla finestra senza che l'applicazione lo segnali chiaramente.
Aumentare num_ctx consuma più memoria e rallenta i giri successivi. Spesso conviene restituire meno passaggi, o riassumerne il contenuto prima di reinserirlo.
#Il modello deve reggere il ciclo
Il modello deve produrre chiamate agli strumenti ben formate, poi giudicare se ciò che ha letto è sufficiente. Verifica il supporto con ollama show: la sezione Capabilities deve menzionare tools. Questa verifica dice che il formato è gestito, non che il modello prende buone decisioni.
- RTX 3060 12 GB o RTX 4070 12 GB
- Un modello da 7 a 9B in Q4_K_M (riferimento del sito: 7B ≈ 5 GB) lascia spazio per il contesto e l'embedding. È il punto di partenza dell'esempio qui sotto, con qwen3.5:9b.
- RTX 4080 16 GB
- Un 14B in Q4_K_M (≈ 9 GB) ci sta con un margine più comodo per un contesto ampliato.
- RTX 4090 24 GB o M4 Pro da 24 a 48 GB
- Diventa possibile considerare un modello più grande, come qwen3.8:27b (circa 18 GB). Con 24 GB, tieni d'occhio quanta memoria resta dopo aver ampliato il contesto.
#Scegliere un orchestratore
L'orchestratore esegue il loop: trasmette le chiamate agli strumenti, restituisce i risultati al modello e applica i limiti. Esistono tre strade, tutte compatibili con un modello locale.
- Ciclo scritto a mano
- Una ventina di righe attorno all'API di chat di Ollama e al suo parametro tools. Adatto per capire il meccanismo o per un caso molto semplice. I limiti e le tracce dovrai scriverli tu.
- LangGraph
- Il ciclo è un grafo esplicito di nodi e archi, con stato, limite di ricorsione e streaming dei passaggi. Una buona scelta se vuoi controllare ogni transizione. È quella del nostro esempio.
- LlamaIndex
- Interessante se la tua ingestione e i tuoi indici sono già lì: i suoi agenti riutilizzano i tuoi motori di query come strumenti.
Non scegliere in base alla popolarità. Se la tua pipeline funziona già con un framework, restaci. In ogni caso, blocca le versioni: queste librerie evolvono rapidamente e le loro funzioni predefinite cambiano. Il nostro esempio scrive quindi il grafo esplicitamente, il che rende anche leggibile il ciclo.
#Prerequisiti
- Ollama
- Installato e in ascolto su http://localhost:11434.
- Python
- Un ambiente virtuale recente. Verifica la versione richiesta dai pacchetti al momento dell'installazione.
- Documenti
- Alcuni file Markdown o di testo in una cartella mes_documents. Per i PDF, riprendi l'ingestione del tutorial ChromaDB.
- Memoria
- Circa 6 GB liberi per un modello da 9B e il suo contesto, di più se aumenti num_ctx.
#Esempio di agentic RAG con LangGraph e Ollama
L'esempio costruisce un agente che dispone di un solo strumento di ricerca, basato su un indice ChromaDB locale. Resta volutamente minimale perché il ciclo sia visibile.
#Passaggio 1: installare i modelli e i pacchetti
#Passaggio 2: indicizzare i documenti
La suddivisione per caratteri serve solo a mantenere breve l'esempio. Su un corpus reale, usa una suddivisione che rispetti la struttura e un modello di embedding validato sui tuoi testi in francese.
#Passo 3: scrivere lo strumento e il ciclo
La descrizione dello strumento conta: è quella che il modello legge per decidere se chiamarlo. L'istruzione di sistema impone di cercare prima di rispondere, di separare le sotto-domande e di ammettere l'assenza di informazioni.
#Passo 4: leggere la traccia
Il vantaggio di stream_mode="values" è che mostra ogni messaggio. Leggi la traccia prima della risposta finale, aiutandoti con questa griglia:
- 01Il modello chiama lo strumento?Se risponde direttamente, non sta cercando: rafforza l'istruzione o cambia modello.
- 02Le query hanno senso?Per il confronto, l'ideale è vedere una query per contratto. Una sola query che riprende tutta la domanda indica che la scomposizione non sta avvenendo.
- 03I passaggi rispondono alla domanda?Se gli estratti sono fuori tema, il problema sta nell'indice, non nell'agente.
- 04La risposta si basa sugli estratti?Verifica ogni citazione tra parentesi quadre nel passaggio corrispondente.
#Passo 5: limitare il ciclo
Ogni ricerca consuma due passaggi del grafo (agente, poi strumento). Un limite di 12 consente quindi cinque ricerche, poi la risposta finale. Oltre questo limite, LangGraph solleva un errore GraphRecursionError (modulo langgraph.errors): intercettalo nella tua applicazione e restituisci un messaggio esplicito, invece di lasciare l'utente davanti a uno stack trace.
#Insidie e risoluzione dei problemi
- Il modello non chiama mai lo strumento
- Verifica tools in ollama show, riformula la descrizione dello strumento e prova un altro modello. Non compensare con un'istruzione sempre più lunga.
- Ripete la stessa ricerca
- Il modello gira a vuoto. Abbassa il limite e, nello strumento, restituisci un messaggio chiaro quando la query è già stata eseguita.
- La risposta dimentica i primi risultati
- Probabile segno di contesto troncato. Riduci n_results, suddividi in modo più fine o aumenta num_ctx se la memoria lo consente.
- Le risposte diventano molto lente
- Controlla ollama ps: forse una parte del modello è sul processore, oppure i modelli si alternano in memoria. Conta anche il numero di turni nella traccia.
- Inventa anche se non ha trovato nulla
- Il ciclo non impedisce le invenzioni. Controlla le citazioni tramite codice: ogni fonte citata deve comparire nei risultati degli strumenti della conversazione.
- Uno strumento troppo potente
- Un agente che legge documenti ne riceve anche il contenuto, eventualmente ostile. Dagli strumenti in sola lettura e prevedi una convalida umana per qualsiasi azione che modifichi qualcosa.
#Decidere in base alle tue domande
I dati pubblicati altrove riguardano altri corpus, altri modelli e altre impostazioni. Solo un confronto sui tuoi dati permette di decidere, e non richiede molto hardware.
- 01Creare un set di domandePrendi domande reali di cui conosci la risposta e i passaggi di origine, mescolando domande semplici e domande a più salti. Tieni traccia del tipo di ogni domanda.
- 02Stabilire un riferimentoFalle passare nel tuo RAG attuale, senza agente. Annota se è stato ritrovato il passaggio giusto, se la risposta è corretta e il tempo totale.
- 03Cambiare una cosa solaEsegui lo stesso set con l'agente, sullo stesso indice e con lo stesso modello, sulla stessa macchina.
- 04Leggi per tipo di domandaGuarda il risultato separatamente per le domande semplici e per quelle complesse, e annota il numero di ricerche per domanda. Una media complessiva può nascondere un guadagno sulle une e una perdita di tempo sulle altre.
- 05Tenere ciò che è giustificatoSe ne traggono vantaggio solo alcune domande, può bastare un routing: RAG diretto come impostazione predefinita, ciclo per le domande rilevate come complesse.
Per automatizzare la parte di qualità di questo confronto, la guida dedicata a Ragas presenta metriche adatte. Annota anche la versione dei pacchetti, il modello, la quantizzazione e num_ctx: senza questi dati, il tuo risultato non sarà confrontabile il mese successivo.
#Per approfondire
L'agentic RAG si appoggia a un RAG che funziona già. Queste guide coprono le basi da stabilizzare prima, gli approcci affini e l'architettura dell'agente.
Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.