Capitolo 10 · RAG · 9 min

Leggere i tuoi documenti

Come un LLM accede a migliaia di pagine senza memorizzarle. Embeddings, ricerca semantica, contesto iniettato.

Il limite che il contesto non può risolvere

Immagina di voler costruire un assistente capace di rispondere a domande su tutta la documentazione interna della tua azienda: 50.000 pagine, aggiornate ogni settimana.

Anche con una finestra da 1 milione di token, non puoi metterci tutto. E se potessi, il costo sarebbe proibitivo e la qualità delle risposte peggiorerebbe: i modelli faticano a estrarre informazioni precise in contesti molto lunghi.

Serve un altro approccio. È il RAGRetrieval-Augmented Generation.

L'idea fondamentale

Invece di dare tutto il documento al modello, gli dai solo i passaggi pertinenti per la domanda. Per farlo servono due cose:

  1. Un indice: una rappresentazione vettoriale di tutti i documenti, salvata in anticipo.
  2. Un motore di ricerca semantica: quando arriva una domanda, trova i passaggi semanticamente più vicini.

I passaggi trovati vengono poi iniettati nel contesto dell'LLM insieme alla domanda. Il modello risponde appoggiandosi a questi estratti.

È esattamente ciò che fa la ricerca semantica con gli embeddings che conosci già dal capitolo 03 — ma applicata a documenti reali.

Il pipeline in tre passaggi

1. Indicizzazione (una sola volta)

Si taglia il documento in chunks — estratti di qualche centinaio di token (con una leggera sovrapposizione per non tagliare il senso al confine).

Ogni chunk viene poi convertito in vettore da un modello di embedding. Questi vettori vengono salvati in un database vettoriale (Pinecone, Chroma, pgvector…).

Questo passaggio si fa una sola volta, o a ogni aggiornamento del documento.

2. Ricerca (a ogni domanda)

Quando arriva una domanda, la convertiamo in vettore con lo stesso modello di embedding.

