次の方法で共有


Azure AI 検索 でハイブリッド クエリを作成する

ハイブリッド検索は、単一の検索要求内でテキスト (キーワード) クエリとベクトル クエリを組み合わせたものです。 どちらのクエリも並列で実行されます。 結果は Reciprocal Rank Fusion (RRF) を使ってマージされ、新しい検索スコアによって並べ替えられて、統合された結果セットが返されます。 多くの場合、ベンチマーク テストに従い、セマンティック ランク付けを使用したハイブリッド クエリからは最も関連性の高い結果が返されます。

この記事では、次のことについて説明します:

  • 基本的なハイブリッド要求を設定する
  • パラメーターとフィルターを追加する
  • セマンティックのランク付けまたはベクトルの重みを使用して関連性を向上させる
  • 入力を制御してクエリの動作を最適化する (maxTextRecallSize)

この記事の終わりまでに、キーワードとベクター検索とオプションのセマンティック ランク付けを組み合わせたハイブリッド クエリを実行できます。

前提条件

API、ツール、実行可能パターンを選択する

  • Azure portal の Search Explorer (安定版とプレビュー版の両方の API 検索構文をサポート) には、ハイブリッド要求を貼り付けることができる JSON ビューがあります。

  • Azure SDK の新しい安定したパッケージまたはプレビュー パッケージ (SDK 機能サポートの変更ログを参照)。

  • maxTextRecallSize や countAndFacetMode(preview)などのプレビュー機能を使用している場合は、安定した REST API または最新のプレビュー API バージョン。

    読みやすくするため、REST の例を使用して、API のしくみを説明します。 Visual Studio Code などの REST クライアントと REST 拡張機能を使用して、ハイブリッド クエリを作成できます。 Azure SDK を使用することもできます。 詳細については、「 クイック スタート: ベクター検索」を参照してください。

実行可能なハイブリッド パターン

ハイブリッド検索を初めて使用する場合は、1 つのパターンを選択し、小さな手順で調整します。 同じ要求で、最大ベクター呼び出し、大きなテキストの再呼び出し、セマンティック再ランク付けから始めないでください。

  • バランスの取れたハイブリッド (既定) : ほとんどのワークロードで最初に使用します。 30 ~ 50 の範囲の k から開始し、10 ~ 20 の範囲で top し、測定された関連性が向上した場合にのみセマンティック ランク付けを有効にします。

  • リコール優先ハイブリッド: 網羅性を重視する難易度の高いクエリには、これを使用します。 maxTextRecallSizeを徐々に増やし、ベクター設定を中程度に保ちます。 マージ コストの増加が予想されます。

  • 精度優先ハイブリッド: 大規模な待機時間が短い場合に使用します。 ktop控えめにし、選択的フィルターを適用し、価値を追加しないセマンティック機能を回避します。

オーバーロードされたクエリがスロットルされる理由

ハイブリッド クエリでは、テキストとベクターの取得が並列で実行され、結果が RRF とマージされます。 字句の貢献度を高める場合 (たとえば、BM25 を優先してハイブリッド重みを変更するなど)、ベクター候補とマージする必要があるテキスト候補の数を増やします。 これを高価なベクター設定とセマンティック再ランク付けと組み合わせると、CPU とメモリの負荷が急速に上昇します。

容量構成が小さい場合、この追加のマージと再ランク付け作業によって、次の原因が生じる可能性があります。

  • レイテンシの増加と p95/p99 スパイクの増加
  • 429 スロットリング応答
  • 再試行動作が設定されていない場合に、クライアントクライアント側で観測されるリクエストのドロップやタイムアウト

スケールアウト前のチューニング順序

レプリカを追加する前に、クエリとベクターの設定を調整します。

  1. まず、コストのかかるベクター検索設定を減らします。 たとえば、 efSearchmaxConnections が積極的に設定されている場合は、スケールアウトする前にそれらを小さくします (たとえば、 efSearch を約 800 から 128 から 192 に減らし、 maxConnections を 64 から 32 に減らします)。
  2. セマンティック再ランク付けスコープを、その恩恵を受けるケースに制限します。
  3. 代表的な負荷の下で待機時間と 429 のレートを再テストします。
  4. チューニング後もスロットリングが続く場合のみ、レプリカをスケーリングします。

このシーケンスを使用して、最初に安定性を向上させ、スケーリングする前にコストを制御します。

ハイブリッド クエリを設定する

このセクションでは、ハイブリッド クエリの基本的な構造と、Search Explorer または REST クライアントで実行するクエリを設定する方法について説明します。

