RAG mit Milvus und Cognee entwickeln
Cognee ist eine auf Entwickler ausgerichtete Plattform, die die Entwicklung von KI-Anwendungen mit skalierbaren, modularen ECL-Pipelines (Extract, Cognify, Load) rationalisiert. Durch die nahtlose Integration mit Milvus ermöglicht Cognee eine effiziente Verbindung und Abfrage von Gesprächen, Dokumenten und Transkriptionen, wodurch Halluzinationen reduziert und Betriebskosten optimiert werden.
Durch die Unterstützung von Vektorspeichern wie Milvus, Graphdatenbanken und LLMs bietet Cognee ein flexibles und anpassbares Framework für den Aufbau von RAG-Systemen (Retrieval-Augmented Generation). Seine produktionsreife Architektur gewährleistet eine verbesserte Genauigkeit und Effizienz für KI-gestützte Anwendungen.
In diesem Tutorial zeigen wir Ihnen, wie Sie eine RAG-Pipeline (Retrieval-Augmented Generation) mit Milvus und Cognee erstellen.
$ pip install pymilvus git+https://github.com/topoteretes/cognee.git
Wenn Sie Google Colab verwenden, müssen Sie möglicherweise die Runtime neu starten, um die soeben installierten Abhängigkeiten zu aktivieren (klicken Sie auf das Menü "Runtime" am oberen Bildschirmrand und wählen Sie "Restart session" aus dem Dropdown-Menü).
Standardmäßig wird in diesem Beispiel OpenAI als LLM verwendet. Sie sollten den Api-Schlüssel vorbereiten und ihn in der Funktion config set_llm_api_key()
einstellen.
Um Milvus als Vektordatenbank zu konfigurieren, setzen Sie VECTOR_DB_PROVIDER
auf milvus
und geben Sie VECTOR_DB_URL
und VECTOR_DB_KEY
an. Da wir in dieser Demo Milvus Lite zum Speichern von Daten verwenden, muss nur die VECTOR_DB_URL
angegeben werden.
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"
Was die Umgebungsvariablen VECTOR_DB_URL
und VECTOR_DB_KEY
betrifft:
- Die Einstellung von
VECTOR_DB_URL
als lokale Datei, z. B../milvus.db
, ist die bequemste Methode, da sie automatisch Milvus Lite nutzt, um alle Daten in dieser Datei zu speichern. - Wenn Sie große Datenmengen haben, können Sie einen leistungsfähigeren Milvus-Server auf Docker oder Kubernetes einrichten. Bei dieser Einrichtung verwenden Sie bitte die Server-Uri, z. B.
http://localhost:19530
, alsVECTOR_DB_URL
. - Wenn Sie Zilliz Cloud, den vollständig verwalteten Cloud-Service für Milvus, nutzen möchten, passen Sie
VECTOR_DB_URL
undVECTOR_DB_KEY
an, die dem öffentlichen Endpunkt und dem Api-Schlüssel in Zilliz Cloud entsprechen.
Bereiten Sie die Daten vor
Wir verwenden die FAQ-Seiten aus der Milvus-Dokumentation 2.4.x als privates Wissen in unserer RAG, was eine gute Datenquelle für eine einfache RAG-Pipeline ist.
Laden Sie die Zip-Datei herunter und entpacken Sie die Dokumente in den Ordner 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
Wir laden alle Markdown-Dateien aus dem Ordner milvus_docs/en/faq
. Für jedes Dokument verwenden wir einfach "# ", um den Inhalt in der Datei zu trennen, wodurch der Inhalt jedes Hauptteils der Markdown-Datei grob getrennt werden kann.
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("# ")
RAG erstellen
Zurücksetzen der Cognee-Daten
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
Jetzt können wir unseren Datensatz hinzufügen und ihn zu einem Wissensgraphen verarbeiten.
Hinzufügen von Daten und Erkennen
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 ...
# ...
Die Methode add
lädt den Datensatz (Milvus FAQs) in Cognee und die Methode cognify
verarbeitet die Daten, um Entitäten, Beziehungen und Zusammenfassungen zu extrahieren und einen Wissensgraphen zu erstellen.
Abfrage nach Zusammenfassungen
Nun, da die Daten verarbeitet wurden, können wir den Wissensgraphen abfragen.
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.'}
Diese Abfrage durchsucht den Wissensgraphen nach einer Zusammenfassung, die mit dem Abfragetext in Beziehung steht, und der am meisten in Beziehung stehende Kandidat wird gedruckt.
Abfrage nach Chunks
Zusammenfassungen bieten Einblicke auf hoher Ebene, aber für detailliertere Informationen können wir bestimmte Datenpakete direkt aus dem verarbeiteten Datensatz abfragen. Diese Chunks werden aus den ursprünglichen Daten abgeleitet, die während der Erstellung des Wissensgraphen hinzugefügt und analysiert wurden.
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)
Formatieren und zeigen wir sie zur besseren Lesbarkeit an!
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.
###
In den vorangegangenen Schritten haben wir den Milvus-FAQ-Datensatz sowohl nach Zusammenfassungen als auch nach bestimmten Datenpaketen abgefragt. Dies lieferte zwar detaillierte Einblicke und granulare Informationen, aber der Datensatz war groß, so dass es schwierig war, die Abhängigkeiten innerhalb des Wissensgraphen klar zu visualisieren.
Um dieses Problem zu lösen, werden wir die Cognee-Umgebung zurücksetzen und mit einem kleineren, gezielteren Datensatz arbeiten. Dadurch können wir die Beziehungen und Abhängigkeiten, die während des Cognify-Prozesses extrahiert wurden, besser darstellen. Durch die Vereinfachung der Daten können wir klar erkennen, wie Cognee die Informationen im Wissensgraphen organisiert und strukturiert.
Cognee zurücksetzen
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
Hinzufügen des fokussierten Datensatzes
Hier wird ein kleinerer Datensatz mit nur einer Textzeile hinzugefügt und verarbeitet, um einen fokussierten und leicht interpretierbaren Wissensgraphen zu erhalten.
# 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()
Abfrage nach Einblicken
Durch die Fokussierung auf diesen kleineren Datensatz können wir nun die Beziehungen und Strukturen innerhalb des Wissensgraphen klar analysieren.
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').
Diese Ausgabe stellt die Ergebnisse einer Wissensgraphenabfrage dar und zeigt die Entitäten (Knoten) und ihre Beziehungen (Kanten), wie sie aus dem verarbeiteten Datensatz extrahiert wurden. Jedes Tupel enthält eine Quell-Entität, einen Beziehungstyp und eine Ziel-Entität, zusammen mit Metadaten wie eindeutigen IDs, Beschreibungen und Zeitstempeln. Der Graph hebt die wichtigsten Konzepte und ihre semantischen Verbindungen hervor und bietet ein strukturiertes Verständnis des Datensatzes.
Herzlichen Glückwunsch, Sie haben die grundlegende Verwendung von cognee mit Milvus gelernt. Wenn Sie mehr über die fortgeschrittene Nutzung von cognee erfahren möchten, besuchen Sie bitte die offizielle Seite.