Azure AI 検索内のベクター インデックス

Azure AI 検索は、Azure ポータルREST APIおよびAzure SDKから使用できます。 また、Foundry IQ は、エンタープライズ コンテンツを、Microsoft Foundry ポータルのエージェントの再利用可能なアクセス許可に対応したナレッジ ベースに変換するマネージド ナレッジ レイヤーです。

ベクターは、テキスト、画像、およびその他のコンテンツを数学的に表す高次元埋め込みです。 Azure AI 検索はフィールド レベルでベクトルを格納し、ベクターコンテンツと非ベクトルコンテンツを同じsearch index内に共存させることができます。

ベクター フィールドとベクター構成を定義すると、検索インデックスがベクター インデックス になります。 ベクター フィールドを設定するには、事前計算された埋め込みをそれらにプッシュするか、インデックス作成中に埋め込みを生成する組み込みのAzure AI 検索機能である integrated vectorization を使用します。

クエリ時に、インデックス内のベクター フィールドによって類似性検索が有効になります。この検索では、ベクトルがベクター クエリに最も似ているドキュメントがシステムによって取得されます。 ベクトル検索を使用して類似性マッチングを単独で行うか、類似度とキーワードマッチングを組み合わせたハイブリッド検索を使用できます。

この記事では、ベクター インデックスを作成および管理するための主な概念について説明します。

  • ベクトル取得パターン
  • コンテンツ (ベクター フィールドと構成)
  • 物理データ構造
  • 基本操作

ヒント

すぐに始めたいですか? ベクター インデックスの作成を参照してください。

ベクトル取得パターン

Azure AI 検索では、ベクター取得用に次の 2 つのパターンがサポートされています。

  • クラシック検索。 このパターンでは、検索バー、クエリ入力、レンダリングされた結果が使用されます。 クエリの実行中に、検索エンジンまたはアプリケーション コードによってユーザー入力がベクター化されます。 検索エンジンは、インデックス内のベクター フィールドに対してベクター検索を実行し、クライアント アプリでレンダリングする応答を作成します。

    Azure AI 検索では、結果はフラット化された行セットとして返され、応答に含めるフィールドを選択できます。 検索エンジンはベクターで一致しますが、インデックスには、検索結果を設定するために人間が判読できる非ベクトルコンテンツが必要です。 クラシック検索では、 ベクター クエリハイブリッド クエリの両方がサポートされます。

  • 生成検索。 言語モデルでは、Azure AI 検索のデータを使用してユーザー クエリに応答します。 オーケストレーション レイヤーは通常、プロンプトを調整し、コンテキストを維持し、GPT などのチャット モデルに検索結果をフィードします。 このパターンは、「取得拡張生成 (RAG)」アーキテクチャに基づいており、検索インデックスによって基礎データが提供されます。

ベクター インデックスのスキーマ

ベクター インデックスのスキーマには、次のものが必要です。

  • 名前
  • キー フィールド (文字列)
  • 1 つ以上のベクター フィールド
  • ベクター構成

非ベクトル フィールドは必須ではありませんが、ハイブリッド クエリや、言語モデルを経由しない逐語的なコンテンツを返す場合に含めてお勧めします。 詳細については、「ベクトル インデックスを作成する」を参照してください。

インデックス スキーマには 、ベクター取得パターンが反映されている必要があります。 このセクションでは、主にクラシック検索のフィールド構成について説明しますが、生成検索のスキーマ ガイダンスも提供します。

基本的なベクトル フィールドの構成

ベクター フィールドには、一意のデータ型とプロパティがあります。 フィールド コレクション内のベクトル フィールドは次のようになります。

{
    "name": "content_vector",
    "type": "Collection(Edm.Single)",
    "searchable": true,
    "retrievable": true,
    "dimensions": 1536,
    "vectorSearchProfile": "my-vector-profile"
}

ベクター フィールドでは 、特定のデータ型 のみがサポートされています。 最も一般的な型は Collection(Edm.Single)ですが、狭い型を使用するとストレージを節約できます。