結果は、retrievable とマークされたフィールドのベクトルを含む、プレーンテキストで返されます。 数値ベクトルは検索結果では役に立たないため、インデックス内の他のフィールドをベクトル一致のプロキシとして選択します。 たとえば、インデックスに "descriptionVector" フィールドと "descriptionText" フィールドがある場合、クエリは "descriptionVector" で一致しますが、検索結果には "descriptionText" と表示されます。 この select パラメータを使用して、結果に人間が判読できるフィールドのみを指定します。

  1. Azure portal にサインインし、ご利用の検索サービスを探します。

  2. [ 検索の管理>インデックス] で、ベクトルと非ベクター コンテンツを含むインデックスを選択します。 検索エクスプローラー が最初のタブです。

  3. [ ビュー]JSON ビュー に切り替えて、ベクター クエリに貼り付けることができます。

  4. 既定のクエリ テンプレートをハイブリッド クエリに置き換えます。 基本的なハイブリッド クエリには、 searchで指定されたテキスト クエリと、 vectorQueries.vectorで指定されたベクター クエリがあります。 テキスト クエリとベクトル クエリは同等の場合も異なる場合もありますが、通常は同じ意図を共有します。

    この例は、ベクターコンテンツと非ベクトルコンテンツを含むベクター クイックスタート と、いくつかのクエリ例です。 簡潔にするために、この記事ではベクトルは切り詰められています。

    {
        "search": "historic hotel walk to restaurants and shopping",
        "vectorQueries": [
            {
                "vector": [0.01944167, 0.0040178085, -0.007816401 ... <remaining values omitted> ], 
                "k": 7,
                "fields": "DescriptionVector",
                "kind": "vector",
                "exhaustive": true
            }
        ]
    }
    
  5. [Search] を選択します。

    ヒント

    ベクトルを非表示にすると、検索結果が読みやすくなります。 [クエリ オプション] で、検索結果のベクトル値の非表示の設定を有効にします。

  6. クエリの別のバージョンを次に示します。 これにより、検出された一致の数の count 、特定のフィールドを選択するための select パラメーター、上位 7 つの結果を返す top パラメーターが追加されます。

     {
         "count": true,
         "search": "historic hotel walk to restaurants and shopping",
         "select": "HotelId, HotelName, Category, Tags, Description",
         "top": 7,
         "vectorQueries": [
             {
                 "vector": [0.01944167, 0.0040178085, -0.007816401 ... <remaining values omitted> ], 
                 "k": 7,
                 "fields": "DescriptionVector",
                 "kind": "vector",
                 "exhaustive": true
             }
         ]
     }
    

maxTextRecallSize と countAndFacetMode を設定する

現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、Microsoft Azure プレビューの追加使用条件に関するページをご覧ください。

ハイブリッド クエリを調整して、各サブクエリが結合された結果にどの程度寄与するかを制御できます。 maxTextRecallSize設定では、ハイブリッド ランク付けモデルに渡される BM25 ランク付け結果の数を指定します。

maxTextRecallSizeを使用する場合は、CountAndFacetModeを設定することもできます。 このパラメーターは、 countfacets に、検索クエリに一致するすべてのドキュメントを含めるか、 maxTextRecallSize ウィンドウ内で取得したドキュメントのみを含めるかを決定します。 既定値は "countAllResults" です。

これらのオプションを設定するには、 最新のプレビュー REST API をお勧めします。

ヒント

ハイブリッド クエリ チューニングのもう 1 つの方法は、要求内のベクター クエリの重要度を高めるために使用されるベクター 重み付けです。

  1. プレビュー パラメーターを指定するには 、検索 - POST (プレビュー) または 検索 - GET (プレビュー) を使用します。

  2. ハイブリッド クエリの BM25 ランク付け結果によって呼び戻されるドキュメントの最大数を設定するには、hybridSearch クエリ パラメーター オブジェクトを追加します。 2 つのプロパティがあります。

    • maxTextRecallSize は、ハイブリッド クエリで使われる Reciprocal Rank Fusion (RRF) ランカーに提供する BM25 ランク付け結果の数を指定します。 既定値は 1,000 です。 最大値は 10,000 です。

    • countAndFacetMode は、BM25 ランク付け結果 (およびファセットを使用している場合はファセット) の数を報告します。 既定値は、クエリに一致するすべてのドキュメントです。 必要に応じて、"カウント" のスコープを maxTextRecallSize に設定できます。

  3. maxTextRecallSizeを設定します。

    • ベクター類似性検索が一般にハイブリッド クエリのテキスト側を上回る場合は、 maxTextRecallSize を減らします。

    • インデックスが大きく、既定値で十分な数の結果がキャプチャされていない場合は、 maxTextRecallSize を増やします。 BM25 ランク付け結果セットが大きいときは、topskipnext を設定して、それらの結果の一部を取得することもできます。

