Invito alla lettura di Andrei Gheorghiu, Building Data-Driven Applications with LlamaIndex: A practical guide to retrieval-augmented generation (RAG) to enhance LLM applications, Packt, 2024
Pur focalizzandosi sul framework Llama Index – framework open source con numerosi tool per attuare vari scenari di RAG –, il libro di Andrei Gheorghiu è un’ottima introduzione alla RAG (Retrieval-Augmented Generation), intesa come metodo in grado di colmare alcune lacune tipiche dei LLM (Large Language Model) puri.
Il compito di un sistema Retrieval-Augmented Generation è generare in modo autonomo prompt per il modello linguistico in base alla domanda dell’utente, ai contenuti rilevanti che la procedura di Information Retrival ha recuperato dalla knowledge base aziendale e a istruzioni specifiche, mettendo il LLM nelle condizioni di generare risposte basate sul sapere aziendale integrato, più precise e rispondenti alle esigenze informative dell’utente.
I componenti del sistema RAG presi in esame da Gheorghiu sono in particolare documenti, nodi, indici, retriver, post-processori, response synthesizer e output processor. Non mancano però approfondimenti su applicazioni di RAG Assessment, nonché su chatbot e agenti basati sulla Retrieval-Augmented Generation.
Data Ingestion
La fase di Data Ingestion è la base per poter eseguire ricerche e recuperare informazioni, ed è funzionale a trasformare la sorgente dati in documenti, nodi e indici di Llama Index, eventualmente anche applicando misure a protezione della privacy.
Documents di Llama Index
I documenti sono il contenitore che Llama Index usa per contenere ogni tipo di dato grezzo caricato a mano o automaticamente (per esempio mediante applicazioni dette Data Loader).
Un documento può essere costituito per esempio da un PDF, da un record di dati proveniente da un database o da una API oppure da un sito web.
Oltre ai dati, il documento può contenere anche metadati atti a supportare un più preciso recupero delle informazioni. I metadati sono assegnabili a mano o automaticamente (per esempio mediante applicazioni dette Metadata Extractor).
Nodes di Llama Index
I nodi sono segmenti (chunk) di testo estratti dai documenti, a mano o automaticamente, per esempio mediante applicazioni dette Text Splitter e Node Parser: ve ne sono anche in grado di creare nodi fra loro collegati da relazioni e altri, detti Element Node Parser, che agiscono su file HTML e separano testi da tabelle, generando due tipi di nodi distinti, quelli di testo interrogabili semanticamente e quelli di tabella importabili in database relazionali e interrogabili via SQL.
La segmentazione ha vari obiettivi:
- Creare chunk che rientrano nel context window del LLM
- Creare segmenti semanticamente unitari, per esempio incentrati su un topic
- Creare relazioni fra i nodi e quindi fra i contenuti dei chunk.
- Al pari dei documenti, anche i nodi possono contenere metadati, per esempio relativi al documento sorgente di un chunk, alla relazione precedente/successivo fra chunk o alla relazione gerarchica padre/figlio fra chunk.
- I metadati sono atti a supportare ricerche più contestuali, a tracciare la fonte di un contenuto, a costruire knowledge graph e a rendere più espressiva l’indicizzazione.
Indexes di Llama Index
Gli indici sono strutture usate per organizzare una collezione di nodi in modo tale da ottimizzarne l’archiviazione e il recupero mediante le funzioni di ricerca.
Oltre al Vector Store Index – che trasforma i nodi in embedding, avvicinando quelli semanticamente simili e supportando così la ricerca per similarità semantica -, esistono in particolare:
- Document Index, che crea un sommario per ogni documento, collegato ai nodi del documento stesso. Utile quando i documenti sono molto eterogenei per identificare i più rilevanti ai fini di una data ricerca
- Summary Index, che indicizza i nodi di un documento. Utile per cercare in documenti molto ampi
- Tree Index, che crea una struttura ad albero in cui ogni padre contiene il sommario dei figli. Utile per compiti di summarization
- Knowledge Graph, utile per quesiti la cui risposta necessita di molte informazioni connesse, basate sulle triple soggetto-verbo-predicato estratte dai documenti
- Composable Index, che permette di creare indici di indici. Utile quando si dispone di ampie collezioni di documenti.
In alcuni casi può essere opportuno creare il Vector Store Index non direttamente sui contenuti dei nodi, ma per esempio su quelli del Document Index e del Questions Answered Extractor (vedi sotto).
Ogni indice supporta una logica di ricerca distinta.
Oltre ai Metadata Extractor – applicazioni anche indipendenti da Llama Index e che agiscono su documenti e nodi –, vi sono altri estrattori che possono elaborare i contenuti per migliorare il risultato delle procedure di information retrival:
- Summary Extractor, che generano il sunto del nodo e di quelli adiacenti, in modo tale che la ricerca possa agire sul sunto, anziché sull’intero contenuto del nodo
- Questions Answered Extractor, che generano un dato numero di domande a cui il nodo risponde, permettendo di indirizzare la ricerca in modo più preciso
- Title Extractor, che creano titoli per documenti che ne sono privi. Le parole chiave contenute nei titoli possono poi essere usate per classificare i documenti
- Entity Extractor, che estraggono nomi di persone, di organizzazioni, di luoghi, date, ecc., arricchendo i metadati
- Keyword Extractor, che estraggono le principali parole chiave dai nodi, permettendone la successiva mappatura rispetto a quelle contenute nella domanda dell’utente. Utile in contesti in cui tipicamente la ricerca avviene per parole chiave precise e codificate
Dato che anche gli estrattori operano attraverso chiamate al modello linguistico è sempre opportuno stimare i costi mediante appositi tool prima di procedere (come per esempio MockLLM e MockEmbedding), e poi:
- Usare se possibile modelli meno costosi, valutando caso per caso se la riduzione dell’accuratezza è accettabile
- Salvare in cache e riutilizzare gli indici
- Ridurre per esempio il valore del parametro SimilarityTopK per ridurre il numero di chiamate al modello linguistico
- Usare in locale LLM ed embedding, beneficiando anche dei vantaggi intrinseci al mantenimento della sovranità sui dati.
Query Engine
Una volta predisposti dati e metadati, può entrare in azione il Query Engine del sistema RAG, che si compone principalmente di retriver, post-processore, response synthesizer e output processor.
Retriver
Il query engine contiene un Retriver che, in base al quesito, cerca i nodi rilevanti all’interno dell’indice e li recupera in base a uno score.
Vi sono vari tipi di retriver per i vari tipi di indici, che ne sfruttano i punti di forza.
Inoltre Llama Index dispone di meccanismi avanzati di information retrival, per esempio:
- Il Vector Index Retriver dispone di un parametro Filter che agisce sui metadati dei nodi recuperati. In combinazione con un sistema di gestione dei ruoli, i filtri possono essere usati, per esempio, per mostrare a ogni ruolo solo i contenuti di sua pertinenza. Alcuni vector store, come Pincone e ChromaDB, supportano operatori logici all’interno dei filtri, permettendo di aggregare più valori in base alle condizioni
- Supporto alla decisione autonoma da parte di Agenti appositi riguardo a quale retriver usare in base al quesito dell’utente e al tipo di contenuti in cui cercare
- Trasformazione e riscrittura della domanda dell’utente, per esempio per segmentare un quesito articolato in più sotto-quesiti meglio gestibili dal sistema.
Dense e Sparse Retrival
Importante è la differenza fra Dense e Sparse Retrival:
Il Dense Retrival (per esempio sul Vector Store Index) si basa sugli embedding di vector store. I suoi punti di forza sono la comprensione semantica del quesito e quindi la buona gestione di sinonimi e polisemie. Gli svantaggi del dense retrival sono, oltre ai costi computazionali del modello linguistico, il bilanciamento non sempre facile fra recupero e precisione, con il rischio di recuperare contenuti non rilevanti o non in linea con le intenzioni o con il ragionamento dell’utente
Lo Sparse Retrival (per esempio sul Keyword Table Index) si base sull’associazione fra parole chiave e documenti. Nello sparse retrival i documenti sono rappresentati come vettori, in cui ogni dimensione corrisponde a una parola chiave e al suo score. La ricerca, che è case sensitive (!) ed è detta sparse perché a ogni documento è associato solo un piccolo sottoinsieme delle keyword totali, avviene in base alla frequenza della parola chiave e al suo score. Il punto di forza dello sparse retrival è la precisione, mentre non supporta comprensione semantica, sinonimi e polisemie. Lo sparse retrival può essere una buona scelta per esempio in ambito legale o di professioni in cui si usano termini tecnici codificati e condivisi, e in cui i documenti sono strutturati attorno a questa terminologia.
Post-Processor
Prima della generazione della risposta entrano in azione i Node Post-Processor del sistema RAG, che all’occorrenza riordinano, trasformano o filtrano (per esempio in base a ruoli e autorizzazioni oppure a una soglia di score) i nodi recuperati, cioè il context che la RAG trasmette al modello linguistico.
Altri possibili usi dei Node Post-Processor sono:
- Recuperare anche i nodi precedenti e successivi a quelli recuperati dalla procedura di information retrival
- Sostituire il contenuto del nodo con i suoi metadati, se i metadati catturano un contesto più ampio del nodo stesso
- Dare priorità ai contenuti più recenti (Time Based Post-Processor)
- Mascherare le informazioni funzionali all’identificazione personale.
Response Synthesizer
Dopo il post-processing interviene il Response Synthesizer che crea il prompt per il LLM, trasmettendogli la domanda dell’utente, il primo nodo recuperato e post-processato (cioè il primo context), nonché le istruzioni per la generazione della risposta. Il response synthesizer itera questo ciclo per tutti i nodi recuperati, sintetizzando le risposte che via via riceve dal modello linguistico e adattando i prompt di conseguenza. L’approccio iterativo fa sì che ogni contesto sia esaminato con attenzione dal LLM.
Per ogni operazione che richiede l’interazione con il modello linguistico Llama Index usa un template di prompt predefinito, che comprende parti fisse e altre variabili, personalizzabili utilizzando le buone pratiche del prompt engineering.
Output Parser
Infine può intervenire un Output Parser. Dato che l’output di un modello linguistico non è deterministico, anche in presenza di istruzioni precise non vi è garanzia che il LLM applichi alla risposta la struttura richiesta. Questo comportamento è negativo in particolare se la risposta del modello linguistico è chiamata ad alimentare applicazioni o le variabili di un successivo prompt, ecc. Gli output parser sono sviluppati per prendere in carico la risposta del LLM, verificarne la struttura ed eventualmente adeguarla a quella richiesta.
Alcuni supporti particolari di Llama Index alla RAG sono:
- Router Query Engine, che decide in autonomia quale Query Engine Tool usare in base al quesito dell’utente
- Sub Question Query Engine, che segmenta un quesito in più sotto-quesiti, per esempio quando le domande dell’utente sono multiple o quando sono necessarie operazioni di confronto oppure quando è necessaria una ricerca che illumini vari aspetti di uno stesso tema
- SQL Join Query Index / SQL Auto Vector Query Engine / SQL Table Retriver Query Engine, che arricchiscono i risultati dell’information retrival con i risultati di query SQL, o viceversa, e che traducono in query SQL il linguaggio naturale in cui l’utente pone il quesito
- Citation Query Engine, che incorpora nella risposta la citazione della fonte.
Chatbot e Agenti con Llama Index
Per realizzare un chatbot aziendale con Llama Index è necessario usare non Query Engine, ma Chat Engine, che – in aggiunta alle funzioni di information retrival di Query Engine – gestisce la memoria della conversazione con l’utente, necessaria per garantirne la coerenza.
Diversamente dai chatbot, gli agenti sono specializzati nel prendere decisioni autonome. Le decisioni sono prese mediante un Reasoning Loop gestito dal motore decisionale specifico dell’agente e sono attuate anche mediante l’uso di Tool adeguati allo scopo, cioè scelti in base all’input dell’utente, al contesto, all’esito del ragionamento, iterando eventualmente il ciclo in base ai risultati dell’output, ecc.
RAG Assessment
Applicazioni di RAG Assessment, come per esempio Phoenix, sono utili in fase di debug, per tracciare e valutare (in sinergia con il GPT di OpenAI) le applicazioni RAG in base a vari criteri come la qualità dell’information retrival e della risposta generata, la fedeltà della risposta al contesto, l’assenza di allucinazioni e incoerenze, l’efficienza computazionale, la robustezza (rispetto a query di varia natura e possibili attacchi).
Autore: Petra Dal Santo