Costruire RAG con Milvus e Cognee
Cognee è una piattaforma per sviluppatori che semplifica lo sviluppo di applicazioni AI con pipeline ECL (Extract, Cognify, Load) scalabili e modulari. Integrandosi perfettamente con Milvus, Cognee consente di collegare e recuperare in modo efficiente conversazioni, documenti e trascrizioni, riducendo le allucinazioni e ottimizzando i costi operativi.
Grazie al forte supporto per archivi vettoriali come Milvus, database a grafo e LLM, Cognee offre un framework flessibile e personalizzabile per la creazione di sistemi di generazione aumentata del reperimento (RAG). La sua architettura pronta per la produzione garantisce una maggiore precisione ed efficienza per le applicazioni basate sull'intelligenza artificiale.
In questo tutorial vi mostreremo come costruire una pipeline RAG (Retrieval-Augmented Generation) con Milvus e Cognee.
$ pip install pymilvus git+https://github.com/topoteretes/cognee.git
Se si utilizza Google Colab, per abilitare le dipendenze appena installate, potrebbe essere necessario riavviare il runtime (fare clic sul menu "Runtime" nella parte superiore dello schermo e selezionare "Riavvia sessione" dal menu a discesa).
Per impostazione predefinita, in questo esempio viene utilizzato OpenAI come LLM. È necessario preparare la chiave api e impostarla nella funzione config set_llm_api_key()
.
Per configurare Milvus come database vettoriale, impostare VECTOR_DB_PROVIDER
su milvus
e specificare VECTOR_DB_URL
e VECTOR_DB_KEY
. Poiché in questa demo utilizziamo Milvus Lite per memorizzare i dati, è necessario fornire solo VECTOR_DB_URL
.
import os
import cognee
cognee.config.set_llm_api_key("YOUR_OPENAI_API_KEY")
os.environ["VECTOR_DB_PROVIDER"] = "milvus"
os.environ["VECTOR_DB_URL"] = "./milvus.db"
Per quanto riguarda le variabili d'ambiente VECTOR_DB_URL
e VECTOR_DB_KEY
:
- L'impostazione di
VECTOR_DB_URL
come file locale, ad esempio./milvus.db
, è il metodo più conveniente, poiché utilizza automaticamente Milvus Lite per memorizzare tutti i dati in questo file. - Se si dispone di una grande quantità di dati, è possibile configurare un server Milvus più performante su docker o kubernetes. In questa configurazione, utilizzare l'uri del server, ad esempio
http://localhost:19530
, comeVECTOR_DB_URL
. - Se si desidera utilizzare Zilliz Cloud, il servizio cloud completamente gestito da Milvus, è necessario impostare
VECTOR_DB_URL
eVECTOR_DB_KEY
, che corrispondono all'endpoint pubblico e alla chiave Api di Zilliz Cloud.
Preparare i dati
Utilizziamo le pagine FAQ della Documentazione di Milvus 2.4.x come conoscenza privata nel nostro RAG, che è una buona fonte di dati per una semplice pipeline RAG.
Scaricare il file zip ed estrarre i documenti nella cartella milvus_docs
.
$ wget https://github.com/milvus-io/milvus-docs/releases/download/v2.4.6-preview/milvus_docs_2.4.x_en.zip
$ unzip -q milvus_docs_2.4.x_en.zip -d milvus_docs
Carichiamo tutti i file markdown dalla cartella milvus_docs/en/faq
. Per ogni documento, usiamo semplicemente "# " per separare il contenuto del file, che può separare approssimativamente il contenuto di ogni parte principale del file markdown.
from glob import glob
text_lines = []
for file_path in glob("milvus_docs/en/faq/*.md", recursive=True):
with open(file_path, "r") as file:
file_text = file.read()
text_lines += file_text.split("# ")
Creare RAG
Ripristino dei dati di Cognee
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
Dopo aver fatto tabula rasa, possiamo aggiungere il nostro set di dati ed elaborarlo in un grafo della conoscenza.
Aggiungere i dati e cognificare
await cognee.add(data=text_lines, dataset_name="milvus_faq")
await cognee.cognify()
# [DocumentChunk(id=UUID('6889e7ef-3670-555c-bb16-3eb50d1d30b0'), updated_at=datetime.datetime(2024, 12, 4, 6, 29, 46, 472907, tzinfo=datetime.timezone.utc), text='Does the query perform in memory? What are incremental data and historical data?\n\nYes. When ...
# ...
Il metodo add
carica il set di dati (Milvus FAQs) in Cognee e il metodo cognify
elabora i dati per estrarre entità, relazioni e sommari, costruendo un grafo della conoscenza.
Interrogazione dei sommari
Ora che i dati sono stati elaborati, interroghiamo il grafo della conoscenza.
from cognee.api.v1.search import SearchType
query_text = "How is data stored in milvus?"
search_results = await cognee.search(SearchType.SUMMARIES, query_text=query_text)
print(search_results[0])
{'id': 'de5c6713-e079-5d0b-b11d-e9bacd1e0d73', 'text': 'Milvus stores two data types: inserted data and metadata.'}
Questa interrogazione cerca nel grafo della conoscenza un sommario correlato al testo dell'interrogazione e il candidato più correlato viene stampato.
Interrogazione per pezzi
I riepiloghi offrono approfondimenti di alto livello, ma per ottenere dettagli più dettagliati è possibile interrogare pezzi specifici di dati direttamente dal set di dati elaborati. Questi pezzi sono derivati dai dati originali che sono stati aggiunti e analizzati durante la creazione del grafo della conoscenza.
from cognee.api.v1.search import SearchType
query_text = "How is data stored in milvus?"
search_results = await cognee.search(SearchType.CHUNKS, query_text=query_text)
Formattiamoli e visualizziamoli per una migliore leggibilità!
def format_and_print(data):
print("ID:", data["id"])
print("\nText:\n")
paragraphs = data["text"].split("\n\n")
for paragraph in paragraphs:
print(paragraph.strip())
print()
format_and_print(search_results[0])
ID: 4be01c4b-9ee5-541c-9b85-297883934ab3
Text:
Where does Milvus store data?
Milvus deals with two types of data, inserted data and metadata.
Inserted data, including vector data, scalar data, and collection-specific schema, are stored in persistent storage as incremental log. Milvus supports multiple object storage backends, including [MinIO](https://min.io/), [AWS S3](https://aws.amazon.com/s3/?nc1=h_ls), [Google Cloud Storage](https://cloud.google.com/storage?hl=en#object-storage-for-companies-of-all-sizes) (GCS), [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs), [Alibaba Cloud OSS](https://www.alibabacloud.com/product/object-storage-service), and [Tencent Cloud Object Storage](https://www.tencentcloud.com/products/cos) (COS).
Metadata are generated within Milvus. Each Milvus module has its own metadata that are stored in etcd.
###
Nelle fasi precedenti, abbiamo interrogato il dataset Milvus FAQ per ottenere sia riepiloghi che pezzi specifici di dati. Se da un lato questo ha fornito approfondimenti dettagliati e informazioni granulari, dall'altro il set di dati era di grandi dimensioni, il che ha reso difficile visualizzare chiaramente le dipendenze all'interno del grafo della conoscenza.
Per risolvere questo problema, ripristineremo l'ambiente Cognee e lavoreremo con un set di dati più piccolo e mirato. Questo ci permetterà di mostrare meglio le relazioni e le dipendenze estratte durante il processo di cognificazione. Semplificando i dati, possiamo vedere chiaramente come Cognee organizza e struttura le informazioni nel grafo della conoscenza.
Resettare Cognee
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
Aggiunta del set di dati focalizzato
In questo caso, viene aggiunto ed elaborato un set di dati più piccolo con una sola riga di testo, per garantire un grafico della conoscenza mirato e facilmente interpretabile.
# We only use one line of text as the dataset, which simplifies the output later
text = """
Natural language processing (NLP) is an interdisciplinary
subfield of computer science and information retrieval.
"""
await cognee.add(text)
await cognee.cognify()
Interrogazione per gli approfondimenti
Concentrandoci su questo set di dati più piccolo, possiamo ora analizzare chiaramente le relazioni e la struttura all'interno del grafico della conoscenza.
query_text = "Tell me about NLP"
search_results = await cognee.search(SearchType.INSIGHTS, query_text=query_text)
for result_text in search_results:
print(result_text)
# Example output:
# ({'id': UUID('bc338a39-64d6-549a-acec-da60846dd90d'), 'updated_at': datetime.datetime(2024, 11, 21, 12, 23, 1, 211808, tzinfo=datetime.timezone.utc), 'name': 'natural language processing', 'description': 'An interdisciplinary subfield of computer science and information retrieval.'}, {'relationship_name': 'is_a_subfield_of', 'source_node_id': UUID('bc338a39-64d6-549a-acec-da60846dd90d'), 'target_node_id': UUID('6218dbab-eb6a-5759-a864-b3419755ffe0'), 'updated_at': datetime.datetime(2024, 11, 21, 12, 23, 15, 473137, tzinfo=datetime.timezone.utc)}, {'id': UUID('6218dbab-eb6a-5759-a864-b3419755ffe0'), 'updated_at': datetime.datetime(2024, 11, 21, 12, 23, 1, 211808, tzinfo=datetime.timezone.utc), 'name': 'computer science', 'description': 'The study of computation and information processing.'})
# (...)
#
# It represents nodes and relationships in the knowledge graph:
# - The first element is the source node (e.g., 'natural language processing').
# - The second element is the relationship between nodes (e.g., 'is_a_subfield_of').
# - The third element is the target node (e.g., 'computer science').
Questo output rappresenta i risultati di una query sul grafo della conoscenza, che mostra le entità (nodi) e le loro relazioni (spigoli) estratte dal dataset elaborato. Ogni tupla include un'entità di origine, un tipo di relazione e un'entità di destinazione, insieme a metadati come ID univoci, descrizioni e timestamp. Il grafico evidenzia i concetti chiave e le loro connessioni semantiche, fornendo una comprensione strutturata del set di dati.
Complimenti, avete imparato l'uso di base di cognee con Milvus. Se volete conoscere un uso più avanzato di cognee, consultate la sua pagina ufficiale.