次の REST の例では、maxTextRecallSize の設定に関する 2 つのユース ケースを示します。

最初の例では、maxTextRecallSize を 100 に減らして、ハイブリッド クエリのテキスト側を 100 ドキュメントのみに制限しています。 また、countAndFacetMode からの結果のみを含むように、maxTextRecallSize を設定しています。

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2025-11-01-preview 

    { 
      "vectorQueries": [ 
        { 
          "kind": "vector", 
          "vector": [1.0, 2.0, 3.0], 
          "fields": "my_vector_field", 
          "k": 10 
        } 
      ], 
      "search": "hello world", 
      "hybridSearch": { 
        "maxTextRecallSize": 100, 
        "countAndFacetMode": "countRetrievableResults" 
      } 
    } 

2 番目の例では、maxTextRecallSize を 5,000 に増やしています。 また、top、skip、next を使って、大きな結果セットから結果をプルしています。 この場合の要求では、RRF 複合結果セットへのテキスト クエリの寄与として、位置 1,500 から始まって 2,000 までの BM25 ランク付け結果がプルされます。

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2025-11-01-preview 

    { 
      "vectorQueries": [ 
        { 
          "kind": "vector", 
          "vector": [1.0, 2.0, 3.0], 
          "fields": "my_vector_field", 
          "k": 10 
        } 
      ], 
      "search": "hello world",
      "top": 500,
      "skip": 1500,
      "next": 500,
      "hybridSearch": { 
        "maxTextRecallSize": 5000, 
        "countAndFacetMode": "countRetrievableResults" 
      } 
    } 

リファレンス: hybridSearch | maxTextRecallSize | countAndFacetMode

ハイブリッド クエリの例

このセクションには、ハイブリッド クエリ パターンを示す複数のクエリ例があります。

例: フィルターを使用したハイブリッド検索

この例では、検索インデックスの非ベクトル フィールド filterable に適用されるフィルターを追加します。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2025-09-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "k": 10
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "vectorFilterMode": "preFilter",
    "filter": "ParkingIncluded",
    "top": "10"
}

重要なポイント:

  • フィルターは、フィルター可能なフィールドの内容に適用されます。 この例では、ParkingIncluded フィールドはブール値であり、インデックス スキーマで filterable としてマークされています。

  • ハイブリッド クエリでは、クエリの実行前にフィルターを適用して、クエリの表面を減らしたり、クエリの実行後に結果をトリミングしたりできます。 "preFilter" は既定値です。 postFilterまたはstrictPostFilter (プレビュー) を使用するには、この例に示すようにフィルター処理モードを設定します。

  • クエリ結果を事後フィルター処理すると、結果の数が上位 N 未満になる可能性があります。

リファレンス: filter | vectorFilterMode

例: ベクター サブクエリを対象とするフィルターを使用したハイブリッド検索 (プレビュー)

最新の プレビュー REST API を使用すると、ハイブリッド要求のベクター サブクエリのみを対象とするセカンダリ フィルターを適用することで、検索要求のグローバル フィルターをオーバーライドできます。

この機能は、フィルターがベクトル検索結果にのみ影響を与え、キーワードベースの検索結果には影響を与えないようにすることで、細かな制御を実現します。

ターゲット フィルターは、セキュリティによるトリミングや地理空間の検索に使用されるフィルターなど、グローバル フィルターを完全にオーバーライドします。 セキュリティによるトリミングなどのグローバル フィルターが必要な場合は、これらのフィルターを、最上位レベルのフィルターと各ベクトル レベルのフィルターの両方に明示的に含め、セキュリティやその他の制約が一貫して適用されるようにする必要があります。

対象となるベクトル フィルターを適用するには:

フィルターのオーバーライドを追加するハイブリッド クエリの例を次に示します。 グローバル フィルター "Rating gt 3" は、実行時に filterOverrideに置き換えられます。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2025-11-01-preview

{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true,
            "filterOverride": "Address/City eq 'Seattle'",
            "k": 10
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Address/City, Rating",
    "filter": "Rating gt 3",
    "debug": "vector",
    "top": 10
}

セマンティック ランカーがあり、インデックス定義にセマンティック構成が含まれていると仮定すると、マージされた結果セットに対するセマンティック ランク付けを使用して、ベクター検索とキーワード検索を含むクエリを作成できます。 必要に応じて、キャプションと回答を追加できます。

