Nel contesto di Elasticsearch, la gestione dei snapshot è una parte cruciale per garantire la sicurezza e l’integrità dei dati. Registrare correttamente un repository di snapshot permette di eseguire backup efficaci dei dati indicizzati, che possono essere successivamente ripristinati in caso di necessità. In questo capitolo, esploreremo i passaggi per configurare un repository di snapshot su AWS S3 tramite Kibana e successivamente, introdurremo il concetto di ingestione dei dati generali, illustrando le principali operazioni di indicizzazione, aggiornamento ed eliminazione dei dati in Elasticsearch.
Per cominciare, è essenziale configurare un keystore in Elasticsearch. Utilizzando il comando $ bin/elasticsearch-keystore add s3.client.secondary.secret_key, è possibile aggiungere la chiave segreta dell'accesso a un secondo client S3, che sarà utilizzato per registrare il repository di snapshot. Una volta completata questa operazione, ci si può dirigere su Kibana nella sezione Management > Stack Management > Snapshot & Restore > Repositories per registrare il repository, assegnargli un nome e scegliere AWS S3 come tipo di repository.
A questo punto, è fondamentale configurare correttamente il client S3, impostando la chiave di accesso secondary e utilizzando il nome del bucket esatto creato su AWS. Nella configurazione di Kibana, occorre prestare attenzione a questo passaggio, poiché l’errore di configurazione potrebbe impedire il corretto collegamento del repository di snapshot. Una volta verificato il corretto stato del repository, si può procedere con la registrazione e la verifica, come illustrato nel passo successivo.
L'importante in questo processo è che la creazione del repository e la registrazione possono avvenire anche tramite l’API di Elasticsearch, consentendo agli amministratori di gestire i snapshot in modo più flessibile. Per chi utilizza Elastic Cloud, esistono anche altre opzioni di configurazione che riguardano la gestione dei repository per altre piattaforme come Azure e Google Cloud Storage, permettendo una personalizzazione a seconda dell'ambiente di deployment.
A seguito della configurazione del repository di snapshot, è possibile passare a uno degli aspetti più rilevanti dell'uso di Elasticsearch: l’ingestione dei dati. In questo capitolo, ci concentreremo sull’ingestione di contenuti generali, come dati provenienti da API, HTML, cataloghi, sistemi di gestione di basi di dati relazionali (RDBMS), file PDF e fogli di calcolo. La capacità di Elasticsearch di gestire diversi formati di dati consente di creare flussi di lavoro altamente scalabili, che si adattano alle esigenze di qualsiasi tipo di azienda.
Uno degli aspetti fondamentali per una corretta ingestione dei dati è la comprensione delle operazioni di base come l'indicizzazione, l’aggiornamento e l’eliminazione dei dati. Per esempio, quando si aggiungono nuovi dati, Elasticsearch li organizza in indici, che sono strutture fondamentali per una ricerca rapida ed efficiente. Inoltre, la gestione dei mapping, sia statici che dinamici, è cruciale per assicurarsi che i dati vengano interpretati correttamente al momento dell’indicizzazione. L’uso di template di indice permette di predefinire le configurazioni per i nuovi indici, garantendo che tutti i dati vengano trattati uniformemente.
In questo capitolo utilizzeremo il dataset dei Wikipedia Movie Plots proveniente da Kaggle come esempio per l’ingestione di contenuti generali. Questo dataset include informazioni su oltre 34.000 film, come anno di rilascio, titolo, regista e cast, provenienti da Wikipedia. Esso rappresenta una fonte interessante di metadati che possiamo utilizzare per illustrare il processo di ingestione in Elasticsearch.
Per eseguire correttamente l'ingestione dei dati in Elasticsearch, è necessario avere un'installazione funzionante di Elastic Stack, comprensiva di Elasticsearch per la gestione dei dati e di Kibana per la visualizzazione e l'interazione con i dati. Inoltre, in questo esempio, utilizzeremo il client Python per interagire con l'API REST di Elasticsearch. La configurazione del client richiede l’installazione di alcune librerie come elasticsearch e dotenv, utilizzando il gestore di pacchetti pip per semplificare la gestione delle dipendenze. La creazione di un file .env permette di memorizzare in modo sicuro le credenziali di accesso, inclusi l'ID del cloud, il nome utente e la password.
Una volta stabilita la connessione con il cluster di Elasticsearch, è possibile procedere con l’invio di dati al sistema. Nel nostro esempio, creeremo un documento JSON contenente i metadati di un film, come titolo, anno di rilascio e cast, e lo indicizzeremo nel nostro cluster Elasticsearch. Con l’API Bulk, possiamo anche caricare più documenti in una sola volta, migliorando l’efficienza del processo di ingestione.
Oltre alle operazioni di base di indicizzazione, è altrettanto importante comprendere come i dati vengano gestiti nel tempo. Per esempio, l’uso degli analizzatori in Elasticsearch permette di definire come i dati dovrebbero essere trattati durante l’indicizzazione, migliorando la ricerca e l'analisi dei dati stessi. I mapping dinamici e i template di indice forniscono una struttura flessibile, che consente di adattarsi a nuove informazioni senza compromettere le performance o la coerenza.
Anche se ci siamo concentrati sull’ingestione dei dati generali, è fondamentale ricordare che esistono altre tipologie di dati, come i dati temporali (logs, metriche, tracce), che richiedono approcci specifici per essere indicizzati e gestiti in modo ottimale in Elasticsearch. La gestione dei dati temporali richiede particolare attenzione alla configurazione degli indici per garantire che le informazioni siano facilmente reperibili e analizzabili nel tempo.
Il ciclo di vita di un indice e dei suoi dati è fondamentale per mantenere il sistema performante e ben gestito. La gestione dei snapshot e il ripristino dei dati possono essere utilizzati per creare backup regolari e recuperare i dati in caso di guasti, e comprendere come automatizzare questi processi è cruciale per le operazioni quotidiane in un ambiente di produzione.
Come utilizzare i template dinamici nella mappatura dei documenti in Elasticsearch
In Elasticsearch, la mappatura dei documenti è fondamentale per definire come i dati vengono memorizzati, indicizzati e ricercati. Quando si lavora con dati complessi, l'uso dei template dinamici può semplificare e ottimizzare la gestione dei campi, riducendo al minimo la necessità di intervento manuale ogni volta che vengono aggiunti nuovi campi. In questo capitolo esploreremo come utilizzare i template dinamici nella mappatura dei documenti, un approccio che offre numerosi vantaggi, tra cui la correlazione dei dati, il riutilizzo e la preparazione per il futuro.
Cosa sono i template dinamici?
I template dinamici in Elasticsearch permettono di applicare automaticamente regole di mappatura a nuovi campi, in base ai loro tipi di dato. Questo significa che quando un campo viene aggiunto a un documento, Elasticsearch applica automaticamente una mappatura predeterminata, senza la necessità di definire manualmente ogni singolo campo. I template dinamici semplificano notevolmente la gestione dei dati, specialmente in scenari in cui i campi possono variare o essere aggiunti frequentemente, come in un ambiente di sviluppo agile.
Per comprendere meglio come funzionano, consideriamo il seguente esempio: supponiamo di avere un campo year nella nostra mappatura che, per motivi di ottimizzazione, dovrebbe essere trattato come un campo short piuttosto che come un campo long, come impostato di default. Allo stesso tempo, vogliamo che eventuali nuovi campi che terminano con "year" (come review_year o award_year) siano automaticamente mappati come short. Questo può essere fatto facilmente utilizzando un template dinamico.
Esempio di utilizzo di un template dinamico
Immagina di voler creare un template dinamico che mappi automaticamente i campi che terminano con "year" come tipo short. Puoi farlo attraverso la seguente configurazione in Kibana:
Questa configurazione applica la mappatura short a tutti i campi che corrispondono al pattern *year, riducendo al minimo l'intervento manuale necessario per gestire i nuovi campi.
Successivamente, se aggiungi un nuovo documento con un campo review_year, Elasticsearch applicherà automaticamente il tipo short a quel campo, come mostrato nell'esempio seguente:
Dopo l'indicizzazione del documento, possiamo verificare la mappatura con il comando seguente:
Vedremo che la mappatura dei film ora include il template dinamico, e il campo review_year è correttamente mappato come tipo short.
Vantaggi dei template dinamici
L'uso dei template dinamici presenta numerosi vantaggi. Prima di tutto, semplifica l'automazione della mappatura, evitando di dover definire manualmente ogni campo. In scenari in cui i campi dei documenti possono variare o essere aggiunti frequentemente, questo approccio permette una gestione più agile ed efficiente dei dati.
Inoltre, l'uso di template dinamici riduce il rischio di errori nella definizione dei campi, specialmente quando si lavora con grandi volumi di dati e documenti. La configurazione automatica della mappatura, basata su pattern predefiniti, assicura che i campi vengano sempre trattati correttamente, ottimizzando la memoria e lo spazio di archiviazione.
Come ottimizzare la progettazione delle mappature
Sebbene la mappatura dinamica sia utile, è consigliabile definire le mappature in modo strategico per ottimizzare l'archiviazione, la memoria e la velocità di indicizzazione/ricerca. Un buon flusso di lavoro per progettare nuove mappature potrebbe essere il seguente:
-
Indicizza un documento di esempio contenente i campi desiderati in un indice di prova.
-
Recupera la mappatura dinamica generata da Elasticsearch.
-
Modifica e ottimizza la definizione della mappatura in base alle esigenze.
-
Crea un indice con la mappatura personalizzata, sia essa esplicita o dinamica.
Inoltre, è possibile combinare i template dinamici con altre tecniche di gestione degli indici, come l'uso dei template di indice, che automatizzano ulteriormente la creazione di indici con configurazioni predefinite, garantendo la coerenza in tutto il cluster Elasticsearch.
Considerazioni aggiuntive
Anche se i template dinamici sono un potente strumento, ci sono alcune limitazioni e pratiche da tenere a mente. In particolare, quando si lavora con grandi quantità di dati numerici, come le metriche temporali, potrebbe essere utile disabilitare l'indicizzazione di certi campi per risparmiare spazio su disco, se questi non vengono utilizzati per ricerche ma solo per aggregazioni.
In scenari in cui si ha a che fare con dati temporali, è comune avere numerosi campi numerici, e quindi disabilitare l'indicizzazione di quei campi è spesso la scelta migliore per ottimizzare le performance.
Anche se la mappatura dinamica predefinita in Elasticsearch è comoda per iniziare, è fondamentale prendere in considerazione l'ottimizzazione delle mappature per garantire che il sistema funzioni in modo efficiente a lungo termine.
Come Creare una Pipeline Logstash per Ingestire Dati in Tempo Reale
Logstash è uno strumento potente per la raccolta, l'elaborazione e l'invio di dati da diverse fonti a destinazioni multiple. La sua flessibilità nella gestione dei flussi di dati lo rende un componente fondamentale in architetture moderne di gestione delle informazioni. Anche se non è strettamente necessario nell'architettura di ingestione dei dati, la sua integrazione offre numerosi vantaggi, tra cui pipeline di elaborazione dati avanzate, resilienza tramite meccanismi di coda persistente e la possibilità di ingerire dati da fonti diverse.
L'uso di Logstash permette di ottenere una maggiore coerenza e affidabilità nei flussi di dati, grazie alla sua capacità di elaborare eventi e di eseguire il buffering dei dati su disco. Questo rende Logstash uno degli strumenti più completi per la gestione delle pipeline di dati.
Il processo di configurazione di una pipeline Logstash coinvolge diverse fasi. Iniziamo con la definizione del file di configurazione, che può essere utilizzato per determinare come i dati vengono raccolti, elaborati e inviati a destinazioni specifiche, come Elasticsearch o altre piattaforme di analisi. In questa guida, esploreremo i passaggi per configurare una pipeline Logstash utilizzando i dati in tempo reale del traffico di Rennes, un esempio che abbiamo introdotto nel capitolo precedente.
Per seguire questa guida, è necessario che tu abbia già completato le ricette per l'installazione di Logstash e la configurazione di un flusso di dati temporale. Useremo i dati del traffico di Rennes per creare un flusso continuo che importerà i dati in tempo reale ogni 10 minuti tramite un'API pubblica. Questo approccio ci permetterà di mantenere aggiornati i dati e di monitorare il traffico in tempo reale.
La prima cosa da fare è creare il file di configurazione di Logstash, che si trova nella directory di configurazione di Logstash, generalmente nella cartella /etc/logstash/conf.d/ su un sistema Debian. La configurazione di base per raccogliere i dati del traffico di Rennes è la seguente:
In questa sezione, il plugin http_poller viene utilizzato per prelevare i dati in formato CSV dal link dell'API di Rennes ogni 10 minuti. Questo permette di raccogliere i dati in tempo reale e di procedere alla loro elaborazione in seguito.
Una volta configurato l'input, il passo successivo è definire i filtri per elaborare e trasformare i dati ricevuti. È possibile utilizzare una serie di filtri per strutturare i dati in modo corretto, eliminando campi non necessari, convertendo formati di data e aggiungendo nuovi campi. Di seguito è riportato un esempio di come si possano applicare i filtri:
In questo esempio, il filtro csv viene utilizzato per separare i dati del CSV, rimuovendo i campi non necessari. Il filtro date converte il campo datetime in un timestamp per una corretta indicizzazione, mentre il filtro mutate permette di rinominare e rimuovere campi.
Una volta preparati i dati, la sezione finale della configurazione riguarda l'output. In questo caso, i dati vengono inviati a due destinazioni: una in Elasticsearch per la memorizzazione e l'analisi, e l'altra su STDOUT per il debug:
Dopo aver configurato correttamente il file, possiamo avviare Logstash con il comando sudo systemctl start logstash.service su un sistema Debian. Successivamente, i dati verranno ingeriti in Elasticsearch, dove potrai verificarli creando una visualizzazione dei dati in Kibana. Basta accedere a Kibana e configurare una vista dei dati chiamata metrics-rennes_traffic-default per monitorare i dati in tempo reale.
La capacità di Logstash di gestire flussi di dati in tempo reale e di elaborare grandi volumi di informazioni lo rende uno strumento essenziale per chi desidera costruire pipeline robuste e scalabili. Utilizzare Logstash permette di avere il controllo totale su come i dati vengono trattati, offrendo una gestione dettagliata delle configurazioni di input, filtri e output.
Per ottenere il massimo da Logstash, è importante comprendere non solo come configurarlo, ma anche come monitorare e ottimizzare le pipeline. Ad esempio, è possibile implementare un meccanismo di recupero in caso di errori, o gestire in modo più efficiente il buffering dei dati per evitare la perdita di eventi importanti in scenari ad alta velocità di ingresso.
Come integrare la ricerca vettoriale e l'AI generativa nelle applicazioni di domande e risposte
La strategia di ricerca riveste un ruolo fondamentale nelle applicazioni moderne che utilizzano motori di ricerca come Elasticsearch. In particolare, nel nostro caso, è stata sviluppata una strategia ibrida che combina la ricerca tradizionale BM25 con la ricerca k-NN (k-nearest neighbors). Quest'approccio si rende necessario poiché i dati provenienti da un indice Elasticsearch esistente non sono strutturati in modo ideale per quanto richiesto da LangChain, una libreria di sviluppo per applicazioni di AI generativa. Per superare questa limitazione, è stato creato un sistema personalizzato di costruzione dei documenti e delle query, tramite le funzioni custom_document_builder e custom_query_builder. Questi strumenti sono cruciali per adattare i documenti estratti da Elasticsearch al formato atteso da LangChain, ottimizzando così la fase di recupero dei dati.
La funzione custom_document_builder è responsabile della costruzione dei documenti sulla base delle informazioni recuperate, mentre custom_query_builder consente una personalizzazione avanzata della query di ricerca. Questi passaggi sono essenziali per garantire che il sistema possa estrarre informazioni in modo efficace da Elasticsearch, adattandole al contesto di un'applicazione di AI generativa.
Un altro aspetto critico per il corretto funzionamento delle applicazioni di AI generativa è la gestione dei prompt, che definiscono come l'algoritmo deve comportarsi durante la generazione delle risposte. Il modello di linguaggio di tipo LLM (Large Language Model) deve essere guidato in modo preciso per garantire che le risposte vengano generate utilizzando esclusivamente il contesto dei documenti estratti. A tal fine, viene utilizzato un prompt che definisce chiaramente come l'AI debba rispondere, indicando che, se la risposta non è presente nel contesto fornito, l'algoritmo dovrà semplicemente rispondere con "non so". La formula di questo prompt, come definita nel sistema, è la seguente:
LangChain, per integrare tutti questi passaggi, fa uso del concetto di "catena" (chain), che consiste in una sequenza di chiamate a vari moduli, come il modello di linguaggio, la fase di recupero dei documenti o l'uso di strumenti specifici. Il cuore della catena nel nostro esempio è rappresentato dalla funzione setup_rag_chain, che combina tutti i passaggi necessari per il recupero dei dati e la generazione delle risposte. Questo processo è cruciale per garantire che ogni domanda venga trattata in modo completo e contestualizzato, con la capacità di restituire anche le fonti dei dati utilizzati per la risposta.
Nel codice, la funzione ask viene invocata ogni volta che l'utente invia una domanda, combinando la query dell'utente con la catena di recupero e generazione delle risposte. Una volta eseguita, questa funzione restituisce la risposta generata:
Per migliorare ulteriormente la personalizzazione e la flessibilità del sistema, l'applicazione include una barra laterale che consente all'utente di scegliere le impostazioni per il modello di linguaggio, come la selezione di Ollama/Mistral come LLM di default o OpenAI GPT-3.5, se disponibile. Questo consente di sperimentare con diverse configurazioni, regolando parametri come la temperatura (che influenza la varietà delle risposte) e il numero di documenti recuperati.
Inoltre, il sistema supporta approcci avanzati per ottimizzare le prestazioni della ricerca, come il retriever auto-querying e il MultiQueryRetriever. Questi metodi migliorano la qualità dei risultati di ricerca, permettendo di formulare query strutturate per il recupero dei dati o di generare più query per lo stesso input al fine di ottenere risposte più complete e diversificate.
Il retriever auto-querying trasforma la domanda originale in una query strutturata, che può essere eseguita direttamente contro l'indice Elasticsearch, migliorando la pertinenza dei risultati. Il MultiQueryRetriever, d'altra parte, genera più varianti della query originale, permettendo di esplorare diverse angolazioni di una stessa richiesta, aumentando le probabilità di ottenere informazioni rilevanti.
Per costruire applicazioni di AI generativa con recupero aumentato delle informazioni (RAG), la combinazione di tecniche avanzate come queste è essenziale. La personalizzazione dei parametri di ricerca, la gestione avanzata dei prompt e la configurazione di catene di recupero rappresentano strumenti indispensabili per ottimizzare la qualità delle risposte e rendere l'interazione con il sistema fluida ed efficace.
Una parte fondamentale della progettazione di applicazioni RAG avanzate è la gestione dei dati stessi. Un aspetto importante, ad esempio, è la segmentazione dei documenti, un processo che consiste nel suddividere i testi in frammenti più piccoli, più facilmente indicizzabili e ricercabili. In questo modo, il sistema può rispondere più rapidamente e in modo più preciso, poiché si concentra su porzioni di contenuto specifiche, piuttosto che su interi documenti.
Oltre a questa tecnica di segmentazione, un'altra considerazione cruciale per la creazione di un chatbot basato su RAG è la capacità di mantenere il contesto della conversazione. In un sistema di chatbot avanzato, l'integrazione di una logica conversazionale complessa permette di gestire il flusso delle interazioni, mantenendo la coerenza delle risposte e rispondendo in modo adeguato a domande che potrebbero non essere state previste in precedenza. L'uso di LangChain per la gestione del flusso conversazionale e della memoria contestuale è essenziale per creare un'esperienza utente davvero interattiva e coinvolgente.
La creazione di un'applicazione RAG in un contesto di AI generativa non si limita solo alla ricerca di informazioni, ma implica anche l'integrazione di tecniche avanzate di gestione della conversazione, segmentazione dei dati e configurazione dei modelli di linguaggio, al fine di garantire che il sistema risponda con precisione e coerenza.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский