在 Azure AI 搜尋服務 中建立混合查詢

註

Azure AI 搜尋服務 可透過 Azure 入口網站、REST API 及 Azure SDK 取得。 它同時也是 Foundry IQ 的基礎,這是一個管理式知識層,能將企業內容轉化為可重複使用、權限感知的知識庫,供 Microsoft Foundry 入口網站中的代理使用。

Important

標記(預覽)的功能、能力或屬性不受服務等級協議涵蓋,也不建議用於生產工作負載,且在正式上架前可能會有所變動或受限。 Azure AI 搜尋服務 預覽條款適用於所有預覽功能,無論是獨立功能還是正式推出功能的一部分。

混合式搜尋 結合了文字(關鍵字)與向量查詢於單一搜尋請求中。 兩個查詢都是平行執行。 結果會合併並依新的搜尋分數重新排序,並使用 Reciprocal Rank Fusion (RRF) 傳回統一結果集。 根據 基準測試,在許多情況下,帶有語意排序的混合查詢會回傳最相關的結果。

在本文中,您將學習如何:

  • 設定一個基本的混合式請求
  • 新增參數與過濾器
  • 利用語意排序或向量權重提升相關性
  • 透過控制輸入maxTextRecallSize() 來優化查詢行為

在本文結尾,你可以執行結合關鍵字與向量搜尋,並可選的語意排序混合查詢。

先決條件

選擇一個 API、工具和可行的模式

  • Azure 入口網站的搜尋總管(支援穩定與預覽版 API 搜尋語法)有一個 JSON 視圖,可以貼上混合式請求。

  • 較新的穩定版本或預覽版本的 Azure SDK 套件(請參見變更記錄以便了解 SDK 功能支援)。

  • 穩定的 REST API,或如果您使用 maxTextRecallSize 和 countAndFacetMode(預覽) 等預覽功能時,請使用較新的預覽 API 版本。

    為了方便閱讀,我們使用 REST 範例來解釋 API 的運作方式。 你可以用像 Visual Studio Code 這樣的 REST 客戶端搭配 REST 擴充功能來建立混合式查詢。 你也可以使用 Azure SDK。 欲了解更多資訊,請參閱 快速入門:向量搜尋。

可行的混合模式

如果你是混合搜尋的新手,可以選擇一個模式,然後逐步微調。 不要在同一請求中同時啟用最大向量召回、大文本召回和語意重排序。

  • 平衡混合(預設):優先使用此模式以處理大多數工作負載。 從 30 到 50 範圍內的 k、10 到 20 範圍內的 top 開始,並且只在語意排名改善測量的相關性時才啟用。

  • 召回優先混合:當涵蓋範圍是目標時,請將此用於困難查詢。 逐步增加 maxTextRecallSize ,並保持向量設定為中等。 合併成本會比較高。

  • 優先考量精密的混合模式:在大規模運行時實現低延遲。 保持ktop謙虛,使用選擇性篩選,避免無價值的語義特徵。

為什麼負擔過重的查詢會被節流

混合式查詢會同時執行文字與向量檢索,然後將結果與 RRF 合併。 如果你增加詞彙貢獻(例如將混合權重調整為 BM25),就會增加必須與向量候選人合併的文本候選數量。 如果再加上昂貴的向量設定和語意重排序,CPU 和記憶體壓力會迅速上升。

在較小容量配置中,這種額外的合併與重新排序工作可能導致:

  • 較高的延遲和 p95/p99 尖峰
  • 429 次降頻回應
  • 當未設定重試行為時,客戶端系統觀察到請求被丟棄或逾時。

放大前的調諧順序

在新增副本前,先調整查詢和向量設定:

  1. 先減少昂貴的向量搜尋設定。 例如,如果 efSearch 和 maxConnections 設定得很激進,先將 efSearch 和 maxConnections 降低,再進行擴大(例如將 從約 800 減少到 128 至 192,並將 從 64 減少到 32)。
  2. 將語意重新排序的範圍限制在真正能夠從中受益的情況。
  3. 在代表性負載下重新測試延遲和 429 速率。
  4. 只有在調校後節流持續時才進行縮放複本。

先用這個序列提升穩定性並控制成本,再擴展。

設定一個混合式查詢

本節說明混合查詢的基本結構,以及如何在搜尋檔案總管或 REST 用戶端中設定。