ベクトルでセマンティック ランク付けを使用するときは常に、k が 50 に設定されていることを確認します。 セマンティック ランカーでは、入力として最大 50 個の一致が使用されます。 50 未満を指定すると、セマンティック ランク付けモデルに必要な入力が与えられなくなります。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2025-09-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "k": 50
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Tags",
    "queryType": "semantic",
    "semanticConfiguration": "my-semantic-config",
    "captions": "extractive",
    "answers": "extractive",
    "top": "50"
}

重要なポイント:

  • セマンティック ランカーでは、マージされた応答から最大 50 個の結果が受け入れられます。

  • "queryType" と "semanticConfiguration" は必須です。

  • "captions" と "answers" は省略可能です。 値は、結果内の逐語的なテキストから抽出されます。 回答は、クエリに対する回答の特性を持つ内容が結果に含まれている場合にのみ返されます。

リファレンス: queryType | semanticConfiguration | captions | answers

例: フィルターを使用したセマンティック ハイブリッド検索

ここでは、コレクションでの最後のクエリを示します。 これは、前の例と同じセマンティック ハイブリッド クエリですが、フィルターを使用します。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2025-09-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "k": 50
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Tags",
    "queryType": "semantic",
    "semanticConfiguration": "my-semantic-config",
    "captions": "extractive",
    "answers": "extractive",
    "filter": "ParkingIncluded",
    "vectorFilterMode": "preFilter",
    "top": "50"
}

重要なポイント:

  • フィルター モードは、セマンティック リランカーで使用できる結果の数に影響を与える可能性があります。 ベスト プラクティスとして、セマンティック ランカーにドキュメントの最大数 (50) を指定するのが賢明です。 事前フィルターまたは事後フィルターの選択性が高すぎる場合、操作するドキュメントを 50 未満にすることでセマンティック ランカーを過小評価している可能性があります。

  • preFilter はクエリの実行前に適用されます。 プレフィルターによって検索領域が 100 個のドキュメントに縮小された場合、ベクター クエリは、これらの 100 個のドキュメントに対して DescriptionVector フィールドに対して実行され、k= 50 の最適な一致が返されます。 その後、これらの一致する 50 ドキュメントが RRF に渡されてマージされた結果が得られ、セマンティック ランカーに渡されます。

  • postFilter は、クエリの実行後に適用されます。 k=50 がベクトル クエリ側で 50 件の一致を返し、その後に 50 件の一致にポストフィルターを適用すると、結果はフィルター条件を満たすドキュメントの数だけ減少します。 これにより、セマンティック ランカーに渡されるドキュメントは 50 未満になります。 セマンティック ランク付けを使用する場合は、この点に留意してください。 セマンティック ランカーは、入力として 50 個のドキュメントがある場合に最適に動作します。

  • strictPostFilter (プレビュー) は、クエリの実行後にフィルター処理されていない上位k 結果に適用されます。 常に、 k ドキュメント以下を返します。 フィルター処理されていない k=50 が 50 個のフィルター処理されていない結果を返し、フィルターが 30 個のドキュメントと一致する場合、インデックスにフィルターに一致するドキュメントが 30 個を超える場合でも、結果セットには 30 個のドキュメントのみが返されます。 このモードでは再現率が最も低いため、セマンティック ランカーで使用することはお勧めしません。

クエリ応答を構成する

ハイブリッド クエリを設定するときは、応答構造について考えてください。 検索エンジンは、一致するドキュメントをランク付けし、最も関連性の高い結果を返します。 応答は平坦化された行集合です。 クエリのパラメータによって、各行に含まれるフィールドと、応答内の行数が決まります。

応答のフィールド

検索結果は、検索インデックスの retrievable フィールドで構成されます。 結果は次のいずれかになります:

  • すべての retrievable フィールド (REST API の既定値)。
  • クエリの select パラメーターに明示的に一覧表示されているフィールド。

この記事の例では、 select ステートメントを使用して、応答のテキスト (非ベクトル) フィールドを指定しました。

ベクトルは人間が判読できるテキストにリバース エンジニアリングされないため、応答で返されないようにします。 代わりに、検索ドキュメントを代表する非ベクトル フィールドを選択します。 たとえば、クエリが "DescriptionVector" フィールドを対象とする場合、応答に 1 つの ("Description") がある場合は、同等のテキスト フィールドを返します。

結果の件数

