Perché RAG e non fine-tuning
Il fine-tuning allena il modello su nuovi dati — efficace ma costoso (GPU time, dataset labeling, retraining ad ogni aggiornamento dei dati) e opaco (il modello "impara" le informazioni ma non cita le fonti, né possiamo verificare da dove viene un'affermazione specifica).
RAG è un approccio diverso: il modello rimane generico, ma a ogni query vengono recuperati i chunk di documento più rilevanti e iniettati nel contesto. Il modello risponde basandosi su quel contesto. I vantaggi: i dati restano aggiornabili senza retraining, le risposte sono verificabili (sappiamo da quale documento viene ogni affermazione), e il costo è molto più contenuto.
Il pipeline RAG — passo per passo
Ingestion e parsing
I documenti (PDF, DOCX, HTML, email) vengono parsati e normalizzati. LlamaIndex supporta decine di reader nativi. Attenzione ai PDF scansionati: richiedono OCR (Tesseract o cloud OCR) prima del parsing. La qualità dell'ingestion determina la qualità di tutto il sistema downstream.
Chunking strategy
Il documento viene spezzato in chunk per il retrieval. La strategia di chunking impatta enormemente la qualità finale. Tre approcci principali: fixed-size (semplice ma perde contesto ai confini), sentence-boundary (rispetta i confini frasali), hierarchical parent-child (recupera chunk piccoli ma inietta il paragrafo padre). Nella maggior parte dei progetti aziendali, il hierarchical chunking produce i risultati migliori.
Embedding e indicizzazione
Ogni chunk viene convertito in un vettore numerico (embedding) che ne rappresenta il significato semantico. Modelli consigliati: text-embedding-3-small (OpenAI, bilancio costo/qualità), nomic-embed-text (locale, open-source, ottimo per dati sensibili), BGE-M3 (multilingue, consigliato per documenti italiani). I vettori vengono salvati in un vector store.
Vector store
Chroma per lo sviluppo locale (zero configurazione). Qdrant per la produzione (self-hosted, payload filtering, scalabile). Pinecone come alternativa managed. La scelta dipende dai requisiti di hosting dei dati: per documenti aziendali sensibili, un Qdrant self-hosted in datacenter privato è spesso obbligatorio per compliance.
Query e retrieval
La query utente viene embeddata con lo stesso modello usato per l'indicizzazione. Viene eseguita una similarity search nel vector store (tipicamente top-K = 5-10 chunk). La threshold di similarità minima (es. 0.75) evita di iniettare chunk irrilevanti nel contesto.
Re-ranking con cross-encoder
Il retrieval iniziale (bi-encoder) è veloce ma impreciso. Un cross-encoder (es. ms-marco-MiniLM-L-6-v2) rivaluta i top-K chunk rispetto alla query e li riordina per rilevanza reale. Aggiunge ~100-200ms di latenza ma migliora significativamente la precision. Fondamentale quando i documenti sono densi e specialistici.
Generazione
I chunk re-ranked vengono assemblati in un contesto strutturato e passati al LLM con un system prompt che istruisce il modello a rispondere solo sulla base del contesto fornito, a citare le fonti, e a dichiarare esplicitamente quando le informazioni non sono disponibili. Quest'ultimo punto — il "non so" esplicito — è fondamentale per la fiducia degli utenti aziendali.
Chunking strategy: l'impatto sulla qualità
La chunking strategy è la variabile con più impatto sulla qualità del sistema RAG, ma è anche la meno discussa. Linee guida pratiche:
- Dimensione chunk: 200-400 token per chunk con 15-20% di overlap. Chunk troppo piccoli perdono contesto; chunk troppo grandi portano rumore nel retrieval.
- Hierarchical chunking: divide il documento in nodi padre (paragrafo/sezione) e figli (frasi). Il retrieval usa i nodi figlio (più precisi), ma al LLM viene passato il padre (più contesto). LlamaIndex implementa questo con
HierarchicalNodeParser. - Metadata embedding: aggiungi metadati nel chunk (titolo documento, sezione, data) per migliorare il retrieval su query che richiedono filtri temporali o per categoria.
Valutazione con RAGAS
RAGAS è il framework standard per valutare sistemi RAG senza label manuali. Le quattro metriche principali:
- Faithfulness: la risposta è supportata dai chunk recuperati? Misura le allucinazioni.
- Answer Relevancy: la risposta è pertinente alla domanda posta?
- Context Precision: i chunk recuperati sono effettivamente rilevanti per la query?
- Context Recall: il retrieval ha trovato tutti i chunk necessari per rispondere?
Target di produzione: faithfulness > 0.85, answer relevancy > 0.80. Un sistema con faithfulness bassa sta allucinando nonostante il contesto — cambia il system prompt. Con context precision bassa, il chunking o il retrieval hanno problemi.
I modelli di embedding anglofoni funzionano meno bene su testi italiani. Utilizzare modelli multilinguali (BGE-M3, paraphrase-multilingual-MiniLM-L12-v2, nomic-embed-text con supporto multilingue) migliora la qualità del retrieval in modo misurabile su corpora italiani.
Cosa non va in produzione senza attenzione
I problemi più comuni nei sistemi RAG aziendali che vediamo:
- Documenti non aggiornati nell'indice: serve un trigger di re-indicizzazione quando un documento cambia (webhook, CDC, polling).
- Mancanza di citazione delle fonti: gli utenti aziendali devono poter verificare le risposte. Ogni risposta deve indicare i chunk e i documenti sorgente.
- Nessun feedback loop: i thumbs down degli utenti sono la fonte di verità sulla qualità del sistema. Raccoglierli e usarli per migliorare è fondamentale.
- Embedding model diversi tra ingest e query: l'embedding della query deve usare esattamente lo stesso modello dell'embedding dei chunk. Cambiare modello richiede la re-indicizzazione completa.