結果以純文字回傳,包括標記為 retrievable的欄位向量。 由於數值向量在搜尋結果中無用,請選擇索引中其他欄位作為向量匹配的代理。 例如,如果索引有「descriptionVector」和「descriptionText」欄位,查詢可以匹配到「descriptionVector」,但搜尋結果可能顯示「descriptionText」。 使用 select 參數在結果中指定僅可讀的欄位。

  1. 在Azure 入口網站中,進入您的搜尋服務。

  2. 在 搜尋管理>的索引中,選擇包含向量與非向量內容的索引。 搜尋總管 是第一個分頁。

  3. 在 檢視中切換到 JSON 檢視 ,這樣你可以貼上向量查詢。

  4. 用混合式查詢取代預設的查詢範本。 基本的混合查詢有一個文字查詢,定義在search內,以及一個向量查詢,定義在vectorQueries.vector下。 文字查詢和向量查詢可以是等價的,也可以是分歧的,但它們通常會有相同的意圖。

    這個範例來自 vector quickstart,裡面有向量和非向量內容,還有幾個查詢範例。 為簡潔起見,本文將向量截斷。

    {
        "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. 選擇 搜尋。

    提示

    如果隱藏向量,搜尋結果會比較容易閱讀。 在 查詢選項中,開啟 搜尋結果中的隱藏向量值。

  6. 這是查詢的另一個版本。 這個版本增加了 count 一個代表匹配數量的參數、 select 一個選擇特定欄位的參數,以及 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(預覽)

混合查詢可以調整以控制每個子查詢對合併結果的貢獻比例。 設定 maxTextRecallSize 參數(預覽)則指定有多少 BM25 排名結果會傳遞給混合排名模型。

如果您的要求包含 Facet,請使用索引中標示為 facetable 的非向量欄位。 向量場不可分面。

Facet 計數視查詢類型而定:

  • 在純文字查詢中,分面會計算與文字查詢相符的文件數量。
  • 在僅向量查詢中,Facet 會計算向量查詢傳回的 k 份文件。
  • 在混合查詢中,Facet 會同時納入向量和文字結果。 向量端會貢獻 k 個最近的文件。 文字端會貢獻 BM25 排名的文件。 countAndFacetMode 參數(預覽)會決定計數和分面計算是使用所有文字相符項目,還是只使用為了進行排名而擷取的文字相符項目。

如果你使用 maxTextRecallSize,你可能還想設定 countAndFacetMode。 此參數決定是否countfacets包含所有符合文字查詢的文件,或僅包含視窗內maxTextRecallSize檢索的文件。 預設值為 countAllResults。

使用預設 countAllResults 模式時,計數和 Facet 可以包含因落在 maxTextRecallSize 視窗之外而未擷取以進行 RRF 排名的文字端文件。 增加 maxTextRecallSize 會增加可供排序的依 BM25 排序文件數量,但不會讓向量的貢獻超過 k。 如果您想將計數和 Facet 計算範圍限定為針對混合式排名擷取的文件,請使用 countRetrievableResults。

我們建議使用 最新的預覽版 REST API 來設定這些選項。

提示

另一種混合查詢調整方法是 向量加權,用以提升請求中向量查詢的重要性。

  1. 請使用 搜尋 - POST(預覽) 或 搜尋 - GET(預覽) 來指定預覽參數。

  2. 新增一個查詢 hybridSearch 參數物件,以設定混合查詢中基於 BM25 排名結果所能調回的文件最大數量。 它有兩個特性:

    • maxTextRecallSize 指定提供給混合查詢中使用的互惠秩融合(RRF)排名器的 BM25 排名結果數量。 預設值是1,000。 最高可達10,000人。

    • countAndFacetMode 會報告混合式查詢的計數和 Facet 範圍。 預設的 countAllResults 會使用完整的混合結果集,其中包含所有符合文字查詢的文件,即使其中部分文字相符結果因落在 maxTextRecallSize 視窗範圍之外而不會被擷取來進行 RRF 排名。 使用 countRetrievableResults,將計數和 Facet 範圍限定為針對排名擷取的文件,包括 maxTextRecallSize BM25 排名文件和 k 向量相符項目。

  3. 設定 maxTextRecallSize:

    • 若向量相似度搜尋通常優於混合查詢的文字端,則減少 maxTextRecallSize 。

    • 如果你的指數很大,且預設無法捕捉足夠數量的結果,就要提高 maxTextRecallSize 。 在較大的 BM25 排名結果集下,你也可以設定top、skip、next來取得這些結果的部分內容。

以下 REST 範例展示了設定 maxTextRecallSize的兩個使用情境。

第一個範例縮減 maxTextRecallSize 為 100 份,將混合式查詢的文字端限制為 100 份文件。 它也會將 countAndFacetMode 設定為僅在計數和 Facet 計算中包含可擷取的文件。

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2026-08-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" 
      } 
    } 