ベクター フィールドは検索可能で取得可能である必要がありますが、フィルター可能、ファセット可能、または並べ替え可能にすることはできません。 また、アナライザー、ノーマライザー、またはシノニム マップの割り当てを持つことはできません。

dimensions プロパティは、埋め込みモデルによって生成される埋め込みの数に設定する必要があります。 たとえば、text-embedding-ada-002 では、テキストのチャンクごとに 1,536 個の埋め込みが生成されます。

ベクター フィールドは、ベクトル 検索プロファイルで指定されたアルゴリズムを使用してインデックスが作成されます。これはインデックス内の別の場所で定義され、この例では示されていません。 詳細については、「 ベクター検索構成の追加」を参照してください。

基本的なベクトル ワークロードのフィールド コレクション

ベクター インデックスには、単なるベクター フィールド以上のものが必要です。 たとえば、すべてのインデックスには、次の例で id キー フィールドが必要です。

"name": "example-basic-vector-idx",
"fields": [
  { "name": "id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "key": true },
  { "name": "content_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": null },
  { "name": "content", "type": "Edm.String", "searchable": true, "retrievable": true, "analyzer": null },
  { "name": "metadata", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true }
]

他のフィールド ( content フィールドなど) は、人間が判読できる content_vector フィールドと同等のフィールドを提供します。 応答の作成専用の言語モデルを使用している場合は、非ベクトル コンテンツ フィールドを省略できますが、クライアント アプリに検索結果を直接プッシュするソリューションには非ベクトル コンテンツが必要です。

メタデータ フィールドは、特にソース ドキュメントに関する配信元情報が含まれている場合に、フィルターに役立ちます。 ベクター フィールドで直接フィルター処理することはできませんが、ベクター クエリの実行前または実行後にフィルター処理するプリフィルター、ポストフィルター、または厳密なポストフィルター (プレビュー) の各モードを設定できます。

インポート ウィザードによって生成されるスキーマ

評価と概念実証のテストには 、データのインポート ウィザード をお勧めします。 ウィザードによって、このセクションのスキーマ例が生成されます。

ウィザードはコンテンツをより小さな検索ドキュメントにチャンクします。これは、言語モデルを使用して応答を作成する RAG アプリにメリットがあります。 チャンクは、言語モデルの入力制限とセマンティック ランカーのトークン制限内に留まるのに役立ちます。 また、複数の親ドキュメントからプルされたチャンクに対してクエリを照合することで、類似性検索の精度も向上します。 詳細については、「ベクトル検索ソリューション用に大きなドキュメントをチャンクに分割する」を参照してください。

次の例の検索ドキュメントごとに、チャンク ID、親 ID、チャンク、タイトル、ベクター フィールドが 1 つあります。 ウィザード:

  • base64 でエンコードされた BLOB メタデータ (パス) を chunk_id フィールドと parent_id フィールドに設定します。

  • BLOB のコンテンツと BLOB 名から、それぞれ chunk フィールドと title フィールドを抽出します。

  • vector フィールドをベクター化するために指定したAzure OpenAI 埋め込みモデルを呼び出して、chunk フィールドを作成します。 このプロセス中にベクター フィールドのみが完全に生成されます。

"name": "example-index-from-import-wizard",
"fields": [
  { "name": "chunk_id", "type": "Edm.String", "key": true, "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true, "analyzer": "keyword"},
  { "name": "parent_id", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "sortable": true},
  { "name": "chunk", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true, "sortable": false},
  { "name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "sortable": false},
  { "name": "vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "vector-1707768500058-profile"}
]

RAG アプリとチャット スタイル アプリ用のベクター ストレージを設計する場合は、次の 2 つのインデックスを作成できます。

  • 1 つは、インデックスを作成してベクター化した静的コンテンツ用です。
  • 1 つは、プロンプト フローで使用できる会話用です。

説明のために、このセクションでは、chat-with-your-data-solution-accelerator を使用して、chat-index インデックスと conversations インデックスを作成します。

アクセラレータによって作成されたインデックスのスクリーンショット。

chat-indexからの次のフィールドは、生成検索エクスペリエンスをサポートします。

"name": "example-index-from-accelerator",
"fields": [
  { "name": "id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true },
  { "name": "content", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
  { "name": "content_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "my-vector-profile"},
  { "name": "metadata", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
  { "name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "facetable": true },
  { "name": "source", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true  },
  { "name": "chunk", "type": "Edm.Int32", "searchable": false, "filterable": true, "retrievable": true },
  { "name": "offset", "type": "Edm.Int32", "searchable": false, "filterable": true, "retrievable": true }
]

conversations からは、オーケストレーションとチャット履歴をサポートする次のフィールドが利用できます。

"fields": [
    { "name": "id", "type": "Edm.String", "key": true, "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": false },
    { "name": "conversation_id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "content", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
    { "name": "content_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "default-profile" },
    { "name": "metadata", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
    { "name": "type", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "user_id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "sources", "type": "Collection(Edm.String)", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "created_at", "type": "Edm.DateTimeOffset", "searchable": false, "filterable": true, "retrievable": true },
    { "name": "updated_at", "type": "Edm.DateTimeOffset", "searchable": false, "filterable": true, "retrievable": true }
]

次のスクリーンショットは、conversationsでのの検索結果を示しています。

RAG アプリ用に設計されたインデックスの結果を含む Search エクスプローラーのスクリーンショット。

この例では、検索が修飾されていないため、検索スコアは 1.00 です。 いくつかのフィールドでは、オーケストレーションフローとプロンプト フローがサポートされています。

  • conversation_id は、各チャット セッションを識別します。
  • type は、コンテンツがユーザーとアシスタントのどちらからのものであるかを示します。
  • created_atupdated_at はチャットを履歴から削除します。

物理的な構造とサイズ

Azure AI 検索では、インデックスの物理的な構造は、主に内部実装です。 スキーマへのアクセス、コンテンツの読み込みとクエリ、サイズの監視、容量の管理を行うことができます。 ただし、Microsoftは、検索サービスに格納されているインフラストラクチャと物理データ構造を管理します。

インデックスのサイズと物質は、次によって決定されます。

  • ドキュメントの数量と構成。

  • 個々のフィールドの属性。 たとえば、フィルター処理可能なフィールドにはより多くのストレージが必要です。

  • 内部ナビゲーション構造の作成方法を指定するベクター構成を含むインデックス構成。 類似性検索には HNSW または完全な KNN を選択できます。

Azure AI 検索はベクター ストレージに制限を課し、すべてのワークロードに対してバランスのとれた安定したシステムを維持するのに役立ちます。 制限を維持するために、ベクターの使用状況は追跡され、Azure ポータルで個別に報告され、サービスとインデックスの統計情報を使用してプログラムによって報告されます。

次に示すのは、1 つのパーティションと 1 つのレプリカで構成された S1 サービスのスクリーンショットです。 このサービスには 24 個の小さなインデックスがあり、それぞれが 1,536 個の埋め込みで構成される 1 つのベクター フィールドの平均を持っています。 2 番目のタイルが示しているのは、ベクトル インデックスのクォータと使用状況です。 ベクター インデックスは各ベクター フィールドに対して作成された内部データ構造であるため、ベクター インデックスのストレージは常に、インデックスによって使用されるストレージ全体の一部です。 非ベクトル フィールドとその他のデータ構造では、残りの部分が使用されます。

ストレージ、ベクトル インデックス、インデックス数を示す使用状況タイルのスクリーンショット。

ベクター インデックスの制限と見積もりについては 別の記事で説明しますが、2 つの重要な点は、最大ストレージは検索サービスの作成日と価格レベルによって異なるということです。 同じレベルでも新しいサービスの方が、かなり多いベクトル インデックスの容量を持ちます。 これらの理由から、次のことが必要です。

基本的な操作と相互作用

このセクションでは、単一のインデックスへの接続やセキュリティ保護など、ベクター ランタイム操作について説明します。

インデックスを移動またはコピーするためのポータルや API のサポートはありません。 通常は、アプリケーションのデプロイを (同じインデックス名を使用して) 別の検索サービスをポイントするか、名前を変更して現在の検索サービスにコピーを作成してからビルドします。

インデックスの分離性

Azure AI 検索では、一度に 1 つのインデックスを操作します。 すべてのインデックス関連の操作は、1 つのインデックスを対象とします。 関連するインデックスや、インデックス作成またはクエリのための独立したインデックスの結合の概念はありません。

継続的に使用可能

インデックスは、最初のドキュメントのインデックスが作成されるとすぐにクエリで使用できますが、すべてのドキュメントにインデックスが作成されるまでは完全には動作しません。 内部的には、インデックスは複数のパーティションにわたって分散され、レプリカ上で実行されます。 物理インデックスは内部で管理されます。 論理インデックスを管理します。

インデックスは継続的に使用でき、一時停止したり、オフラインにしたりすることはできません。 継続的な操作用に設計されているため、コンテンツの更新とインデックス自体への追加はリアルタイムで行われます。 要求がドキュメントの更新と一致する場合、クエリは一時的に不完全な結果を返す可能性があります。

クエリの継続性は、更新や削除などのドキュメント操作や、インデックスの既存の構造や整合性に影響しない変更 (新しいフィールドの追加など) に対して存在します。 既存のフィールドの変更などの構造の更新は、通常、開発環境でドロップアンドリビルド ワークフローを使用するか、運用サービスでインデックスの新しいバージョンを作成することによって管理されます。

インデックスの再構築を回避するために、以前のバージョンと共存する新しいフィールドを作成することで、小さな変更を行う一部のお客様はフィールドを "バージョン" にします。 時間の経過と同時に、古いフィールドと古いカスタム アナライザー定義 (特にレプリケートにコストがかかる運用インデックス) によって、孤立したコンテンツが発生します。 インデックスのライフサイクル管理の一環として、インデックスの計画的な更新中にこれらの問題に対処できます。

エンドポイント接続

ベクトルのインデックス作成とクエリ要求はすべて、インデックスを対象とします。 エンドポイントは、通常、次のいずれかになります。

エンドポイント 接続とアクセスの制御
<your-service>.search.windows.net/indexes インデックスのコレクションを対象とします。 インデックスを作成、一覧表示、または削除するときに使用します。 これらの操作には管理者権限が必要であり、管理者 API キー または 検索共同作成者ロールを通じて利用できます。
<your-service>.search.windows.net/indexes/<your-index>/docs 1 つのインデックスのドキュメント コレクションを対象とします。 インデックスまたはデータ更新に対してクエリを実行するときに使用します。 クエリの場合、読み取り権限は十分であり、クエリ API キーまたはデータ閲覧者ロールを使用して使用できます。 データ更新の場合は、管理者権限が必要です。
  1. アクセス許可または API アクセス キーがあることを確認します。 既存のインデックスに対してクエリを実行する場合を除き、検索サービスのコンテンツを管理および表示するには、管理者権限または共同作成者ロールの割り当てが必要です。

  2. Azure ポータル で開始します。 検索サービスを作成したユーザーは、アクセス 制御 (IAM) ページで他のユーザーにアクセス権を付与するなど、検索サービスを表示および管理できます。

  3. プログラムによるアクセスのために他のクライアントに移動します。 最初の手順では、Quickstart: RESTおよび azure-search-vector-samples リポジトリを使用することをお勧めします。

ベクトル ストアを管理する

Azureは、診断ログとアラートを含む監視プラットフォームを提供します。 推奨事項は次のとおりです。

ベクトル データへのアクセスをセキュリティで保護する

Azure AI 検索では、データ暗号化、インターネットなしのシナリオでのプライベート接続、およびMicrosoft Entra IDを介したセキュリティで保護されたアクセスのためのロールの割り当てを実装します。 エンタープライズ セキュリティ機能の詳細については、「 データ、プライバシー、および組み込みの保護」を参照してください。