Open In Colab GitHub Repository

LlamaIndexとmilvusで全文検索を使う

全文検索では、キーワードの完全一致を使用し、多くの場合BM25のようなアルゴリズムを活用して関連性によって文書をランク付けする。検索拡張生成(RAG)システムでは、この方法はAIが生成した応答を強化するために適切なテキストを検索する。

一方、セマンティック検索は文脈の意味を解釈して、より広範な結果を提供する。この2つのアプローチを組み合わせることで、情報検索を向上させるハイブリッド検索が実現する。

Milvus2.5のSparse-BM25アプローチでは、生テキストは自動的にスパースベクトルに変換されます。これにより、手作業によるスパース埋め込み生成が不要になり、意味理解とキーワードの関連性のバランスをとったハイブリッド検索戦略が可能になります。

このチュートリアルでは、LlamaIndexとMilvusを使って、全文検索とハイブリッド検索を使ったRAGシステムを構築する方法を学びます。まずは全文検索を単独で実装し、次にセマンティック検索を統合してより包括的な結果を得られるように拡張していきます。

このチュートリアルを進める前に、全文検索と LlamaIndexにおけるMilvusの基本的な使い方を理解しておいてください。

前提条件

依存関係のインストール

始める前に、以下の依存関係がインストールされていることを確認してください:

$ $pip install llama-index-vector-stores-milvus
$ $pip install llama-index-embeddings-openai
$ $pip install llama-index-llms-openai

Google Colabを使用している場合、ランタイムを再起動する必要があるかもしれません(インターフェースの上部にある "Runtime "メニューに移動し、ドロップダウンメニューから "Restart session "を選択してください)。

アカウントの設定

このチュートリアルでは、テキスト埋め込みと回答生成にOpenAIを使います。OpenAIのAPIキーを準備する必要があります。

import openai

openai.api_key = "sk-"

Milvusベクターストアを使用するには、MilvusサーバをURI (オプションでTOKEN)で指定します。Milvusサーバを立ち上げるには、Milvusのインストールガイドに従うか、Zilliz Cloudを無料で試すことができる。

全文検索は現在、Milvus Standalone、Milvus Distributed、Zilliz Cloudでサポートされていますが、Milvus Liteではまだサポートされていません(将来実装予定)。詳細は support@zilliz.com までお問い合わせください。

URI = "http://localhost:19530"
# TOKEN = ""

サンプルデータのダウンロード

以下のコマンドを実行し、サンプルドキュメントを「data/paul_graham」ディレクトリにダウンロードしてください:

$ mkdir -p 'data/paul_graham/'
$ $wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
--2025-03-27 07:49:01--  https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 75042 (73K) [text/plain]
Saving to: ‘data/paul_graham/paul_graham_essay.txt’

data/paul_graham/pa 100%[===================>]  73.28K  --.-KB/s    in 0.07s   

2025-03-27 07:49:01 (1.01 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]

全文検索をRAGシステムに統合することで、セマンティック検索と正確で予測可能なキーワードベースの検索のバランスが取れます。より良い検索結果を得るためには、全文検索とセマンティック検索を組み合わせることをお勧めしますが、全文検索のみを使用することもできます。ここではデモンストレーションのため、全文検索のみとハイブリッド検索を示します。

はじめに、SimpleDirectoryReaderLoad 、Paul Grahamのエッセイ「What I Worked On」を読み込んでください:

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./data/paul_graham/").load_data()

# Let's take a look at the first document
print("Example document:\n", documents[0])
Example document:
 Doc ID: 16b7942f-bf1a-4197-85e1-f31d51ea25a9
Text: What I Worked On  February 2021  Before college the two main
things I worked on, outside of school, were writing and programming. I
didn't write essays. I wrote what beginning writers were supposed to
write then, and probably still are: short stories. My stories were
awful. They had hardly any plot, just characters with strong feelings,
which I ...

BM25による全文検索

LlamaIndex のMilvusVectorStore は全文検索をサポートしており、キーワードベースの効率的な検索が可能です。組み込み関数をsparse_embedding_function 、検索結果のランク付けにBM25スコアリングを適用します。

このセクションでは、全文検索にBM25を使ったRAGシステムの実装方法を示す。

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.vector_stores.milvus.utils import BM25BuiltInFunction
from llama_index.core import Settings

# Skip dense embedding model
Settings.embed_model = None

# Build Milvus vector store creating a new collection
vector_store = MilvusVectorStore(
    uri=URI,
    # token=TOKEN,
    enable_dense=False,
    enable_sparse=True,  # Only enable sparse to demo full text search
    sparse_embedding_function=BM25BuiltInFunction(),
    overwrite=True,
)

# Store documents in Milvus
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
Embeddings have been explicitly disabled. Using MockEmbedding.

