Azure AI Search では、 インデックスの作成または更新 (REST API) を使用して、ベクターを検索インデックスに格納できます。 ベクター インデックスは、ベクター フィールド、非ベクトル フィールド、およびベクター構成セクションを持つインデックス スキーマによって定義されます。
ベクター インデックスを作成するときは、ベクター クエリのコーパスとして機能する 埋め込み空間 を暗黙的に作成します。 埋め込み空間は、同じ埋め込みモデルからの埋め込みによって設定されたすべてのベクター フィールドで構成されます。 クエリ時に、システムはベクター クエリをインデックス付きベクターと比較し、セマンティック類似性に基づいて結果を返します。
Azure AI Search でベクターのインデックスを作成するには、次の手順に従います。
この記事では、REST を使って説明します。 基本的なワークフローを理解したら、 azure-search-vector-samples リポジトリの Azure SDK コード サンプルに進みます。このリポジトリでは、テスト コードと運用コードでのベクターの使用に関するガイダンスが提供されます。
ヒント
Azure portal を使用して ベクター インデックスを作成 し、統合されたデータ チャンクとベクター化を試すこともできます。
前提条件
任意のリージョンおよび任意のレベルの Azure AI Search サービス 。 Azure AI スキルと ベクターライザーで統合ベクター化 を使用する予定の場合、Azure AI Search は、Azure AI Vision でホストされている埋め込みモデルと同じリージョンにある必要があります。
ソース ドキュメントには、インデックスにアップロードする ベクター埋め込み がある必要があります。 この手順では 、統合ベクター化 を使用することもできます。
ベクター フィールドにその制限を割り当てることができるように、埋め込みを作成するモデルの寸法制限を把握しておく必要があります。 text-embedding-ada-002 の場合、次元は 1536 で固定されます。 text-embedding-3-small または text-embedding-3-large の場合、寸法はそれぞれ 1 から 1536、1 から 3072 の範囲です。
使用する類似性メトリックを把握しておく必要があります。 Azure OpenAI にモデルを埋め込む場合は、
cosine
を使用して類似性が計算されます。インデックスを作成する方法 を知っている必要があります。 スキーマには、常にドキュメント キーのフィールド、検索またはフィルターのフィールド、およびインデックス作成とクエリ中に必要な動作のその他の構成が含まれます。
制限事項
2019 年 1 月より前に作成された一部の検索サービスでは、ベクター インデックスを作成できません。 これに該当する場合は、ベクトルを使用する新しいサービスを作成します。
インデックス作成のためのドキュメントを準備する
インデックスを作成する前に、ベクター データと非ベクトル データのフィールドを含むドキュメント ペイロードをアセンブルします。 ドキュメント構造は、インデックス スキーマのフィールド コレクションに準拠している必要があります。
ソース ドキュメントで次の内容が提供されていることを確認します。
コンテンツ | 説明 |
---|---|
一意識別子 | 各ドキュメントを一意に識別するフィールドまたはメタデータ プロパティ。 すべての検索インデックスにはドキュメント キーが必要です。 ドキュメント キーの要件を満たすには、ソース ドキュメントにインデックス内で一意に識別されるフィールドまたはプロパティが 1 つ必要です。 BLOBをインデックス化する場合、各blobを一意に識別するのがmetadata_storage_pathかもしれません。 データベースからインデックスを作成する場合は、主キーである可能性があります。 このソース フィールドは、Edm.String 型のインデックス フィールドにマップし、検索インデックスで key=true である必要があります。 |
非ベクター コンテンツ | 人間が判読できるコンテンツを他のフィールドに提供します。 人間が判読できるコンテンツは、クエリ応答と、同じ要求にフルテキスト検索またはセマンティック ランク付けを含む ハイブリッド クエリ に役立ちます。 チャット完了モデルを使用している場合、ChatGPT のようなほとんどのモデルでは人間が判読できるテキストが必要であり、未加工のベクターは入力として受け入れられません。 |
ベクター コンテンツ | クエリ時に使用する非ベクトル コンテンツのベクター化表現。 ベクトルは、埋め込みモデルによって生成される単精度浮動小数点数の配列です。 各ベクター フィールドには、モデルによって生成された配列が含まれています。 フィールドごとに 1 つの埋め込みがあり、フィールドは最上位のフィールド (入れ子になった型または複合型の一部ではありません) です。 単純な統合を行う場合は、 Azure OpenAI にモデルを埋め込む (テキスト ドキュメントの 場合は text-embedding-3 、イメージとマルチモーダル埋め込みの場合は Image Retrieval REST API など) をお勧めします。 インデクサーとスキルセットを使用できる場合は、インデックス作成中に画像とテキストをエンコードする 統合ベクター化を検討してください。 フィールド定義はベクトル フィールド用のものですが、入力されるソース データはテキストと画像のどちらでも構いません。これらはインデックス作成中にベクトル配列に変換されます。 |
検索インデックスには、サポートするすべてのクエリ シナリオのフィールドと内容が含まれている必要があります。 製品名、バージョン、メタデータ、または住所を検索またはフィルター処理するとします。 この場合、ベクター類似性検索は特に役に立ちません。 キーワード検索、geo 検索、または逐語的なコンテンツを反復処理するフィルターが適しています。 ベクター フィールドと非ベクトル フィールドの両方を含む検索インデックスは、クエリの構築と応答の構成に最大限の柔軟性を提供します。
ベクター フィールドと非ベクトル フィールドを含むドキュメント ペイロードの短い例については、この記事の 「ロード ベクター データ 」セクションを参照してください。
基本的なインデックスから始める
最小限のスキーマから開始することで、ベクター構成やベクターフィールドを追加する前に作業可能な定義を持てるようにします。 単純なインデックスは次の例のようになります。 インデックス スキーマの詳細については、「 検索インデックスの作成」を参照してください。
インデックスには、必須の名前、必須のドキュメント キー ("key": true
)、およびプレーン テキストで人間が判読できるコンテンツのフィールドがあることに注意してください。 ベクター化する予定のコンテンツの人間が判読できるバージョンを用意するのが一般的です。 たとえば、PDF ファイルのテキストのチャンクがある場合、インデックス スキーマにはプレーンテキスト チャンク用のフィールドと、ベクター化されたチャンク用の 2 番目のフィールドが必要です。
"name"
、"fields"
コレクション、および追加構成のためのその他のコンストラクトを含む基本的なインデックスを次に示します。
POST https://[servicename].search.windows.net/indexes?api-version=[api-version]
{
"name": "example-index",
"fields": [
{ "name": "documentId", "type": "Edm.String", "key": true, "retrievable": true, "searchable": true, "filterable": true },
{ "name": "myHumanReadableNameField", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": true, "facetable": false },
{ "name": "myHumanReadableContentField", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzer": "en.microsoft" },
],
"analyzers": [ ],
"scoringProfiles": [ ],
"suggesters": [ ],
"vectorSearch": [ ]
}
ベクトル検索構成を追加する
次に、スキーマに "vectorSearch"
構成を追加します。 ここで定義するプロファイルはベクター フィールドの定義の一部になるため、フィールド定義の前に構成を指定すると便利です。 スキーマでは、ベクター構成は通常、フィールド コレクションの後 ( "analyzers"
、 "scoringProfiles"
、 "suggesters"
の後など) に挿入されます。 ただし、順序は関係ありません。
ベクター構成には、次のものが含まれます。
vectorSearch.algorithms
は、インデックス作成中にベクター ノード間に "最も近い近隣" 情報を作成するために使用されます。vectorSearch.compressions
スカラー量子化またはバイナリ量子化、オーバーサンプリング、および元のベクトルを使用した再ランク付けの場合。vectorSearch.profiles
アルゴリズムと圧縮構成の複数の組み合わせを指定する場合。
2024-07-01 は一般提供されています。 次のベクター構成がサポートされています。
- 階層ナビゲーション可能スモールワールド (HNSW) アルゴリズム。
- 完全な K ニアレスト ネイバー (KNN) アルゴリズム。
- スカラー圧縮
- バイナリ圧縮。2024-07-01 でのみ、新しい Azure SDK パッケージで使用できます。
- オーバーサンプリング。
- 元のベクターを使用した再ランク付け。
フィールドで HNSW を選択した場合は、クエリ時に完全な KNN を選択できます。 ただし、その逆は機能しません。 インデックス作成のために包括的なデータを選択した場合、後で HNSW 検索を要求することはできません。これは、近似検索を有効にする追加のデータ構造が存在しないためです。
コンテンツをベクトル化するための戦略を必ず用意してください。 組み込みのエンコードには、垂直統合とクエリ時ベクトル化をお勧めします。
インデックスの 作成または更新 REST API を使用してインデックスを作成します。
埋め込み空間の作成に使用する検索アルゴリズムを指定する
vectorSearch
セクションをインデックスに追加します。"vectorSearch": { "compressions": [ { "name": "scalar-quantization", "kind": "scalarQuantization", "rerankWithOriginalVectors": true, "defaultOversampling": 10.0, "scalarQuantizationParameters": { "quantizedDataType": "int8" } }, { "name": "binary-quantization", "kind": "binaryQuantization", "rerankWithOriginalVectors": true, "defaultOversampling": 10.0 } ], "algorithms": [ { "name": "hnsw-1", "kind": "hnsw", "hnswParameters": { "m": 4, "efConstruction": 400, "efSearch": 500, "metric": "cosine" } }, { "name": "hnsw-2", "kind": "hnsw", "hnswParameters": { "m": 8, "efConstruction": 800, "efSearch": 800, "metric": "hamming" } }, { "name": "eknn", "kind": "exhaustiveKnn", "exhaustiveKnnParameters": { "metric": "euclidean" } } ], "profiles": [ { "name": "vector-profile-hnsw-scalar", "compression": "scalar-quantization", "algorithm": "hnsw-1" } ] }
重要なポイント:
圧縮、アルゴリズム、プロファイルの各構成の名前は、その種類ごとに、インデックス内で一意である必要があります。
vectorSearch.compressions
には、scalarQuantization
またはbinaryQuantization
を指定できます。 スカラー量子化では、浮動小数点値をより少ないビット数のデータ型に圧縮します。 二項量子化は、浮動小数点をバイナリ 1 ビット値に変換します。vectorSearch.compressions.rerankWithOriginalVectors
は元の非圧縮ベクトルを使用して類似性を再計算し、最初の検索クエリによって返される上位の結果を再ランク付けします。stored
が false の場合でも、非圧縮ベクトルが検索インデックスに存在します。 このプロパティは省略可能です。 既定値は True です。量子化による情報の減少を緩和するために、
vectorSearch.compressions.defaultOversampling
は潜在的な結果のより広範なセットを考慮します。 潜在的な結果の数式は、クエリ内のk
とオーバーサンプリング乗数で構成されます。 たとえば、クエリでk
5 を指定し、オーバーサンプリングが 20 の場合、クエリは実質的に、その目的のために元の非圧縮ベクターを使用して、再ランク付けに使用する 100 個のドキュメントを要求します。 上位k
の再ランキングされた結果のみが返されます。 このプロパティは省略可能です。 既定値は 4 です。vectorSearch.compressions.scalarQuantizationParameters.quantizedDataType
がint8
に設定されていること。 これは現時点でサポートされている唯一のプリミティブ データ型です。 このプロパティは省略可能です。 既定値はint8
です。vectorSearch.algorithms
はhnsw
またはexhaustiveKnn
です。 これらは、インデックス作成中にベクトル コンテンツを整理するために使用される近似最近傍 (ANN) アルゴリズムです。vectorSearch.algorithms.m
は、双方向リンク数です。 既定値は 4 です。 範囲は 4 ~ 10 です。 値を小さくすると、結果のノイズが少なくなります。vectorSearch.algorithms.efConstruction
は、インデックス作成中に使用される最も近い近隣ノードの数です。 既定値は 400 です。 範囲は 100 ~ 1,000 です。"vectorSearch.algorithms.efSearch
は、検索中に使用される最も近い近隣ノードの数です。 既定値は 500 です。 範囲は 100 ~ 1,000 です。vectorSearch.algorithms.metric
Azure OpenAI を使用している場合はcosine
する必要があります。それ以外の場合は、使用している埋め込みモデルに関連付けられている類似性メトリックを使用します。 サポートされている値は、cosine
、dotProduct
、euclidean
、およびhamming
です ( バイナリ データのインデックス作成に使用されます)。vectorSearch.profiles
によって、より豊富な定義に対応するための抽象化レイヤーが追加されます。 プロファイルはvectorSearch
で定義され、各ベクター フィールドの名前によって参照されます。 これは圧縮とアルゴリズム構成の組み合わせです。 このプロパティをベクター フィールドに割り当てて、フィールドのアルゴリズムと圧縮を決定します。
フィールド コレクションにベクトル フィールドを追加する
ベクター構成を作成したら、フィールド コレクションにベクター フィールドを追加できます。 フィールド コレクションには、ドキュメント キー、ベクター フィールド、および RAG ワークロードでのハイブリッド検索シナリオまたはチャット モデルの完了に必要なその他の非ベクトル フィールドのフィールドが含まれている必要があることを思い出してください。
ベクター フィールドは、 データ型、ベクターの出力に使用される埋め込みモデルに基づく dimensions
プロパティ、および前の手順で作成したベクター プロファイルによって特徴付けられます。
2024-07-01 は一般提供されています。
インデックスの 作成または更新 REST API を使用してインデックスを作成し、フィールド コレクションにベクター フィールドを追加します。
{ "name": "example-index", "fields": [ { "name": "contentVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "vector-profile-1" } ] }
次の属性を持つベクター フィールドを指定します。 生成された埋め込みをフィールドごとに 1 つ格納できます。 各ベクトル フィールドについて次を行います。
type
は ベクター データ型である必要があります。Collection(Edm.Single)
は、モデルの埋め込みに最も一般的です。dimensions
は、埋め込みモデルによって生成されるディメンションの数です。 text-embedding-ada-002 の場合は 1,536 に固定されます。 text-embedding-3 モデル シリーズの場合は、値の範囲があります。 垂直統合と埋め込みスキルを使用してベクトルを生成する場合は、このプロパティが埋め込みスキルで使用される値と同じディメンション値に設定されていることを確認してください。vectorSearchProfile
は、インデックス内の他の場所で定義されているプロファイルの名前です。searchable
は true にする必要があります。retrievable
には、true または false を指定できます。 True を指定すると、生のベクトル (そのうち 1,536 個) がプレーン テキストとして返され、ストレージ領域が消費されます。 ベクトル結果をダウンストリーム アプリに渡す場合は、true に設定します。stored
には、true または false を指定できます。 これは、取得に備えてベクトルの追加コピーを保存するかどうかを決定します。 詳細については、ベクトル サイズを小さくする方法に関する記事を参照してください。filterable
、facetable
、およびsortable
は false にする必要があります。
title
でfilterable
処理を呼び出す場合は、を true に設定したなど、フィルター可能な非ベクトル フィールドをコレクションに追加します。インデックスを作成するテキスト コンテンツの内容と構造を定義する他のフィールドを追加します。 最低でも、ドキュメント キーが必要です。
また、クエリまたはその応答に役立つフィールドも追加する必要があります。 次の例は、ベクトルと同等のタイトルとコンテンツ (
titleVector
とcontentVector
) のベクター フィールドを示しています。 また、検索結果の並べ替え、フィルター処理、読み取りに役立つ同等のテキスト コンテンツ (title
とcontent
) のフィールドも提供します。次の例は、フィールド コレクションを示しています。
PUT https://my-search-service.search.windows.net/indexes/my-index?api-version=2024-07-01&allowIndexDowntime=true Content-Type: application/json api-key: {{admin-api-key}} { "name": "{{index-name}}", "fields": [ { "name": "id", "type": "Edm.String", "key": true, "filterable": true }, { "name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "retrievable": true }, { "name": "titleVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "stored": true, "dimensions": 1536, "vectorSearchProfile": "vector-profile-1" }, { "name": "content", "type": "Edm.String", "searchable": true, "retrievable": true }, { "name": "contentVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "vector-profile-1" } ], "vectorSearch": { "algorithms": [ { "name": "hnsw-1", "kind": "hnsw", "hnswParameters": { "m": 4, "efConstruction": 400, "efSearch": 500, "metric": "cosine" } } ], "profiles": [ { "name": "vector-profile-1", "algorithm": "hnsw-1" } ] } }
インデックス作成のためベクトル データを読み込む
インデックス作成用に指定するコンテンツは、インデックス スキーマに準拠し、ドキュメント キーの一意の文字列値を含んでいる必要があります。 事前ベクトル化データは、非ベクトル コンテンツを含む他のフィールドと共存できる 1 つ以上のベクトル フィールドに読み込まれます。
データ インジェストでは、 プッシュまたはプルの手法を使用できます。
Documents - Index を使用して、ベクトル データと非ベクトル データをインデックスに読み込みます。 インデックス作成用のプッシュ API は、すべての安定バージョンとプレビュー バージョンで同じです。 ドキュメントを読み込むには、次のいずれかの API を使用します。
POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/index?api-version=2024-07-01
{
"value": [
{
"id": "1",
"title": "Azure App Service",
"content": "Azure App Service is a fully managed platform for building, deploying, and scaling web apps. You can host web apps, mobile app backends, and RESTful APIs. It supports a variety of programming languages and frameworks, such as .NET, Java, Node.js, Python, and PHP. The service offers built-in auto-scaling and load balancing capabilities. It also provides integration with other Azure services, such as Azure DevOps, GitHub, and Bitbucket.",
"category": "Web",
"titleVector": [
-0.02250031754374504,
. . .
],
"contentVector": [
-0.024740582332015038,
. . .
],
"@search.action": "upload"
},
{
"id": "2",
"title": "Azure Functions",
"content": "Azure Functions is a serverless compute service that enables you to run code on-demand without having to manage infrastructure. It allows you to build and deploy event-driven applications that automatically scale with your workload. Functions support various languages, including C#, F#, Node.js, Python, and Java. It offers a variety of triggers and bindings to integrate with other Azure services and external services. You only pay for the compute time you consume.",
"category": "Compute",
"titleVector": [
-0.020159931853413582,
. . .
],
"contentVector": [
-0.02780858241021633,
. . .
],
"@search.action": "upload"
}
. . .
]
}
インデックスにベクター コンテンツのクエリを実行する
検証目的で、Azure portal の検索エクスプローラーまたは REST API 呼び出しを使用してインデックスのクエリを実行できます。 Azure AI Search ではベクトルを人間が判読できるテキストに変換できないため、一致のエビデンスを提供する同じドキュメントからフィールドを返すようにしてください。 たとえば、ベクター クエリが titleVector
フィールドを対象とする場合は、検索結果の title
を選択できます。
フィールドは、結果に含める retrievable
として属性付けする必要があります。
[検索管理]>[インデックス] でインデックスを確認して、インデックス サイズの合計とベクトルのインデックス サイズを表示します。 正のベクトル インデックス サイズは、ベクトルが存在することを示します。
検索エクスプローラーを使用して、インデックスのクエリを実行します。 検索エクスプローラーには、クエリ ビュー (既定) と JSON ビューの 2 つのビューがあります。
[クエリ オプション]>[Hide vector values in search results] (検索結果でベクトル値を非表示する) を設定して、結果を読みやすくします。
ベクトル クエリに JSON ビューを使用します。 実行するベクター クエリの JSON 定義を貼り付けることができます。 インデックスに ベクター化代入がある場合は、組み込みのテキストからベクターへの変換、または画像からベクターへの変換を使用することもできます。 画像検索の詳細については、クイック スタート: 検索エクスプローラーで画像を検索する方法に関する記事を参照してください。
既定のクエリ ビューを使用して、インデックスにベクトルが含まれていることをすばやく確認します。 クエリ ビューはフルテキスト検索用です。 ベクトル クエリには使用できませんが、空の検索 (
search=*
) を送信してコンテンツを確認できます。 ベクトル フィールドを含むすべてのフィールドの内容が、プレーン テキストとして返されます。
詳細については、「 ベクター クエリの作成」を参照してください。
ベクター インデックスを更新する
ベクター インデックスを更新するには、スキーマを変更し、ドキュメントを再読み込みして新しいフィールドを設定します。 スキーマ更新の API には、インデックスの作成または更新 (REST)、Azure SDK for .NET の CreateOrUpdateIndex、Azure SDK for Python の create_or_update_index、その他の Azure SDK の同様のメソッドが含まれます。
インデックスの更新に関する標準的なガイダンスについては、「インデックスの 更新または再構築」を参照してください。
重要なポイントは次のとおりです。
多くの場合、既存のフィールドの更新と削除には、インデックスの削除と完全な再構築が必要です。
再構築を必要とせず、次の変更を行うことができます。
- Fields コレクションに新しいフィールドを追加します。
- 新しいベクター構成を追加します。新しいフィールドには割り当てられますが、既にベクター化されている既存のフィールドには割り当てません。
- 既存のフィールドの
retrievable
変更 (値は true または false)。 ベクトル フィールドは検索可能で取得可能である必要がありますが、削除と再構築が不可能な状況でベクトル フィールドへのアクセスを無効にする場合は、retrievable を false に設定できます。
次のステップ
次の手順として、 ベクター クエリを作成することをお勧めします。
azure-search-vector-samples リポジトリのコード サンプルでは、スキーマ定義、ベクトル化、インデックス作成、クエリを含むエンド ツー エンドのワークフローが示されています。
Python、C#、JavaScript 用のデモ コードがあります。