ベクター ストアを作成する

Azure AI 検索において、"ベクトル ストア" には、ベクトル フィールドと非ベクトル フィールドを定義するインデックス スキーマ、埋め込み空間を作成するアルゴリズムのベクトル構成、およびクエリ要求で使用されるベクトル フィールド定義の設定が含まれています。 Create Index API によってベクトル ストアが作成されます。

次の手順に従ってベクトル データにインデックスを作成します。

  • インデックス作成と検索のアルゴリズムを指定する、1 つ以上のベクトル構成を使用するスキーマを定義します
  • 1 つ以上のベクトル フィールドを追加します
  • 事前にベクトル化されたデータを別のステップとして読み込むか、インデックス作成中のデータのチャンク分割とエンコードに垂直統合 (プレビュー) を使用します。

この記事は、一般提供されている、非プレビュー バージョンのベクトル検索に適用されます。ここでは、アプリケーション コードでチャンク分割およびエンコードのために外部リソースが呼び出されることを想定しています。

Note

2023-07-01-preview からの移行ガイダンスをお探しですか? REST API のアップグレードに関するページを参照してください。

前提条件

  • 任意のリージョンおよび任意のレベルの Azure AI Search。 既存のサービスのほとんどではベクトル検索がサポートされています。 2019 年 1 月より前に作成されたサービスでは、ごく一部がベクトル検索をサポートできません。 ベクトル フィールドを含むインデックスの作成または更新に失敗した場合、これはインジケーターです。 このような場合は、新しいサービスを作成する必要があります。

  • ソース ドキュメント内の既存のベクトル埋め込み。 Azure AI Search では、Azure SDK と REST API の一般提供バージョンにおいてベクトルは生成されません。 Azure OpenAI 埋め込みモデルをお勧めしますが、ベクター化には任意のモデルを使用できます。 詳細については、「埋め込みの生成」を参照してください。

  • 埋め込みの作成に使用されるモデルの次元の制限と、類似性の計算方法を理解している必要があります。 Azure OpenAI では、text-embedding-ada-002 の場合、数値ベクトルの長さは 1536 です。 類似性は、cosine を使用して計算されます。 有効値は 2 から 3072 次元です。

  • インデックスの作成に慣れている必要があります。 スキーマには、ドキュメント キーのフィールド、検索またはフィルター処理するその他のフィールド、およびインデックス作成やクエリの実行中に必要な動作に関するその他の構成が含まれている必要があります。

インデックス作成のためのドキュメントを準備する

インデックスを付ける前に、ベクトルおよび非ベクトル データのフィールドを含むドキュメント ペイロードをアセンブルします。 ドキュメント構造は、インデックス スキーマに準拠している必要があります。

ドキュメントが次のようになっていることを確認します。

  1. 各ドキュメントを一意に識別するフィールドまたはメタデータ プロパティを指定します。 すべての検索インデックスにはドキュメント キーが必要です。 ドキュメント キーの要件を満たすには、ソース ドキュメントに、インデックス内で一意に識別できる 1 つのフィールドまたはプロパティが必要です。 このソース フィールドは、Edm.String 型のインデックス フィールドにマップし、検索インデックスで key=true である必要があります。

  2. ソース フィールドにベクトル データ (単精度浮動小数点数の配列) を指定します。

    ベクトル フィールドには、モデルを埋め込むことで生成される数値データが含まれます。フィールドごとに 1 つの埋め込みがあります。 テキスト ドキュメント用の text-embedding-ada-002 やイメージ用の Image Retrieval REST API など、Azure OpenAI の埋め込みモデルをお勧めします。 インデックスの最上位ベクトル フィールドのみがサポートされており、ベクトル サブフィールドは現在サポートされていません。

  3. クエリ応答、および同じ要求にフルテキスト検索またはセマンティック ランク付けを含むハイブリッド クエリ シナリオ用に、人間が判読できる英数字の内容を他のフィールドに提供します。

検索インデックスには、サポートするすべてのクエリ シナリオのフィールドと内容が含まれている必要があります。 製品名、バージョン、メタデータ、または住所を検索またはフィルター処理するとします。 この場合、類似性検索は特に役立つわけではありません。 キーワード検索、地域検索、またはフィルターの方が適しています。 ベクトルおよび非ベクトル データの包括的なフィールド コレクションを含む検索インデックスでは、クエリの構築と応答の構成に最大限の柔軟性を提供します。

