LLMに知識を与える手法として、検索システムを使用したRAGが主流になっています。
Azureにおいては、Azure OpenAI ServiceのLLMとAzure AI Searchの検索システムを利用してRAGを実装することが可能です。
本記事では、RAGの実装の基盤となる、Azure AI Searchのインデックス作成の方法をまとめます。
インデックス
詳しくは、Micorosoft社のドキュメントをご覧いただければと思いますが、リンク先から引用しながら、インデックスについて簡単にまとめてみます。
Azure AI Searchの「検索インデックス」は、検索可能なコンテンツを指します。これは、検索エンジンでインデックス作成、全文検索、ベクトル検索、ハイブリッド検索、フィルターされたクエリに使用できます。
インデックスは、スキーマによって定義され、検索サービスに保存されます。このスキーマは、検索ドキュメントが格納されるインデックスの構造を決定します。
概念的には、ドキュメントはインデックス内で検索可能なデータの1つの単位です。例えば、小売業者には製品ごとのドキュメントがあり、ニュース組織には記事ごとのドキュメントがある場合、旅行サイトにはホテルと目的地ごとのドキュメントがある場合があります。
インデックスには、ベクトル検索のためのベクトル化されたドキュメントを格納することができます。
また、文書が長い場合、分割してドキュメントとして格納することもできます。
検索サービスの作成
まず、Azure AI Searchで検索サービスを作成することから始まります。
本記事では例として、商品についてのドキュメントを格納するインデックスを作成してみます。
Azureポータルから、検索ウィンドウで検索するなどして、AI Searchを開きます。
左上あたりの「作成」もしくは中央の「Search Serviceの作成」をクリックします。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-1024x429.png)
以下のとおり設定して、「確認および作成」をクリックします。
サブスクリプション、リソースグループはアカウントにあわせて設定し、サービス名と場所を今回のシステムに適した名称・設定にします。価格レベルは、Free(無料)で作成します。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-5-1024x781.png)
検証が完了したら「作成」ボタンをクリックします。
作成が完了すると以下のようにメッセージが表示されます。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-6-1024x554.png)
Pythonを用いたインデックス作成
アクセス情報の確認
ローカルのPythonプログラムから検索サービスにアクセスするためのエンドポイントとアクセスキーを確認します。
エンドポイント
デプロイ完了画面の「リソースに移動」をクリックすると、以下のような表示になります。AI Searchのトップ画面の一覧から作成した検索サービスを選択することも可能です。
メニューの「概要」をクリックすると、エンドポイントURLが表示されます。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-9-1024x513.png)
アクセスキー
メニューの「キー」をクリックすると、APIキーが表示されます。プライマリ管理者キーでアクセス可能です。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-10-1024x749.png)
Pythonによるインデックス作成
必要なライブラリをインストールします。
pip install python-dotenv
pip install azure-search-documents==11.4.0b8
インデックス作成を行うPythonのサンプルコードです。
import os
from dotenv import load_dotenv
from azure.core.credentials import AzureKeyCredential
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
CorsOptions,
SearchIndex,
SearchField,
SearchFieldDataType,
SimpleField,
SearchableField,
VectorSearch,
SemanticConfiguration,
SemanticField,
PrioritizedFields,
SemanticSettings,
HnswVectorSearchAlgorithmConfiguration,
HnswParameters
)
load_dotenv()
# AI Search Endpoint & Key
endpoint = os.getenv('AI_SEARCH_ENDPOINT')
key = os.getenv('AI_SEARCH_KEY')
# AI Search Client
client = SearchIndexClient(endpoint, AzureKeyCredential(key))
name = "index-product"
fields = [
SimpleField(
name="id",
type=SearchFieldDataType.String,
key=True
),
SimpleField(
name="price",
type=SearchFieldDataType.Double,
filterable=True,
),
SearchableField(
name="description",
type=SearchFieldDataType.String,
searchable=True,
filterable=True,
analyzer_name='ja.microsoft',
),
SearchField(
name="description_vector",
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
searchable=True,
vector_search_dimensions=1536,
vector_search_configuration='vectorConfig',
),
]
vector_search = VectorSearch(
algorithm_configurations=[
HnswVectorSearchAlgorithmConfiguration(
name="vectorConfig",
kind="hnsw",
parameters={
"m": 4,
"efConstruction": 400,
"efSearch": 500,
"metric": "cosine"
}
)
]
)
semantic_config = SemanticConfiguration(
name="semantic-config",
prioritized_fields=PrioritizedFields(
prioritized_content_fields=[SemanticField(field_name="description")]
)
)
semantic_settings = SemanticSettings(configurations=[semantic_config])
cors_options = CorsOptions(allowed_origins=["*"], max_age_in_seconds=60)
scoring_profiles = []
index = SearchIndex(
name=name,
fields=fields,
semantic_settings=semantic_settings,
scoring_profiles=scoring_profiles,
vector_search=vector_search,
cors_options=cors_options
)
result = client.create_index(index)
print(result)
コード解説
インポート
import os
from dotenv import load_dotenv
from azure.core.credentials import AzureKeyCredential
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
CorsOptions,
SearchIndex,
SearchField,
SearchFieldDataType,
SimpleField,
SearchableField,
VectorSearch,
SemanticConfiguration,
SemanticField,
PrioritizedFields,
SemanticSettings,
HnswVectorSearchAlgorithmConfiguration,
HnswParameters
)
必要なライブラリやモジュールをインポートしています。dotenv
は環境変数の読み込み、azure.search.documents.indexes
関連のインポートは、Azure AI Searchのインデックス作成に必要です。
環境変数の読み込み
load_dotenv(override=True)
.env
ファイルから環境変数を読み込みます。
Azure Search クライアントの設定
endpoint = os.getenv('AI_SEARCH_ENDPOINT')
key = os.getenv('AI_SEARCH_KEY')
環境変数に設定しているAzure Searchのエンドポイントとアクセスキーを取得し、SearchIndexClient
を作成します。
インデックス名の設定
name = “index-product”
インデックスフィールドの定義
client = SearchIndexClient(endpoint, AzureKeyCredential(key))
name = "index-product"
fields = [
SimpleField(
name="id",
type=SearchFieldDataType.String,
key=True
),
SimpleField(
name="price",
type=SearchFieldDataType.Double,
filterable=True,
),
SearchableField(
name="description",
type=SearchFieldDataType.String,
searchable=True,
filterable=True,
analyzer_name='ja.microsoft',
),
SearchField(
name="description_vector",
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
searchable=True,
vector_search_dimensions=1536,
vector_search_configuration='vectorConfig',
),
]
インデックスに含まれるフィールドを定義します。
id
: 主キーとなる文字列フィールド。
price
: フィルタリング可能な数値フィールド。
description
: 検索可能でフィルタリング可能なテキストフィールド(日本語解析を指定)。
description_vector
: ベクター検索用のフィールド。
ベクター検索の設定
vector_search = VectorSearch(
algorithm_configurations=[
HnswVectorSearchAlgorithmConfiguration(
name="vectorConfig",
kind="hnsw",
parameters={
"m": 4,
"efConstruction": 400,
"efSearch": 500,
"metric": "cosine"
}
)
]
)
HNSWアルゴリズムを用いたベクター検索の設定を行います。
セマンティック設定
semantic_config = SemanticConfiguration(
name="semantic-config",
prioritized_fields=PrioritizedFields(
prioritized_content_fields=[SemanticField(field_name="description")]
)
)
semantic_settings = SemanticSettings(configurations=[semantic_config])
セマンティック検索の設定を行います。
CORS設定
cors_options = CorsOptions(allowed_origins=["*"], max_age_in_seconds=60)
CORS(Cross-Origin Resource Sharing)の設定を行います。
スコアリングプロファイルの設定
scoring_profiles = []
インデックスの作成
index = SearchIndex(
name=name,
fields=fields,
semantic_settings=semantic_settings,
scoring_profiles=scoring_profiles,
vector_search=vector_search,
cors_options=cors_options
)
result = client.create_index(index)
上記で定義した設定を用いてインデックスを作成します。
実行結果
サンプルコードを実行すると、AI Searchのメニュー「インデックス」に作成したインデックスが表示されます。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-11-1024x390.png)
「index-product」をクリックして、「フィールド」をクリックすると設定したフィールド名が表示されていることが分かります。
![](https://ninthcode.net/wp-content/uploads/2024/07/image-12-1024x449.png)