MilvusとCogneeでRAGを構築する
Cogneeは、スケーラブルでモジュール化されたECL(Extract、Cognify、Load)パイプラインによりAIアプリケーション開発を合理化する開発者ファーストのプラットフォームです。CogneeはMilvusとシームレスに統合することで、会話、ドキュメント、トランスクリプションの効率的な接続と検索を可能にし、幻覚を減らし、運用コストを最適化します。
Milvusのようなベクトルストア、グラフデータベース、LLMを強力にサポートするCogneeは、検索支援世代(RAG)システムを構築するための柔軟でカスタマイズ可能なフレームワークを提供します。そのプロダクション・レディなアーキテクチャは、AIを活用したアプリケーションの精度と効率の向上を保証します。
このチュートリアルでは、MilvusとCogneeを使ってRAG(Retrieval-Augmented Generation)パイプラインを構築する方法を紹介します。
$ pip install pymilvus git+https://github.com/topoteretes/cognee.git
Google Colabを使用している場合、インストールしたばかりの依存関係を有効にするために、ランタイムを再起動する必要があるかもしれません(画面上部の "Runtime "メニューをクリックし、ドロップダウンメニューから "Restart session "を選択してください)。
この例では、デフォルトでOpenAIをLLMとして使用しています。apiキーを用意し、configset_llm_api_key()
。
Milvusをベクターデータベースとして設定するには、VECTOR_DB_PROVIDER
をmilvus
に設定し、VECTOR_DB_URL
とVECTOR_DB_KEY
を指定します。このデモではMilvus Liteを使ってデータを保存しているので、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"
環境変数としてはVECTOR_DB_URL
とVECTOR_DB_KEY
を指定する:
VECTOR_DB_URL
をローカルファイル、例えば./milvus.db
に設定するのが最も便利な方法である。- データ規模が大きい場合は、dockerやkubernetes上に、よりパフォーマンスの高いMilvusサーバを構築することができます。このセットアップでは、サーバの uri、例えば
http://localhost:19530
をVECTOR_DB_URL
として使用してください。 - MilvusのフルマネージドクラウドサービスであるZilliz Cloudを利用する場合は、Zilliz CloudのPublic EndpointとApi keyに対応する
VECTOR_DB_URL
とVECTOR_DB_KEY
を調整してください。
データの準備
Milvusドキュメント2.4.xのFAQページをRAGのプライベートナレッジとして使用する。
zipファイルをダウンロードし、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
フォルダmilvus_docs/en/faq
からすべてのマークダウン・ファイルをロードする。各ドキュメントについて、単に "# "を使ってファイル内のコンテンツを区切るだけで、マークダウン・ファイルの各主要部分のコンテンツを大まかに区切ることができる。
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の構築
Cogneeデータのリセット
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
データセットを追加し、ナレッジグラフに加工することができる。
データの追加とコグニファイ
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 ...
# ...
add
メソッドはデータセット(Milvus FAQs)をCogneeにロードし、cognify
メソッドはデータを処理してエンティティ、リレーションシップ、サマリーを抽出し、ナレッジグラフを構築します。
要約のクエリ
データが処理されたので、ナレッジグラフをクエリしてみましょう。
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.'}
このクエリは、クエリテキストに関連する要約をナレッジグラフから検索し、最も関連する候補を表示します。
チャンクのクエリ
要約はハイレベルな洞察を提供しますが、より詳細な詳細については、処理されたデータセットから直接データの特定のチャンクをクエリできます。これらのチャンクは、ナレッジグラフ作成時に追加・分析された元のデータから派生したものです。
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)
読みやすいように整形して表示しましょう!
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.
###
これまでのステップでは、MilvusのFAQデータセットに対して、要約と特定のデータチャンクの両方を照会しました。これは詳細な洞察と粒度の細かい情報を提供しましたが、データセットが大きかったため、ナレッジグラフ内の依存関係を明確に視覚化することが困難でした。
この問題に対処するため、Cognee環境をリセットし、より小さく、より焦点を絞ったデータセットで作業する。これにより、コグニファイ処理中に抽出された関係や依存関係をより明確に示すことができるようになります。データを単純化することで、Cogneeがどのようにナレッジグラフ内の情報を整理し、構造化するかを明確に見ることができます。
Cogneeのリセット
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
フォーカスされたデータセットの追加
ここでは、1行のテキストのみの小さなデータセットが追加され、ナレッジグラフがフォーカスされ解釈しやすくなるように処理されます。
# 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()
インサイトのクエリ
この小さなデータセットに焦点を当てることで、ナレッジグラフ内の関係と構造を明確に分析できるようになりました。
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').
この出力はナレッジグラフのクエリの結果を表しており、処理されたデータセットから抽出されたエンティティ(ノード)とその関係(エッジ)を示しています。各タプルには、一意のID、説明、タイムスタンプなどのメタデータとともに、ソース・エンティティ、関係タイプ、ターゲット・エンティティが含まれます。グラフは、主要な概念とその意味的なつながりを強調し、データセットの構造的な理解を提供します。
Milvusを使ったcogneeの基本的な使い方はご理解いただけたと思います。より高度な使い方を知りたい方はcogneeの公式ページをご覧ください。