ベクトルおよび非ベクトル フィールドを含むドキュメント ペイロードの簡単な例が、この記事のベクトル データの読み込みに関するセクションにあります。

ベクトル検索構成を追加する

ベクトル構成では、インデックス作成中に使用されるベクトル検索アルゴリズムおよびパラメーターを指定して、ベクトル ノード間の "最近傍" の情報を作成します。

  • 階層ナビゲーション可能な小さい世界 (HNSW)
  • 完全な KNN

フィールドで HNSW を選択すると、クエリ時に完全な KNN を選択できます。 しかし、逆の方向ではうまくいきません。完全な検索を選択すると、後で HNSW 検索を要求することはできません。これは、近似検索を有効にする追加のデータ構造が存在しないため’です。

preview-to-stable バージョンの移行ガイダンスをお探しですか? 手順については、REST API のアップグレードに関するページを参照してください。

REST API バージョン 2023-11-01 では、次のベクトル構成がサポートされます。

  • インデックス作成とスコア付けのためのパラメーターを伴う vectorSearch アルゴリズム、hnsw および exhaustiveKnn ニアレスト ネイバー。
  • アルゴリズム構成の複数の組み合わせ用の vectorProfiles

コンテンツをベクトル化するための戦略を必ず用意してください。 安定バージョンでは、組み込みの埋め込み用の vectorizer は提供されません。

  1. インデックスの作成または更新 API を使用してインデックスを作成します。

  2. 埋め込み空間の作成に使用する検索アルゴリズムを指定する vectorSearch セクションをインデックスに追加します。

     "vectorSearch": {
         "algorithms": [
             {
                 "name": "my-hnsw-config-1",
                 "kind": "hnsw",
                 "hnswParameters": {
                     "m": 4,
                     "efConstruction": 400,
                     "efSearch": 500,
                     "metric": "cosine"
                 }
             },
             {
                 "name": "my-hnsw-config-2",
                 "kind": "hnsw",
                 "hnswParameters": {
                     "m": 8,
                     "efConstruction": 800,
                     "efSearch": 800,
                     "metric": "cosine"
                 }
             },
             {
                 "name": "my-eknn-config",
                 "kind": "exhaustiveKnn",
                 "exhaustiveKnnParameters": {
                     "metric": "cosine"
                 }
             }
    
         ],
         "profiles": [
           {
             "name": "my-default-vector-profile",
             "algorithm": "my-hnsw-config-2"
           }
         ]
     }
    

    重要なポイント:

    • 構成オプションの名前。 名前はインデックス内で一意でなければなりません。
    • profiles によって、より豊富な定義に対応するための抽象化レイヤーが追加されます。 プロファイルは vectorSearch で定義され、その後、各ベクトル フィールドで名前によって参照されます。
    • "hnsw""exhaustiveKnn" は、インデックス作成中にベクトル コンテンツを整理するために使用される近似最近傍 (ANN) アルゴリズムです。
    • "m" (双方向リンク数) の既定値は 4 です。 範囲は 4 ~ 10 です。 値を小さくすると、結果のノイズが少なくなります。
    • "efConstruction" の既定値は 400 です。 範囲は 100 ~ 1,000 です。 インデックス作成中に使用される最も近い近隣ノードの数です。
    • "efSearch" の既定値は 500 です。 範囲は 100 ~ 1,000 です。 検索中に使用される最も近い近隣ノードの数です。
    • Azure OpenAI を使用している場合、"metric" は "cosine" にする必要があります。それ以外の場合は、使用している埋め込みモデルに関連付けられている類似性メトリックを使用します。 サポートされる値は、cosinedotProducteuclidean です。

フィールド コレクションにベクトル フィールドを追加する

フィールド コレクションには、ドキュメント キーのフィールド、ベクトル フィールド、およびハイブリッド検索シナリオに必要なその他のフィールドを含める必要があります。

ベクトル フィールドは、Collection(Edm.Single) 型で単精度浮動小数点値です。 この型のフィールドにも dimensions プロパティがあり、ベクトル構成を指定します。