Calcoliamo la similarità coseno tra questo vettore-domanda e i vettori-chunk della base. I k chunk più vicini vengono recuperati — in genere 3-5. (In realtà non si confronta con tutti i chunk: superate qualche decina di migliaia di vettori, i database vettoriali usano indici approssimati — HNSW, IVF — che trovano i vicini più prossimi senza percorrere tutto. È anzi la loro ragione d'essere.)

Questa è la ricerca semantica: "vicino" non significa "contiene le stesse parole", ma "esprime un significato simile".

3. Generazione

I chunk recuperati vengono assemblati in un prompt:

Estratti dal documento:
[Estratto 1 — ...]
[Estratto 2 — ...]
[Estratto 3 — ...]

Domanda: {domanda dell'utente}

Questo prompt viene inviato all'LLM, che genera una risposta basandosi sugli estratti. Il modello non ha memorizzato il documento: lo legge nel momento in cui gli fai la domanda.

Visualizzazione del pipeline

Ecco il sistema in azione su un mini-corpus di planetologia. Scegli una domanda: osserva quali chunk vengono recuperati nello spazio vettoriale e come vengono assemblati in contesto.

Scegli una domanda: viene embedded, confrontata con i chunk del corpus, e i più pertinenti vengono iniettati nel prompt prima della generazione. È questa deviazione che permette a un LLM di rispondere su documenti che non ha mai visto durante il training.

Due cose da portarsi via da questa manipolazione. Primo, i chunk recuperati non sono quelli che contengono le parole della domanda: chiedi "qual è il pianeta più grande?" e ottieni i giganti gassosi, mentre la parola "grande" non compare da nessuna parte in quegli estratti. È la vicinanza nello spazio vettoriale a decidere, non il vocabolario. Secondo, il modello non vede mai il corpus intero: riceve solo la manciata di estratti selezionati. Tutta la qualità di un RAG si gioca quindi prima della generazione. Se il chunk giusto non viene recuperato, nessuna finezza di prompt lo recupera — è per questo che il resto di questo capitolo parla soprattutto di taglio e di ricerca.

Dimensione dei chunk: una vera scelta ingegneristica

Il taglio in chunk non è banale. È spesso la prima fonte di problemi in un sistema RAG.

Chunk troppo piccoli: ogni chunk è poco informativo. Recuperiamo frammenti che, fuori contesto, non permettono al modello di rispondere correttamente.

Chunk troppo grandi: superiamo la precisione dell'embedding. Un vettore che rappresenta 2.000 token è una media sfocata: verrà recuperato per alcune domande, ma il contenuto pertinente sarà annegato nel testo.

Regola pratica: chunk da 200 a 500 token, con overlap del 10-15%. Il parametro giusto dipende dalla struttura dei tuoi documenti.

Quale modello di embedding usare?

Non tutte le domande arrivano ai chunk giusti con lo stesso embedding. Un modello addestrato su italiano generalista recupererà male del codice Python; un modello addestrato sul codice recupererà male scambi medici.

Le scelte che ricorrono in pratica:

  • text-embedding-3-small / -large (OpenAI) — qualità solida, generalista, multilingua. A lungo la scelta di default quando si cominciava; oggi superata sui benchmark, ma ancora perfettamente utilizzabile.
  • bge-large / bge-m3 (BAAI) — open-source, eccellente in multilingua. Dominavano i benchmark MTEB nel 2024.
  • Gemini Embedding (Google) — in testa al MTEB inglese.
  • Qwen3-Embedding (Alibaba) — il migliore tra i modelli a pesi aperti, che puoi ospitare tu stesso.
  • Voyage 3.x, Cohere embed-v4, Jina v4 — i riferimenti commerciali del momento, l'ultimo dei quali multimodale (testo e immagini nello stesso spazio).
  • all-MiniLM-L6-v2 (Sentence-Transformers) — piccolo, veloce, distribuibile in locale. Buon rapporto qualità/costo per casi d'uso semplici.
  • Modelli specializzati per dominio (codice, biomedico, giuridico) — sempre migliori sulla loro nicchia, più deboli altrove.

Questa classifica si muove ogni sei mesi. E attenzione a come la leggi: i punteggi MTEB v2 non si confrontano con quelli della v1, i task sono cambiati tra le due.

Regola pratica: testare due o tre modelli sui tuoi dati e sulle tue domande. La classifica MTEB dice poco del tuo caso d'uso specifico.

Il reranker: una seconda passata

La ricerca vettoriale ha un difetto: è veloce ma grossolana. Un embedding di qualche centinaio di dimensioni è una media sfocata di un testo. Molti chunk "più o meno pertinenti" galleggiano in superficie, e quelli davvero buoni a volte vengono annegati.

Da qui un passaggio diventato standard nei sistemi RAG seri: il reranker.

L'idea in due tempi:

  1. Prima passata (ricerca vettoriale) — recupera i 50 o 100 chunk più vicini. Veloce.
  2. Seconda passata (reranking) — un piccolo modello (spesso un cross-encoder) valuta ogni coppia (domanda, chunk) insieme, dà un punteggio preciso, e tiene i top 5-10. Lento per chunk, ma lo si fa solo sui 50 candidati della prima passata.

Il reranker vede la domanda e il chunk allo stesso tempo, cosa che l'embedding non fa. Coglie sottigliezze semantiche che la ricerca vettoriale manca. Cohere, Jina AI, BAAI offrono reranker pronti all'uso.

Senza reranker, il tuo RAG si appiattisce. Con uno, la qualità salta di un livello senza cambiare il resto della pipeline.

Domanda legittima: perché non fare semplicemente una ricerca per parole chiave, come un motore di ricerca classico?

La ricerca vettoriale è complementare, non un sostituto. Trova passaggi semanticamente vicini anche quando la formulazione è diversa. "Quale pianeta ruota più lentamente?" può recuperare un chunk che parla di "periodo orbitale" senza che quelle parole siano nella domanda.

In pratica, i sistemi migliori combinano i due approcci: hybrid search — un punteggio che combina similarità vettoriale e corrispondenza di parole chiave (BM25).

I limiti del RAG

Il RAG non è magia. Ecco i problemi più frequenti:

Chunk tagliato male. Se una risposta si estende su due chunk e il confine cade nel punto sbagliato, nessuno dei due chunk è sufficiente da solo.

Il "lost in the middle" dentro il chunk. Se il chunk è troppo lungo, le informazioni importanti possono finire al centro ed essere ignorate dal modello.

Domanda ambigua. Se la domanda è vaga, l'embedding-domanda sarà lontano dalla maggior parte dei chunk pertinenti. Soluzione: riformulare la domanda, o generarne più varianti.

Allucinazioni sugli estratti. L'LLM può estrapolare oltre ciò che dicono i chunk. Il RAG riduce le allucinazioni, non le elimina.

Cosa cambia il RAG in pratica

Il RAG è oggi la tecnica di riferimento per collegare un LLM a dati privati o recenti. Quasi tutti i chatbot aziendali, gli assistenti di documentazione e gli strumenti di monitoraggio si appoggiano a questo.

Ma la pipeline classica — embed, retrieve, generate — è un'architettura "passiva": il modello riceve una domanda, cerca chunk, risponde. Dal 2025 le fa concorrenza, su molti casi d'uso, la ricerca agentica: si dà al modello uno strumento di ricerca e lo si lascia cercare in loop, riformulare, scavare finché non ha ciò che gli serve. Per compiti più complessi — cercare, poi agire in base al risultato, poi cercare ancora — bisogna salire di un livello.

Aggiornato il