Costruire un RAG in locale, dal PDF alla risposta
La pipeline completa su una macchina sola: estrarre il testo dai PDF, indicizzarlo, interrogarlo. Con i punti dove si inciampa davvero e come si capisce se sta funzionando.
Il video parte solo se lo chiedi: nessuna richiesta a YouTube prima del click.
Le tre lezioni precedenti hanno spiegato i pezzi: cos’è il RAG, come si spezzano i documenti, dove finiscono i vettori. Qui li mettiamo in fila su una macchina sola, senza mandare niente fuori casa.
La pipeline minima ha cinque passaggi, e nessuno di questi richiede una scheda grafica:
PDF/appunti → [estrazione] → [chunking] → [embedding] → [archivio]
│
risposta ← [modello] ← [recupero] ←─┘
Il modello linguistico serve solo all’ultimo passo. Tutto il lavoro che decide la qualità avviene prima, ed è la ragione per cui un RAG mediocre non migliora cambiando modello.
Passo 1: tirare fuori il testo (il punto più sottovalutato)
Un PDF può contenere il testo in due modi completamente diversi, e la differenza decide quanto lavoro ti aspetta.
PDF digitale PDF scansionato
il testo è dentro il file la pagina è una fotografia
come caratteri fatta di pixel
→ basta leggerlo → serve un OCR che lo riconosca
I libri moderni, gli articoli scientifici e i manuali generati da un word processor sono digitali: una libreria di base estrae il testo in un secondo. Le fotocopie, i libri vecchi digitalizzati e i documenti scannerizzati sono immagini: senza riconoscimento ottico ne esce una pagina vuota. Esistono anche i casi misti, i più insidiosi: corpo del testo nativo, tabelle e formule come immagini. Lì l’estrazione riesce e perde silenziosamente proprio le parti che ti servivano.
Conviene ragionare a livelli, dal più economico:
| Livello | Cosa usa | Quando basta |
|---|---|---|
| 1 | Estrattori di testo nativo | PDF digitali: la maggior parte |
| 2 | OCR con analisi del layout, su CPU | Scansioni, documenti misti, tabelle |
| 3 | Strumenti specializzati, scheda grafica opzionale | Formule, impaginazioni complesse |
| 4 | Modelli visione-linguaggio | Documenti dove tutto il resto fallisce |
La regola pratica è partire dal livello 1 e guardare cosa è uscito: apri il testo estratto di due o tre documenti e leggilo. Trenta secondi lì risparmiano un pomeriggio di domande a un archivio pieno di niente.
Due dettagli che rovinano le estrazioni riuscite: le pagine su due colonne, che molti estrattori leggono in orizzontale mescolando le due metà riga per riga, e le intestazioni e piè di pagina ripetuti, che finiscono in ogni pezzo e diventano rumore identico su tutto l’archivio.
Passo 2 e 3: spezzare e vettorizzare
Il chunking l’abbiamo visto: ricorsivo, intorno ai mille token, con un po’ di sovrapposizione, e i metadati attaccati a ogni pezzo. Qui conta ricordare una cosa sola: si spezzano i documenti, non le domande — la domanda si vettorizza intera, con lo stesso modello.
Per gli embedding in locale servono due decisioni:
Quale modello. Uno multilingue se i tuoi documenti sono in italiano: parecchi modelli diffusi sono addestrati soprattutto sull’inglese e rendono meno sulle altre lingue. Le dimensioni del vettore contano meno di quanto sembri: più grande non vuol dire più preciso, vuol dire più spazio occupato e ricerche più lente.
In blocco, non uno alla volta. Calcolare gli embedding pezzo per pezzo, con una chiamata per ciascuno, è l’errore che fa sembrare lenta l’indicizzazione. In blocchi da qualche decina si va molto più veloce sulla stessa macchina.
Passo 4 e 5: archiviare e interrogare
L’archivio in locale è quello che si installa e basta: tiene insieme vettore, testo e metadati, e salva su disco da solo. Sulla dimensione tipica di una libreria personale — poche migliaia di pezzi — l’indice esatto è più che sufficiente.
L’interrogazione è dove si decidono due parametri che contano più del modello.
Quanti pezzi recuperare. Tre o cinque. La tentazione di metterne quindici “per sicurezza” peggiora la risposta: il modello si distrae e la finestra di contesto si riempie di roba mediocre.
Cosa dire al modello. Il prompt di sistema deve essere esplicito su due punti: rispondi solo dal contesto fornito, e se la risposta non c’è dillo. Senza la seconda frase il modello colma il vuoto con la sua conoscenza generale, e tu non hai modo di accorgertene: la risposta suona identica a una corretta.
SISTEMA: Rispondi usando solo il contesto qui sotto.
Se la risposta non è nel contesto, di' che non lo sai.
Cita la fonte fra parentesi.
CONTESTO: [pezzo 1 — manuale.pdf, p. 145]
[pezzo 2 — manuale.pdf, p. 146]
DOMANDA: ...
Una temperatura bassa aiuta: qui non serve creatività, serve che il modello resti aderente a quello che legge. È lo stesso ragionamento della lezione sui parametri di generazione.
Come si capisce se funziona
Un RAG non si valuta “a sensazione”, si valuta a pezzi. E i pezzi sono due, perché i modi di sbagliare sono due.
Il recupero. Prendi dieci domande di cui conosci la risposta e per ognuna segnati in quale documento e a quale pagina si trova. Poi guarda i pezzi recuperati, non la risposta finale: il pezzo giusto è fra i primi tre? Se non c’è, il problema è a monte e nessun cambiamento sul modello lo risolve.
La generazione. Se il pezzo giusto c’era ma la risposta è sbagliata o incompleta, il problema è nel prompt, nella temperatura o nel modello.
Questa separazione è tutto il metodo: senza, si finisce a cambiare modello linguistico per risolvere un problema di chunking.
I guasti tipici, e cosa toccare
| Sintomo | Prima cosa da guardare |
|---|---|
| Recupera pezzi che non c’entrano | Modello di embedding poco adatto alla lingua, o pezzi troppo grandi |
| Risposte frammentarie, senza contesto | Pezzi troppo piccoli: alza dimensione e sovrapposizione |
| Il pezzo giusto c’è ma annegato nel rumore | Pezzi troppo grandi, o troppi pezzi passati al modello |
| Risponde da sé, ignorando i documenti | Prompt di sistema debole, temperatura alta, modello piccolo |
| Indicizzazione lentissima | Embedding uno alla volta invece che in blocco |
| Inventa citando le fonti | Manca l’istruzione a dire “non lo so” |
L’ultima riga è la più insidiosa: un sistema che cita la fonte sembra affidabile. La citazione dice da dove viene il pezzo recuperato, non che la frase generata sia contenuta lì dentro.
Quando non vale la pena
Costruire tutto questo ha senso se i documenti sono tanti, cambiano, o non devono uscire di casa. Per venti pagine da capire, incollarle nel prompt resta più veloce e più accurato. E se il fine è “cercare nei miei documenti” senza scrivere codice, un’interfaccia locale con il RAG già dentro — Open WebUI appoggiata a Ollama — arriva al risultato in mezz’ora. Il valore di costruirla a mano è un altro: vedere i parametri e poterli spostare, che è anche l’unico modo per capire perché una risposta è venuta storta.
In sintesi
| Concetto | In una riga |
|---|---|
| La pipeline | Estrai, spezza, vettorizza, archivia, recupera, rispondi |
| Il passo sottovalutato | L’estrazione: un PDF scansionato senza OCR dà pagine vuote |
| Controllo da fare subito | Leggere il testo estratto prima di indicizzare |
| Embedding | In blocco, e con un modello adatto alla lingua dei documenti |
| Quanti pezzi passare | Tre o cinque, non quindici |
| Prompt | “Solo dal contesto” e “se non c’è, dillo”: entrambe le frasi |
| Come si valuta | Prima il recupero, poi la generazione: sono guasti diversi |
| Quando evitarlo | Pochi documenti stabili: incollarli è meglio |
- RAG
- Locale
- Ollama
Lezioni collegate
- Cos'è il RAG: far leggere i tuoi documenti a un modello
Un modello non conosce i tuoi file. Il RAG glieli fa consultare al momento della domanda: prima cerca, poi risponde. È la differenza fra un esame a libro chiuso e uno a libro aperto.
- Chunking: come si spezzano i documenti
La scelta più sottovalutata di tutta la pipeline RAG. Da come tagli i testi dipende cosa il sistema riuscirà a trovare: un chunking sbagliato rende inutili il miglior modello di embedding e il miglior LLM.
- Database vettoriali: cercare per significato
Dove finiscono i vettori dei tuoi documenti e come si fa a ritrovarli in fretta. Indici, metriche di distanza e la scelta fra le opzioni che contano davvero, senza cambiare strumento tre volte.