La Retrieval-Augmented Generation (RAG) rappresenta una fusione potente tra l'intelligenza artificiale generativa e i dati aziendali, permettendo ai modelli linguistici di accedere a informazioni esterne e fornire risposte più precise e contestualizzate. Tuttavia, senza una pipeline di dati RAG adeguata, il sistema potrebbe non riuscire a individuare i dati più accurati per rispondere alle richieste degli utenti. La qualità dei dati è di primaria importanza nei sistemi RAG.
Pertanto, la creazione di un'applicazione RAG di successo implica una serie di compiti di pre-elaborazione dei dati, tra cui il filtraggio dei contenuti, la normalizzazione del testo, il chunking, il tagging dei metadati e la generazione di embedding. Per garantire una corretta preparazione dei dati, i team di sviluppo RAG devono comprendere come RAG rende i dati ricercabili, esaminare strategie di pre-elaborazione dei dati come i metodi di chunking e imparare a costruire una pipeline di dati RAG, dalla selezione e pulizia dei dati all'embedding e all'archiviazione in un database vettoriale.
Come RAG rende i dati ricercabili
RAG assiste i servizi di IA generativa nell'accesso a dati esterni utilizzando un archivio vettoriale o un database dotato di specifici meccanismi di ricerca. Per incorporare dati non strutturati – come ad esempio un documento – in un archivio vettoriale, i team devono prima "embeddare" i dati tramite un modello di embedding. Un embedding converte il testo in vettori numerici, ovvero un elenco di numeri decimali che rappresentano il testo, come parole o frasi, in un modo comprensibile per i computer.
Consideriamo, ad esempio, il seguente paragrafo estratto da un documento:
"Abbiamo introdotto Copilot la scorsa settimana e l'adozione è eccellente. Le prime misurazioni mostrano una riduzione del volume dei ticket del 32% e un aumento delle soluzioni self-service del 27% nelle prime 48 ore. Il dipartimento finanziario stima un risparmio annuale di 1,4 milioni di euro se questa tendenza continua."
L'embedding di questo paragrafo in vettori che rappresentano il testo si presenta così:
[0,81, -0,23, 0,45, 0,12, -0,67, 0,94, 0,30, -0,55, 0,76, 0,10]
Questo è un esempio fortemente semplificato. Se i team utilizzano un modello di embedding come il modello OpenAI text-embedding-3-small, questo produce un vettore di 1536 dimensioni. Esistono diversi modelli di embedding offerti da vari fornitori. Hugging Face, ad esempio, offre una classifica degli embedding che illustra i punti di forza e di debolezza di vari modelli di embedding.
Questi vettori e il testo originale vengono memorizzati in un archivio vettoriale come Pinecone o Weaviate. I dati nell'archivio vettoriale possono assomigliare a questo:
{
"id": "unique-id-123",
"values": [0,81, -0,23, ..., 0,789], // il vettore (embedding)
"metadata": {
"text": " Abbiamo introdotto Copilot la scorsa settimana e l'adozione è eccellente ...",
"source": "Documento A",
"page": 3
}
}
Quando un utente desidera porre una domanda sui dati, invia il prompt tramite un orchestratore – come LangGraph, LangChain o Semantic Kernel – che a sua volta invia una richiesta all'archivio vettoriale utilizzando un metodo di ricerca. Il metodo di ricerca può restituire due o più parti di contenuto pertinenti e inoltrare queste informazioni al modello linguistico di grandi dimensioni (LLM), che genera una risposta per l'utente.
Perché il Chunking è Importante
Il chunking è un metodo standard di pre-elaborazione che prevede la suddivisione di un set di dati in sezioni più piccole, chiamate "chunk". Poiché gli archivi vettoriali non possono contenere tutti i dati originali, questi devono essere divisi in chunk.
Il paragrafo su Copilot, ad esempio, può essere suddiviso in due sezioni:
- Chunk 1: "Abbiamo introdotto Copilot la scorsa settimana e l'adozione è eccellente."
- Chunk 2: "Le prime misurazioni mostrano una riduzione del volume dei ticket del 32% e un aumento delle soluzioni self-service del 27% nelle prime 48 ore. Il dipartimento finanziario stima un risparmio annuale di 1,4 milioni di euro se questa tendenza continua."
Il problema con questo approccio è che alcune parti potrebbero perdere il loro significato originale. Ad esempio, se un utente interroga il sistema RAG su Copilot, il meccanismo di ricerca restituirebbe solo la prima parte, non la seconda, poiché non c'è correlazione diretta tra i due chunk. Senza la seconda parte, l'utente non riceverebbe il contesto aggiuntivo e le informazioni sull'accettazione di Copilot.
È qui che le strategie di chunking possono aiutare a scomporre i dati in modo che si adattino all'archivio vettoriale e mantengano il loro significato originale all'interno di un motore RAG.
4 Strategie di Chunking
Senza strategie appropriate, i sistemi RAG possono scomporre i dati in modo errato. Sono disponibili diverse metodologie di chunking, tra cui chunking a dimensione fissa, chunking a dimensione variabile basato sul contenuto, chunking basato su regole e chunking a finestra scorrevole (sliding window chunking).
1. Chunking a dimensione fissa
In questo metodo, il testo viene suddiviso in segmenti di dimensioni uguali, indipendentemente dal contenuto, ad esempio 400 parole o 800 caratteri per chunk. È semplice da implementare ma può spezzare frasi o concetti a metà, compromettendo la coerenza.
2. Chunking a dimensione variabile basato sul contenuto
Qui il testo viene suddiviso in base a confini naturali, come i segni di fine frase, le interruzioni di riga o i segnali strutturali identificati da strumenti di elaborazione del linguaggio naturale (NLP) che analizzano il layout e il significato dei documenti. Questo approccio tende a preservare meglio il significato dei chunk.
3. Chunking basato su regole
Questo approccio si basa sulla struttura intrinseca o sui confini linguistici del documento. I metodi tipici includono il chunking per frasi o paragrafi utilizzando regole predefinite. Ad esempio, ogni paragrafo può essere considerato un chunk, o ogni frase separata da un punto.
4. Chunking con finestra scorrevole (Sliding Window Chunking)
In questa tecnica, vengono creati chunk sovrapposti facendo scorrere una finestra di dimensioni fisse attraverso il testo. Ad esempio, ogni chunk può contenere 500 parole, con il chunk successivo che inizia 300 parole più avanti, creando così un'overlap di 200 parole tra i chunk. Questo garantisce che il contesto non venga perso ai bordi dei chunk e che le informazioni correlate rimangano vicine.
Per il paragrafo di Copilot, un approccio a finestra scorrevole o basato su regole garantirebbe che il paragrafo non perda il suo significato, poiché entrambi i contenuti (l'introduzione e i dati sull'adozione/risparmio) sarebbero disponibili nello stesso chunk o in chunk sovrapposti che mantengono il legame semantico.
6 Passi della Pipeline Dati RAG
Un altro aspetto da considerare nei sistemi RAG è l'aggiornamento dei dati. Ad esempio, se i dati originali sono un documento Word prima di essere incorporati in un archivio vettoriale, i dati potrebbero perdere rapidamente valore se non vengono aggiornati regolarmente. Inoltre, i documenti che non possono essere incorporati direttamente, come i file PDF, devono essere convertiti in un formato leggibile dal testo per essere trasferiti nell'archivio vettoriale.
È quindi fondamentale costruire una pipeline di dati che possa automatizzare il processo di embedding continuo di nuovi dati da varie fonti e tipi di file nell'archivio vettoriale. Una pipeline di dati RAG è generalmente composta dai seguenti sei passaggi:
1. Selezione e acquisizione del corpus
A seconda del caso d'uso, è necessario selezionare le fonti di dati e i contenuti più rilevanti. Questo passaggio iniziale è cruciale per garantire che il sistema RAG abbia accesso a informazioni pertinenti e di valore. La scelta del corpus influenzerà direttamente l'accuratezza e l'utilità delle risposte generate dal modello.
2. Pre-elaborazione e analisi dei dati
I dati grezzi devono essere puliti e standardizzati per essere pronti per l'embedding e il recupero. Questo può includere la rimozione di caratteri speciali, la correzione di errori di formattazione e la normalizzazione del testo. Uno strumento comunemente utilizzato è MarkItDown. Supporta PDF, PowerPoint e molti altri formati di file e può convertire il contenuto nel formato Markdown, facilitando la strutturazione durante il processo di chunking.
3. Arricchimento
Rimuovere i contenuti di disturbo e aggiungere metadati utili ai dati. Ad esempio, si può aggiungere il titolo del documento all'inizio, in modo che sia disponibile durante il processo di chunking. Altri metadati possono includere l'autore, la data di pubblicazione, la categoria o parole chiave pertinenti, che possono migliorare la precisione del recupero.
4. Filtraggio
Rimuovere tutti i documenti irrilevanti o di scarso valore che non supportano il caso d'uso specifico. Questo aiuta a ridurre il "rumore" nel set di dati e a garantire che il sistema RAG si concentri sulle informazioni più utili, migliorando l'efficienza e la pertinenza delle risposte.
5. Chunking
Dividere i dati puliti in chunk più piccoli e logici per migliorare le prestazioni di recupero. Come discusso in precedenza, è fondamentale scegliere la strategia di chunking più appropriata per preservare il contesto e il significato. Framework come LangChain offrono diverse metodologie di chunking, come LangChain CharacterTextSplitter, che possono essere configurate per adattarsi alle specifiche esigenze del progetto.
6. Embedding
Convertire ogni chunk in un vettore utilizzando un modello di embedding. Questi vettori numerici catturano il significato semantico del testo e vengono quindi archiviati in un database vettoriale. Il database vettoriale indicizza questi vettori, rendendoli rapidamente recuperabili in base alla loro somiglianza semantica con la query dell'utente, completando così il ciclo per rendere i dati accessibili e utili per la generazione aumentata dal recupero.