一般提供の機能のみが必要な場合は、このバージョンを使用します。

  1. インデックスの作成または更新を使用してインデックスを作成します。

  2. 次の属性を含むベクトル フィールドを定義します。 生成された埋め込みをフィールドごとに 1 つ格納できます。 各ベクター フィールドについて次を行います。

    • type は、Collection(Edm.Single) である必要があります。
    • dimensions は、埋め込みモデルによって生成されるディメンションの数です。 text-embedding-ada-002 の場合は、1,536 個です。
    • vectorSearchProfile は、インデックス内の他の場所で定義されているプロファイルの名前です。
    • searchable は true にする必要があります。
    • retrievable には、true または false を指定できます。 True の場合、生のベクトル (そのうちの 1,536 個) がプレーンテキストとして返され、ストレージ領域が消費されます。 ベクトル結果をダウンストリーム アプリに渡す場合は、true に設定します。
    • filterablefacetablesortable は、false にする必要があります。
  3. ベクトル クエリ事前フィルター処理または事後フィルター処理を呼び出す場合は、filterable を true に設定した "title" など、フィルターを適用できる非ベクトル フィールドをコレクションに追加します。

  4. インデックスを作成するテキスト コンテンツの内容と構造を定義する他のフィールドを追加します。 最低でも、ドキュメント キーが必要です。

    また、クエリまたはその応答に役立つフィールドも追加する必要があります。 次の例は、ベクトルと同等のタイトルとコンテンツ ("titleVector"、"contentVector") のベクトル フィールドを示しています。 また、検索結果の並べ替え、フィルター処理、読み取りに役立つ同等のテキスト コンテンツ ("title"、"content") のフィールドも提供します。

    次の例は、フィールド コレクションを示しています。

    PUT https://my-search-service.search.windows.net/indexes/my-index?api-version=2023-11-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,
                "dimensions": 1536,
                "vectorSearchProfile": "my-default-vector-profile"
            },
            {
                "name": "content",
                "type": "Edm.String",
                "searchable": true,
                "retrievable": true
            },
            {
                "name": "contentVector",
                "type": "Collection(Edm.Single)",
                "searchable": true,
                "retrievable": true,
                "dimensions": 1536,
                "vectorSearchProfile": "my-default-vector-profile"
            }
        ],
        "vectorSearch": {
            "algorithms": [
                {
                    "name": "my-hnsw-config-1",
                    "kind": "hnsw",
                    "hnswParameters": {
                        "m": 4,
                        "efConstruction": 400,
                        "efSearch": 500,
                        "metric": "cosine"
                    }
                }
            ],
            "profiles": [
                {
                    "name": "my-default-vector-profile",
                    "algorithm": "my-hnsw-config-1"
                }
            ]
        }
    }
    

インデックス作成のためベクトル データを読み込む

インデックス作成用に指定するコンテンツは、インデックス スキーマに準拠し、ドキュメント キーの一意の文字列値を含んでいる必要があります。 事前ベクトル化データは、英数字コンテンツを含む他のフィールドと共存できる 1 つ以上のベクトル フィールドに読み込まれます。

データ インジェストにプッシュまたはプルの手法を使用できます。

ドキュメントのインデックス作成 (2023-11-01)ドキュメントのインデックス作成 (2023-10-01-Preview)、または ドキュメントの追加、更新、削除 (2023-07-01-Preview) を使用して、ベクトル データを含むドキュメントをプッシュします。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/index?api-version=2023-11-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "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 の Search エクスプローラーまたは REST API 呼び出しを使用してインデックスのクエリを実行できます。 Azure AI Search ではベクトルを人間が判読できるテキストに変換できないため、一致のエビデンスを提供する同じドキュメントからフィールドを返すようにしてください。 たとえば、ベクトル クエリが "titleVector" フィールドを対象とする場合は、検索結果に "title" を選択できます。

あるフィールドを結果に含めるには、そのフィールドに "retrievable" の属性が付けられている必要があります。

Search エクスプローラーを使用して、インデックスにクエリを実行できます。 Search エクスプローラーには、クエリ ビュー (既定) と JSON ビューの 2 つのビューがあります。

  • 実行するベクトル クエリの 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 リポジトリのコード サンプルでは、スキーマ定義、ベクトル化、インデックス作成、クエリを含むエンドツーエンドのワークフローを示しています。

PythonC#JavaScript 用のデモ コードがあります。