MilvusとHaystack 2.0によるRAGパイプラインの構築
このガイドでは、MilvusとHaystack 2.0を統合し、強力な質問応答アプリケーションを構築する方法を説明します。
シリーズ全体を読む
- 楽々AIワークフロー:Hugging FaceとPyMilvusの初心者ガイド
- MilvusとHaystack 2.0によるRAGパイプラインの構築
- Milvusインスタンスでベクターインデックスを選ぶ方法:ビジュアルガイド
- MilvusとOpenAIによるセマンティック検索
- GCP KubernetesでMilvusを効率的にデプロイする:オープンソースデータベース管理ガイド
- 北極雪片とMilvus上のトランスフォーマーでRAGを作る
- MilvusでJSONデータをベクトル化し、類似性検索を行う
- Gemini 1.5、BGE-M3、Milvus Lite、LangChainによるマルチモーダルRAGの構築
#はじめに
自然言語処理(NLP)において、MilvusとHaystackは高度なアプリケーションを構築するための強力なツールとして登場した。非構造化データの量が飛躍的に増加する中、組織は文書コレクションから価値ある洞察を抽出する効率的かつ効果的な方法を求めている。従来の検索手法では、コンテンツの意味や文脈を把握できないことが多く、最適な検索結果が得られなかったり、使い勝手が悪かったりする。そこで、ベクトルデータベースであるMilvusと、実稼働可能なLLMアプリケーションを構築するためのオープンソースフレームワークであるHaystack 2.0の組み合わせが活躍する。これらの最先端技術の長所を活用することで、開発者やデータサイエンティストは文書リポジトリの真の可能性を引き出し、より高速で正確な情報検索、意味検索、知識発見を実現することができる。
この記事では、MilvusとHaystack 2.0がどのようにシームレスに統合できるのか、そしてこの統合を利用して強力な検索拡張世代(RAG)アプリケーションを構築する方法を探ります。Milvusのベクトルインデックス機能とHaystackのRAGフレームワークを活用することで、ユーザのクエリに対する正確な回答を生成するために文書を効率的に処理、保存、検索する方法を紹介する。
Milvusとは?
Milvusは高次元ベクトルを効率的に扱うために設計されたオープンソースのベクトルデータベースです。Zillizの開発者がこのプロジェクトを管理している。自然言語処理(NLP)や文書検索の文脈では、ベクトルは高次元空間におけるテキストやその他のデータポイントの数値表現です。これらのベクトルは、データ点間の意味や関係を捉え、類似性に基づく検索や比較を可能にする。
埋め込み文書の保存と検索に関して、Milvusはいくつかの重要な利点を提供します:
1.高次元ベクトルインデックス: Milvusは高次元ベクトルのインデックス作成と検索に最適化されています。階層型ナビゲーシブルスモールワールドグラフ(HNSW)やインバーテッドファイルシステム(IVF)などの高度なインデックス作成技術を利用し、効率的なインデックス構造を作成します。これらのインデックス構造により、数百万から数十億のベクトルを持つ大規模データセットでも、高速な類似検索が可能になります。
2.スケーラビリティと性能: Milvusは、高性能を維持しながら大量のベクトルデータを処理できるように設計されています。Milvusは複数のノードやマシンを水平方向に拡張することができ、分散ストレージや並列処理を可能にします。このスケーラビリティにより、Milvusは検索速度や精度を損なうことなく、データセットの増大や高いクエリスループットに対応することができます。
3.マルチベクトルおよびハイブリッド検索: ユーザーは1つのコレクションに最大10個のベクトルフィールドを含めることができ、それぞれが様々な埋め込みモデルやデータタイプでデータの異なる側面を表します。このエンリッチメントにより検索機能が強化され、画像、音声、テキストなどを表すメタデータやベクトル埋め込みなどの属性に基づいて、ベクトル・データベース内の最も類似したアイテムを見つけることができます。マルチベクトル検索は、これらのフィールドにまたがるクエリを実行し、RRF(Reciprocal Rank Fusion)や重み付きスコアリング(Weighted Scoring)のようなリランキング戦略を使用して結果をマージします。
4.機械学習モデルとの統合: Milvusは、OpenAI、Cohere、VoyageAIの一般的な機械学習モデルと統合されています。この統合により、非構造化データをMilvusのベクトル埋め込みに簡単に変換し、効率的な検索が可能になります。
5.複数のインデックスと距離メトリックのサポート: Milvusは様々なユースケースやデータ特性に対応するため、様々なインデックスアルゴリズムと距離メトリックをサポートしています。特定の要件に応じて、HNSW、IVF、ANNOY、FAISSなどのインデックス作成オプションから選択することができます。さらに、Milvusはユークリッド距離、コサイン類似度、内積などの距離メトリクスをサポートしており、お客様の用途に最も適したメトリックを選択することができます。
埋め込み文書の保存と検索に関しては、Milvusはいくつかの点で優れています:
効率的なストレージ:** Milvusは圧縮表現と最適化されたデータ構造を利用することで、高次元ベクトルを効率的に保存します。これにより、ベクトルデータの完全性を維持しながら、ストレージのオーバーヘッドを削減します。
高速検索:**高度なインデックス作成技術とクエリの最適化により、Milvusはベクトル表現に基づく類似文書の電光石火の高速検索を可能にします。何百万ものベクトルを素早く検索し、最も関連性の高い文書を数ミリ秒で返します。
意味的類似性: ベクトル埋め込みを活用することで、Milvusは意味的類似性に基づいた文書の検索を可能にします。キーワードの完全一致のみに頼るのではなく、Milvusはベクトルによって捕らえられた意味的な意味を考慮し、より文脈的で意味のある検索結果を可能にします。
スケーラブルな更新:** Milvusは、データベース全体の完全な再インデックスを必要とすることなく、新しいベクトルの埋め込みの動的な更新と挿入をサポートします。これにより、効率的な検索パフォーマンスを維持しながら、コレクションの成長と進化が可能になります。
高次元のベクトルインデックス、スケーラビリティ、ハイブリッド検索機能、そして効率的なストレージと検索メカニズムを組み合わせることで、Milvusはエンベッディングの保存と検索のための強力なソリューションを提供します。Milvusは、セマンティック検索、推薦システム、コンテンツベースの検索などのアプリケーションに、正確で関連性の高い結果をリアルタイムで提供することを可能にします。
Haystack 2.0とは?
Haystack (by deepset.ai)はオープンソースのPythonフレームワークで、大規模な文書コレクションに対してインテリジェントに動作するLLMアプリケーション、検索を補強した生成パイプライン、検索システムを構築するためのものです。Haystack 2.0は、旧バージョンを大幅に改良したもので、使いやすく、カスタマイズ、拡張、最適化、評価、そして最終的には本番環境へのデプロイが容易な、コンポーザブルなAIシステムの実装を可能にします。
Haystackの核となるのはコンポーネントで、文書検索、テキスト生成、要約などのタスクを実行できる基本的なビルディング・ブロックだ。Haystackには、すぐに使えるコンポーネントがたくさん用意されていますが、Pythonのクラスを書くのと同じくらい簡単に、独自のカスタムコンポーネントを作成することもできます。HaystackのLLMアプリケーションアーキテクチャの基盤であるパイプラインを構築するために、コンポーネントを接続することができます。
**パイプライン:RAGとその先
Haystackのパイプラインは、LLMアプリケーションのデータフローを定義できる強力な抽象化機能です。パイプラインはコンポーネントで構成されます。パイプラインは基本的にグラフ、あるいはマルチグラフです。パイプラインの柔軟性のおかげで、複数の出力を持つ1つのコンポーネントが、複数の入力を持つ別のコンポーネントや複数のコンポーネントに接続することができます。
Haystackは、インデックス作成、抽出QA、ウェブ検索など、様々なユースケースに対応した パイプラインの例 を多数提供しています。この投稿では、RAGパイプラインに焦点を当てます。RAGパイプラインは、ユーザーのクエリに基づいてLLMにコンテキストに関連するドキュメントを提供し、より良い回答を生成できるようにします。
Haystack 2.0は、LLMアプリケーションの開発を強化するための様々な機能や機能も提供しています。
ウェブ上のあらゆる場所からの検索拡張のためのデータソースの統合
Jinja2テンプレート言語によるLLMプロンプト用の高度な動的テンプレート
さまざまなデータ形式とデータソースに対応するクリーニングと前処理機能
システム全体または個々のコンポーネントを評価するためにさまざまなメトリクスを使用する特別な評価ツール
HTTPエンドポイントを介してHaystack Pipelinesを提供するHayhooksモジュール。
カスタマイズ可能なロギングシステムで、構造化されたロギングと相関関係のトレースをすぐにサポートします。
Open TelemetryとDatadogのサポートにより、実行パスの戦略的なポイントでスパンとトレースを収集するコードインスツルメンテーション。
Milvusとの統合:
Haystack 2.0の主な利点の一つは、高次元ベクトルをインデックス化して検索するベクターデータベースであるMilvusとのシームレスな統合です。開発者は、Haystack 2.0のRAGパイプラインとMilvusのベクトル保存・検索機能を組み合わせることにより、文書評価アプリケーションを作成することができます。Milvusは大規模な文書コレクションに対する高速でスケーラブルな類似性検索を可能にし、検索コンポーネントが与えられたクエリに対して最も関連性の高い文書を特定することを可能にします。この統合により、大量の非構造化テキストデータを扱う非常に効率的で正確なQAシステムを構築できる可能性が広がります。
セットアップとインストール
Pythonがインストールされていることを確認してください(バージョン3.6以上)。インストールされていない場合は、https://www.python.org からダウンロードできます。Pythonがインストールできたら、以下のコマンドを使ってPython環境に必要なパッケージをすべてインストールできます:
pip install --upgrade pymilvus milvus-haystack markdown-it-py mdit_plain pypdf sentence-transformers
Note: "pip "コマンドが動作しない場合、コマンドプロンプトがPythonをインストールした環境にないか、システムの環境変数に基づいてPythonがどこにあるかをシステムが "認識 "するようにコンピュータを再起動する必要があります。
重要:LLMの世界では、物事はすぐに変わる可能性があります。最新のコードサンプルはHaystack's tutorials を参照してください。
トラックに戻る:ドキュメントの保存
文書ストアは、文書を保存・管理するための一元化されたリポジトリとして、自然言語処理アプリケーションにおいて重要な役割を果たします。このガイドではMilvusをドキュメントストアとして使用し、その高性能なベクトル類似検索機能を活用します。それでは始めましょう。
インデックス作成パイプラインの構築
インデキシングパイプラインはMilvusDocumentStoreのドキュメントを処理し、格納する役割を担っています。ここでは、インデックス作成パイプラインのセットアップをステップバイステップで説明します。
コーディングを始める前に、"recipe_files" というプロジェクトのサブフォルダにいくつかのサンプルファイルを追加してください。この例では、some recipes from this folderを使用しました。コード内のファイルパスを正しいファイル名に修正すれば、どのようなファイルでも使用できます。
**1.MilvusDocumentStoreを初期化する。
from milvus_haystack import MilvusDocumentStore
document_store = MilvusDocumentStore(
connection_args={
"uri":"http://localhost:19530", #あなたのMilvusサービスURI
},
drop_old=True、
)
注意: 上記のコードと、それに続くすべてのコードについて、エラーチェック、エラー処理、エラーログを追加することを強く推奨します。実際には、ネットワークの問題、設定エラー、データ形式の問題など、さまざまな理由でドキュメントの索引付けや検索操作が失敗する可能性があります。エラー処理ルーチンを追加することで、スクリプトをより堅牢にし、トラブルシューティングを容易にすることができます。
**2.文書処理に必要なコンポーネントを設定する。
from haystack.components.writers import DocumentWriter
from haystack.components.converters import MarkdownToDocument, PyPDFToDocument, TextFileToDocument
from haystack.components.preprocessors import DocumentSplitter, DocumentCleaner
from haystack.components.routers import FileTypeRouter
from haystack.components.joiners import DocumentJoiner
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack import Pipeline
# インデックス作成パイプラインで必要なコンポーネントを初期化します。
file_type_router = FileTypeRouter(mime_types=["text/plain", "application/pdf", "text/markdown"])
text_file_converter = TextFileToDocument()
markdown_converter = MarkdownToDocument()
pdf_converter = PyPDFToDocument()
document_joiner = DocumentJoiner()
document_cleaner = DocumentCleaner()
document_splitter = DocumentSplitter(split_by="word", split_length=150, split_overlap=50)
document_embedder = SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
document_writer = DocumentWriter(document_store)
**3.ドキュメントのインデックスを作成する。
コンポーネントをパイプラインに追加します。各コンポーネントの入出力と実行順序を指定するために、コンポーネントを接続します。
preprocessing_pipeline = Pipeline()
preprocessing_pipeline.add_component(instance=file_type_router, name="file_type_router")
preprocessing_pipeline.add_component(instance=text_file_converter,name="text_file_converter")。
前処理パイプライン.add_component(instance=markdown_converter, name="markdown_converter")
preprocessing_pipeline.add_component(instance=pdf_converter,name="pypdf_converter")。
preprocessing_pipeline.add_component(instance=document_joiner,name="document_joiner")。
前処理パイプライン.add_component(instance=document_cleaner, name="document_cleaner")
前処理パイプライン.add_component(instance=document_splitter, name="document_splitter")
前処理パイプライン.add_component(instance=document_embedder, name="document_embedder")
前処理パイプライン.add_component(instance=document_writer, name="document_writer")
前処理_パイプライン.connect("file_type_router.text/plain", "text_file_converter.sources")
前処理パイプライン接続("file_type_router.application/pdf", "pypdf_converter.sources")
前処理パイプライン.connect("file_type_router.text/markdown", "markdown_converter.sources")
前処理パイプライン.connect("text_file_converter", "document_joiner")
前処理パイプライン.connect("pypdf_converter", "document_joiner")
前処理パイプライン.connect("markdown_converter", "document_joiner")
前処理パイプライン.connect("document_joiner", "document_cleaner")
前処理パイプライン.connect("document_cleaner", "document_splitter")
前処理パイプライン.connect("document_splitter", "document_embedder")
前処理パイプライン.connect("document_embedder", "document_writer")
パイプラインを実行する
from pathlib import Path
output_dir = "recipe_files"
preprocessing_pipeline.run({"file_type_router":{"sources": list(Path(output_dir).glob("**/*"))}})
print(document_store.count_documents())
インデックス作成中、ドキュメントは処理され、テキストに変換され、チャンクに分割され、高次元ベクトルに埋め込まれる。これらの埋め込みベクトルは、意味的類似性に基づく効率的な検索のために重要である。
RAGパイプラインの統合
RAG (Retrieval-Augmented Generation)パイプラインは、大規模言語モデル(LLM)を使って、文書検索と回答生成を組み合わせます。この例では、OpenAIのキーが必要です。これを環境変数 OPENAI_API_KEY に設定する。Haystackがサポートしているモデルの全リストは、ドキュメントを参照。
RAGパイプラインの設定方法は以下の通り:
from haystack import Pipeline
from haystack.utils import Secret
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack.components.builders import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from milvus_haystack.milvus_embedding_retriever import MilvusEmbeddingRetriever
インポート os
os.environ["TOKENIZERS_PARALLELISM"] = "false"
テンプレート = """
与えられた文脈に基づいて質問に答える。
コンテキスト
{ドキュメント内のドキュメントに対して %}
{{ document.content }}
{% endfor %}
質問{{ 質問 }}
答え
"""
rag_pipeline = Pipeline()
rag_pipeline.add_component("embedder", SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"))
rag_pipeline.add_component("retriever", MilvusEmbeddingRetriever(document_store=document_store))
rag_pipeline.add_component("prompt_builder", PromptBuilder(template=template))
rag_pipeline.add_component("llm", OpenAIGenerator(api_key=Secret.from_token(os.getenv("OPENAI_API_KEY"))、
generation_kwargs={"temperature":0}))
rag_pipeline.connect("embedder.embedding", "retriever.query_embedding")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
質問 = (
"ビーガンケト茄子ラザニア、ビーガン柿フラン、ビーガン麻チーズを作るにはどんな材料が必要ですか?"
)
response = rag_pipeline.run(
{
"embedder":{"text": question}、
"prompt_builder":{"question": 質問}、
}
)
print(レスポンス)
{'llm':{'replies': ['To make vegan keto eggplant lasagna, you would need ingredients such as eggplants, basil, almonds, nutritional yeast, olive oil, tofu, spinach, lemon, garlic powder, macadamia nuts, agar agar, and vegan mozzarella.\Vegan persimmon flanを作るには、柿の果肉、コーンスターチ、寒天、アガベネクター、グラニュー糖、ココナッツクリーム、アーモンドミルク、バニラなどの材料が必要。\ヴィーガン麻チーズを作るには、ひまわりの種、麻の実、味噌、栄養酵母、リジュベラック、塩などの材料が必要です:0, 'finish_reason':stop', 'usage':{'completion_tokens':130, 'prompt_tokens':3016, 'total_tokens':3146}}]}}
また、前述したように、AIの状況は急速に変化しているため、上記のコードやこのドキュメント全体を通して、例として扱うことをお勧めします。Haystackの広範なリソースページにある最新のドキュメントとサンプルを参照してください。この記事の最後に記載されているリソースに注意してください。
RAGパイプラインは、クエリに基づいて関連文書を検索し、検索された文書を使ってOpenAIGenerator用のプロンプトを生成し、LLMを使って答えを生成します。そして、生成された回答が最終出力として返される。
結論
MilvusとHaystack 2.0の統合は、効率的で正確な質問応答アプリケーションを構築するための強力なフレームワークを提供します。Milvusのベクトルインデックス作成機能とHaystackの検索支援生成パイプラインを活用することで、効率的に文書を処理、保存、評価し、ユーザからの質問に対して適切な回答を生成するシステムを構築することができます。本ガイドで説明する手順で、これらのテクノロジーを使用した高度なNLPアプリケーションの構築を開始することができます。
リソース
Milvusのドキュメント:https://milvus.io/docs
Milvus コミュニティ (GitHub, Discord, Reddit, Twitter):https://milvus.io/community
Haystackドキュメント:https://docs.haystack.deepset.ai/docs/intro
Haystack API リファレンス:https://docs.haystack.deepset.ai/reference
ヘイスタック・ディスコードhttps://discord.com/invite/VBpFzsgRVF
読み続けて

楽々AIワークフロー:Hugging FaceとPyMilvusの初心者ガイド
この包括的なガイドでは、PyMilvusとHugging Faceデータセットを活用して機械学習プロジェクトを強化する方法を学びます。

MilvusとOpenAIによるセマンティック検索
このガイドでは、MilvusとOpenAIのEmbedding APIを統合したセマンティック検索機能について、書籍のタイトル検索をユースケース例としてご紹介します。

MilvusでJSONデータをベクトル化し、類似性検索を行う
この記事では、MilvusがJSONデータのベクトル化、取り込み、類似検索をどのように効率化するかを紹介する。