上記のコードでは、Milvusにサンプル文書を挿入し、全文検索のためのBM25ランキングを有効にするためのインデックスを構築している。これは密な埋め込みを無効にし、デフォルトのパラメータでBM25BuiltInFunction

BM25BuiltInFunction パラメータで入力フィールドと出力フィールドを指定することができます:

  • input_field_names (str):入力テキスト・フィールド(デフォルト:"text")。これは、BM25アルゴリズムがどのテキストフィールドに適用されるかを示す。異なるテキストフィールド名を持つ独自のコレクションを使用する場合は、これを変更する。
  • output_field_names (str):このBM25関数の出力が格納されるフィールド(デフォルト:"sparse_embedding")。

ベクトルストアが設定されると、Milvusを使ってクエリーモード "sparse "または "text_search "で全文検索クエリーを実行することができます:

import textwrap

query_engine = index.as_query_engine(
    vector_store_query_mode="sparse", similarity_top_k=5
)
answer = query_engine.query("What did the author learn at Viaweb?")
print(textwrap.fill(str(answer), 100))
The author learned several important lessons at Viaweb. They learned about the importance of growth
rate as the ultimate test of a startup, the value of building stores for users to understand retail
and software usability, and the significance of being the "entry level" option in a market.
Additionally, they discovered the accidental success of making Viaweb inexpensive, the challenges of
hiring too many people, and the relief felt when the company was acquired by Yahoo.

テキストアナライザーのカスタマイズ

アナライザは文章をトークンに分割し、ステミングやストップワード除去などの語彙処理を行うことで、全文検索において重要な役割を果たします。アナライザは通常、言語固有である。詳細はMilvus Analyzer Guideをご参照ください。

Milvusは2種類のアナライザをサポートしています:ビルトイン アナライザと カスタム アナライザです。デフォルトでは、BM25BuiltInFunction 、句読点に基づいてテキストをトークン化する標準の内蔵アナライザが使用されます。

別のアナライザを使用したり、既存のアナライザをカスタマイズしたりするには、analyzer_params 引数に値を渡します:

bm25_function = BM25BuiltInFunction(
    analyzer_params={
        "tokenizer": "standard",
        "filter": [
            "lowercase",  # Built-in filter
            {"type": "length", "max": 40},  # Custom cap size of a single token
            {"type": "stop", "stop_words": ["of", "to"]},  # Custom stopwords
        ],
    },
    enable_match=True,
)

再ランカーによるハイブリッド検索

ハイブリッド検索システムは、セマンティック検索と全文検索を組み合わせ、RAGシステムにおける検索パフォーマンスを最適化する。

以下の例では、セマンティック検索にOpenAIエンベッディングを使用し、全文検索にBM25を使用しています:

# Create index over the documnts
vector_store = MilvusVectorStore(
    uri=URI,
    # token=TOKEN,
    # enable_dense=True,  # enable_dense defaults to True
    dim=1536,
    enable_sparse=True,
    sparse_embedding_function=BM25BuiltInFunction(),
    overwrite=True,
    # hybrid_ranker="RRFRanker",  # hybrid_ranker defaults to "RRFRanker"
    # hybrid_ranker_params={},  # hybrid_ranker_params defaults to {}
)

storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
    documents,
    storage_context=storage_context,
    embed_model="default",  # "default" will use OpenAI embedding
)

仕組み

このアプローチでは、Milvusコレクションに両方のベクトルフィールドを持つ文書を格納する:

  • embedding:意味検索のためのOpenAI埋め込みモデルによって生成された密な埋め込み。
  • sparse_embedding:全文検索のためにBM25BuiltInFunctionを用いて計算された疎埋め込み。

さらに、"RRFRanker "を使って、デフォルトのパラメータでリランキング戦略を適用した。RRFRankerをカスタマイズするには、Milvus Reranking Guideに従ってhybrid_rankerhybrid_ranker_params

それでは、サンプルクエリでRAGシステムをテストしてみよう:

# Query
query_engine = index.as_query_engine(
    vector_store_query_mode="hybrid", similarity_top_k=5
)
answer = query_engine.query("What did the author learn at Viaweb?")
print(textwrap.fill(str(answer), 100))
The author learned several important lessons at Viaweb. These included the importance of
understanding growth rate as the ultimate test of a startup, the impact of hiring too many people,
the challenges of being at the mercy of investors, and the relief experienced when Yahoo bought the
company. Additionally, the author learned about the significance of user feedback, the value of
building stores for users, and the realization that growth rate is crucial for the long-term success
of a startup.

このハイブリッド・アプローチは、セマンティック検索とキーワード・ベースの検索の両方を活用することで、RAGシステムにおいてより正確で文脈を考慮した応答を保証する。

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
フィードバック

このページは役に立ちましたか ?