検索条件が弱い場合は、クエリが任意の数のドキュメントと一致する場合があります (たとえば、null クエリの場合は "search=*")。 無制限の結果を返すことが実用的であることは滅多にないので、"応答全体" の最大値を指定する必要があります:

  • "top": n キーワードのみのクエリの結果 (ベクターなし)
  • "k": n ベクトルのみのクエリの結果
  • "top": n "search" パラメーターを含むハイブリッド クエリ (セマンティックあり、または、なし) の結果

ktop はどちらも省略可能です。 指定しない場合、応答の結果の既定の数は 50 です。 topskipをページに設定して、より多くの結果を表示したり、既定値を変更したりできます。

2024-05-01-preview API でハイブリッド検索を使用する場合は、maxTextRecallSize を使用してキーワード クエリから返される結果の数を制御できます。 これを k の設定と組み合わせて、各検索サブシステム (キーワードとベクター) の表現を制御します。

セマンティック ランカーの結果

セマンティック ランカーでは最大 50 件の結果を受け取ることができます。

2024-05-01-preview 以降でセマンティック ランカーを使用している場合は、 kmaxTextRecallSize を合計 50 以上に設定することをお勧めします。 その後、 top パラメーターを使用して、ユーザーに返される結果を制限できます。

前の API でセマンティック ランカーを使用する場合は、次の操作を行います。

  • キーワードのみの検索 (ベクトルなし) top 50 に設定する場合
  • ハイブリッド検索 k 50 に設定されている場合は、セマンティック ランカーが少なくとも 50 件の結果を取得するようにします。

ランク付け

オプションの セマンティック再ランク付けの有無にかかわらず、ハイブリッド クエリでは複数のセットが作成されます。 結果のランク付けは、Reciprocal Rank Fusion (RRF) によって計算されます。

このセクションでは、単一ベクトル検索と単純ハイブリッド検索の応答を比較して、上位の結果を確認します。 異なるランク付けアルゴリズムである HNSW の類似性メトリックと RRF の場合では、異なる大きさのスコアが生成されます。 この動作は仕様によるものです。 RRF スコアは、類似性の一致が高い場合でも、非常に低くなる場合があります。 スコアの低さは、RRF アルゴリズムの特性です。 RRF を使用するハイブリッド クエリの場合、純粋なベクトル検索とは対照的に、RRF でランク付けされたドキュメントのスコアは比較的小さいため、ランク付けされたドキュメントの逆数がより多く結果に含まれます。

単一ベクトル検索: コサイン類似度で並べ替えられた結果の @search.score (既定のベクトル類似距離関数)。

{
    "@search.score": 0.8399121,
    "HotelId": "49",
    "HotelName": "Swirling Currents Hotel",
    "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center.",
    "Category": "Luxury",
    "Address": {
    "City": "Arlington"
    }
}

ハイブリッド検索: Reciprocal Rank Fusion を使用してランク付けされたハイブリッド結果の @search.score。

{
    "@search.score": 0.032786883413791656,
    "HotelId": "49",
    "HotelName": "Swirling Currents Hotel",
    "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center.",
    "Category": "Luxury",
    "Address": {
    "City": "Arlington"
    }
}

ハイブリッド クエリのトラブルシューティング

次の表を使用して、ハイブリッド クエリに関する一般的な問題を診断します。

問題点 考えられる原因 解決策
空の結果 ベクター フィールド名の不一致またはインデックス データの欠落 fieldsvectorQueriesがインデックス スキーマのベクター フィールドと一致するかどうかを確認します。 ドキュメントにベクター データが含まれていることを確認します。
RRF スコアが低い 通常の RRF 動作 RRF スコアは、本質的に類似性スコアよりも低くなります。 スコアが 0.03 であっても、依然として強い一致を示すことがあります。
ベクトルの結果が優勢 テキスト クエリのパフォーマンスが低い maxTextRecallSizeを増やして BM25 の結果を増やすか、ベクターの重みを調整します。
テキストの結果が優勢 ベクターの類似性が低すぎます 埋め込み品質を確認します。 クエリ ベクターでドキュメント ベクターと同じモデルが使用されていることを確認します。
セマンティックランク付けシステムが返す結果の数が減少します 入力ドキュメントが不足しています セマンティック ランク付けを使用する場合は、 k を少なくとも 50 に設定します。 フィルターの制限が厳しすぎないことを確認します。
ベクターに適用されないフィルター グローバル フィルターのみを使用する ベクター固有のフィルター処理では、ベクター クエリ (プレビュー) で filterOverride を使用します。
結果に予期しないフィールドが含まれています select パラメーターがありません selectを追加して、返すフィールドを指定します。 読みやすくするためにベクター フィールドを除外します。