ingestion RAG
Come due colonne di legalese mi hanno insegnato tutto sulla vettorializzazione ad alta fedeltà — e perché 3072 dimensioni non sono un lusso
Avevo un PDF di testo giuridico. Due colonne, articoli di legge, DLGS, note a piè di pagina. Ho lanciato il parser. Quello che è uscito era incomprensibile.
Ci sono momenti in cui la tecnologia ti guarda negli occhi e ti dice: ricomincia da capo.
Per me è arrivato davanti a uno schermo con un output di testo che mescolava la colonna sinistra con quella destra, spezzava gli articoli di legge a metà, fondeva le note a piè di pagina con il corpo del testo.
Il PDF era perfettamente leggibile. Il parser lo aveva trasformato in una poltiglia semantica.
E io dovevo costruirci sopra un sistema RAG che rispondesse a domande giuridicamente precise.
Il problema che nessuno racconta
Quando si parla di sistemi RAG, si parla quasi sempre di retrieval — come il sistema recupera le informazioni, come le presenta, come evita le allucinazioni.
Raramente si parla di quello che viene prima: l’ingestion RAG, la fase in cui i tuoi documenti vengono trasformati in qualcosa che l’AI può effettivamente capire.
Eppure è lì che si vince o si perde tutto.
Un LLM non può leggere un PDF di 2500 pagine ad ogni query. L’ingestion serve a fare quattro cose in sequenza: estrarre il testo grezzo, spezzettarlo in blocchi logici, tradurre quei blocchi nella lingua madre dell’AI — i vettori numerici — e salvarli in un database interrogabile in millisecondi.
È l’ETL dell’era dell’intelligenza artificiale. E vale una regola antica: garbage in, garbage out.
Con i documenti giuridici, il garbage entra facilissimo.
Due colonne di legalese — e un parser in crisi
I manuali giuridici sono l’incubo dei parser tradizionali.
Due colonne affiancate. Note a piè di pagina che si intrecciano con il testo principale. Tabelle sanzionatorie. Rimandi interni tra articoli. DLGS con strutture gerarchiche profonde — commi, lettere, numeri.
Un parser standard legge il PDF riga per riga, da sinistra a destra, dall’alto in basso. Risultato: mescola la colonna sinistra con quella destra, produce frasi senza senso, perde il contesto tra la descrizione di un reato e la relativa sanzione.
Ho provato diversi approcci. Ho impazzito, per usare le parole giuste.
Poi ho scoperto due cose che hanno cambiato tutto.
La prima scoperta: un parser che capisce la geometria
La prima svolta è stata trovare un parser che non leggesse il PDF come testo, ma come layout.
👉 PyMuPDF4LLM analizza la geometria della pagina — sa dove finisce la colonna sinistra e dove inizia quella destra, riconosce le tabelle, linearizza il testo nell’ordine corretto e converte le tabelle in Markdown pulito.
Il risultato non era più poltiglia. Era testo strutturato, gerarchico, leggibile — con titoli, sottotitoli, articoli e commi al posto giusto.
Ma risolvere l’estrazione era solo metà del problema.
La seconda scoperta: 3072 dimensioni non sono un lusso
L’altra cosa che ho capito lavorando sui testi giuridici riguarda i vettori — la rappresentazione matematica del testo che permette al sistema di fare ricerca semantica.
Per capire cosa significa lavorare ad alta dimensionalità: con 2 dimensioni individui un punto su un foglio, con 3 lo collochi nello spazio reale. Con 3072 dimensioni stai lavorando in uno spazio matematico con 3072 assi distinti, ognuno dei quali rappresenta una sfumatura semantica del linguaggio.
Nel legalese questa risoluzione non è un optional.
La differenza tra annullamento e nullità, o tra detenzione e possesso, è minima nel linguaggio comune. In giurisprudenza è abissale. Un vettore a bassa dimensionalità le tratta come sinonimi. A 3072 dimensioni, lo spazio matematico è sufficiente per mapparle come concetti distinti.
👉 Alta dimensionalità = alta fedeltà semantica = risposte giuridicamente precise.
Ho usato text-embedding-3-large di OpenAI — il modello che genera vettori a 3072 dimensioni. La differenza nel retrieval su documenti complessi è stata immediata e misurabile.
Come funziona la pipeline completa
L’architettura è scritta interamente in Python — la scelta naturale per questo tipo di lavoro, dove l’ecosistema AI è nativo e le dipendenze si gestiscono senza attriti.
Il flusso è questo:
Il parser legge il PDF e riconosce il layout. Il testo esce strutturato in Markdown, con la gerarchia degli articoli intatta.
Il chunking avviene in due fasi: prima il Markdown Header Text Splitter divide seguendo capitoli, articoli e commi — rispettando la struttura logica del documento. Poi il Recursive Character Splitter interviene solo sugli articoli troppo lunghi, tagliando alla fine di un paragrafo, mai a metà di una norma.
La vettorializzazione chiama l’API OpenAI in batch — pacchetti da 100 chunk alla volta, per evitare colli di bottiglia su manuali da milioni di caratteri. I vettori finiscono in Qdrant, pronti per la ricerca semantica in millisecondi.
L’interfaccia è costruita con Streamlit. Un’ingestion su documenti complessi richiede 20–30 minuti — ho costruito un logger in tempo reale che mostra il progresso blocco per blocco. L’utente vede letteralmente la macchina pensare.
La libertà che ne deriva
La cosa più bella di questa architettura è quello che succede dopo.
Una volta che i documenti sono strutturati matematicamente in Qdrant, nella fase di chat puoi interrogare il database con qualsiasi modello generativo — Gemini, GPT, o un modello locale come Llama. La fonte rimane sotto controllo totale. Il modello è intercambiabile.
Un’ingestion RAG ben costruita non ti lega a nessun vendor. Ti libera da tutti.
Ho applicato questa pipeline a documenti tecnici industriali, manuali di macchinari, procedure aziendali riservate. Il principio non cambia — cambia la complessità del layout da gestire.
Se vuoi approfondire come questa pipeline si integra in un’architettura RAG enterprise completa con memoria episodica, l’ho raccontato su Medium.
Cosa succede quando porti questa pipeline su domini ancora più specializzati — medicina, finanza, ingegneria industriale — dove ogni termine tecnico ha un peso specifico insostituibile?