第二個例子中,將 maxTextRecallSize 提高到5,000。 它也使用 top、skip 和 next 從大型結果集中抓取結果。 在此情況下,要求會提取從位置 1,500 到 2,000 的 BM25 排名結果,做為 RRF 複合結果集的文字查詢貢獻。

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2026-08-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=2026-04-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 (預覽),請設定此範例所示 的過濾處理模式 。

  • 當您對查詢結果進行後置篩選時,結果數量可能少於 top-n。

參考資料: filter | vectorFilterMode

範例:以向量子查詢為目標並使用篩選器的混合式搜尋 (預覽版)

使用 最新的預覽 REST API,您可以套用僅以混合式要求中的向量子查詢為目標的次要篩選,以覆寫搜尋要求上的全域篩選。

此功能提供細緻控制,確保篩選器只影響向量搜尋結果,關鍵字搜尋結果不受影響。

目標過濾器會完全覆蓋全域過濾器,其中包括用於 安全修剪 或地理空間搜尋的任何過濾器。 在需要全域篩選器的情況下,例如安全裁剪,必須在頂層篩選器及每個向量層級篩選器中明確納入這些篩選器,以確保安全及其他限制能一致執行。

應用針對性向量濾波器:

以下是新增篩選覆寫的混合式查詢範例。 全域過濾器「Rating gt 3」在執行時會被替換為 filterOverride。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2026-08-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=2026-04-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」是必需的。

  • 「說明文字」和「答案」為可選。 數值是從結果中的逐字文字中提取的。 只有當結果包含具有該查詢答案特徵的內容時,才會回傳答案。

參考資料:queryType | semanticConfiguration | captions | answers

範例:含過濾器的語意混合搜尋

此範例為語意混合查詢新增了一個 ParkingIncluded 過濾器。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2026-04-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 件文件,向量查詢會對 DescriptionVector 這 100 份文件的欄位執行,回傳 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」欄位,回應中有相應的文字欄位(「Description」),則回傳一個等效的文字欄位(「Description」)。

結果數量

查詢可以匹配任意數量的文件,若搜尋條件較弱(例如空查詢的「search=*」),則可匹配所有文件。 由於回傳無界結果通常不實際,你應該為 整體回應設定一個最大值:

  • "top": n 僅關鍵字查詢的結果(無向量)
  • "k": n 僅向量查詢的結果
  • "top": n 包含"search"參數的混合查詢結果(有語意或無語意)

兩者都是ktop可選的。 未指定,回應的預設結果數為50。 你可以設定 top 和 skip 來翻閱更多結果,或更改預設值。

註

如果你在 2024-05-01-preview API 中使用混合搜尋,你可以使用 maxTextRecallSize 控制關鍵字查詢的結果數量。 將此與一個針對k的設定結合,以控制每個搜尋子系統(關鍵字和向量)的表現形式。

語意排名結果

註

語意排名器最多可接受 50 個結果。

如果您使用 2024-05-01-preview 或更新版本中的語意排名器,最佳做法是將 k 和 maxTextRecallSize 設定為總和至少 50。 接著你可以用參數 top 限制回傳給使用者的結果。

如果你在 2024-05-01-preview 之前的 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"
    }
}

混合式搜尋:@search.score 適用於使用 Reciprocal Rank Fusion 排名的混合式結果。

{
    "@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"
    }
}

排除混合查詢問題

請使用以下表格來診斷混合查詢的常見問題。

問題 可能原因 解決方法
空結果 向量欄位名稱不匹配或索引資料遺失 驗證 fields in vectorQueries 與你的索引模式中的向量場相符。 檢查文件是否包含向量資料。
低RRF分數 一般 RRF 行為 RRF 分數本質上低於相似度分數。 即使分數為 0.03,仍可能表示高度匹配。
向量結果佔主導地位 文字查詢表現不佳 增加 maxTextRecallSize 以納入更多BM25結果,或調整向量加權。
文字結果佔主導地位 向量相似度太低 檢查嵌入品質。 確保查詢向量使用與文件向量相同的模型。
語意排序器回傳的結果較少 輸入文件不足 使用語意排名時,至少設定 k 為 50。 檢查過濾器是否過於嚴格。
未將濾波器套用於向量 僅使用全域過濾器 針對向量特定篩選,請在向量查詢(預覽)中使用 filterOverride 。
結果中的未預期欄位 select 缺少參數 新增 select 以指定要回傳哪些欄位。 為了可讀性,排除向量場。