共用方式為


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

混合式搜尋會將一或多個文字 (關鍵字) 查詢與一或多個向量查詢合併到單一搜尋要求中。 查詢會以平行方式執行。 結果會使用倒數排名融合 (RRF) 以新的搜尋分數加以合併並重新排序,以傳回統一的結果集。

在許多情況下,根據效能評定測試 (英文),具有語意排名的混合式查詢會傳回最相關的結果。

若要改善相關性:

  • 新的參數 maxTextRecallSize and countAndFacetMode(preview) 可讓您更充分掌控輸入到混合式查詢中的文字。

  • 新的向量加權可讓您設定向量查詢的相對權數。 這項功能特別適用於需要合併兩個以上相異結果集的複雜查詢,就和混合式搜尋的情況一樣。

必要條件

選擇 API 或工具

  • 2023-11-01 (部分機器翻譯) 穩定版本
  • 2023-10-01-preview (部分機器翻譯),在混合式查詢的向量側新增了整合向量化
  • 2024-03-01-preview (部分機器翻譯),在混合式查詢的向量側新增了窄資料類型和純量量化
  • 2024-05-01-preview (部分機器翻譯),特別針對混合式搜尋新增了 maxTextRecallSizecountAndFacetMode
  • Azure 入口網站中的搜尋總管 (目標為 2024-05-01-preview 行為)
  • 較新的穩定或 Beta 版 Azure SDK 套件 (請參閱 SDK 功能支援的變更記錄)

在搜尋總管中執行混合式查詢

  1. 搜尋總管 (部分機器翻譯) 中,確定 API 版本為 2023-10-01-preview 或更新版本。

  2. 在 [檢視] 底下,選取 [JSON 檢視]

  3. 將預設查詢範本取代為混合式查詢,例如向量快速入門範例第 539 行起的內容。 為求簡潔,本文截斷了該向量。

    混合式查詢會在 search 中指定文字查詢,並在 vectorQueries.vector 底下指定向量查詢。

    文字查詢和向量查詢應該相等或至少不衝突。 如果這兩個查詢不同,您就無法獲得混合式查詢的優點。

    {
        "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
            }
        ]
    }
    
  4. 選取搜尋

混合式查詢要求 (REST API)

混合式查詢合併了文字搜尋和向量搜尋,其中 search 參數會採用查詢字串,而且 vectorQueries.vector 採用向量查詢。 搜尋引擎會以平行方式執行全文檢索搜尋和向量查詢。 系統會使用倒數排名融合 (RRF) 來評估所有相符項目聯集的相關性,並在回應中傳回單一結果集。

結果會以純文字傳回,包括標示為 retrievable 的欄位中的向量。 因為數值向量不適用於搜尋結果,所以請選擇索引中的其他欄位做為向量比對的 Proxy。 例如,如果索引具有「descriptionVector」和「descriptionText」欄位,查詢可以比對「descriptionVector」,但搜尋結果可以顯示「descriptionText」。 使用 select 參數,只指定結果中人類可讀取的欄位。

下列範例會示範混合式查詢的設定。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true,
            "k": 10
        },
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true,
            "k": 10
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Address/City",
    "top": 10
}

重點︰

  • 向量查詢字串可透過 vectorQueries.vector 屬性來加以指定。 查詢會針對「DescriptionVector」欄位來執行。 將 kind 設定為「vector」以表示查詢類型。 或者,將 exhaustive 設定為 true,以查詢向量欄位的完整內容。

  • 關鍵字搜尋是透過 search 屬性來指定。 這會與向量查詢平行執行。

  • k 會決定從向量查詢傳回的近鄰相符項目數目,並提供給 RRF 排名工具。

  • top 會決定回應全部傳回的相符項目數目。 在此範例中,回應包含 10 個結果,假設合併的結果中至少有 10 個相符項目。

混合式搜尋與篩選

此範例會新增篩選,這會套用於搜尋索引的 filterable 非向量欄位。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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": "postFilter",
    "filter": "ParkingIncluded",
    "top": "10"
}

重點︰

  • 篩選會套用於可篩選欄位的內容。 在此範例中,ParkingIncluded 欄位是布林值,且在索引結構描述中標示為 filterable

  • 在混合式查詢中,篩選可以在查詢執行之前套用,以減少查詢介面,或在查詢執行之後套用以修剪結果。 "preFilter" 是預設值。 若要使用 postFilter,請設定 篩選處理模式,如此範例所示。

  • 您在篩選後查詢結果時,結果數目可能小於 top-n。

假設您已啟用語意排名,且索引定義包含語意設定 (部分機器翻譯),您可以制定包含向量搜尋和關鍵字搜尋的查詢,並對合併的結果集進行語意排名。 (選擇性) 您可以新增標題和答案。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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」是選用。 值會從結果中逐字擷取。 只有在結果包含具有查詢答案特性的內容時,才會傳回答案。

使用篩選的語意混合式搜尋

以下是集合中的最後一個查詢。 這是與上一個範例相同的語意混合式查詢,但使用篩選條件。

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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": "ParkingIsIncluded'",
    "vectorFilterMode": "postFilter",
    "top": "50"
}

重點︰

  • 篩選模式可能會影響語意重新執行程式可用的結果數目。 最佳做法是,為語意排名工具設定文件數目上限 (50)。 如果預先篩選或後置篩選過於選擇性,您可能會藉由提供少於 50 份文件來保留語意排名工具。

  • 預先篩選會在查詢執行之前套用。 如果預先篩選將搜尋區域縮減為 100 份文件,則向量查詢會針對這 100 份文件的「DescriptionVector」欄位來執行,並傳回 k=50 的最佳相符項目。 這 50 個相符的文件接著會傳遞至 RRF 以取得合併的結果,然後傳遞至語意排名工具。

  • 後續篩選會在查詢執行之後套用。 如果 k=50 傳回向量查詢側的 50 個相符項目,則篩選後會套用於 50 個相符項目,減少符合篩選準則的結果,讓您擁有少於 50 份文件以傳遞至語意排名工具。

設定 maxTextRecallSize 和 countAndFacetMode (預覽)

本節說明如何藉由控制流向混合式排名模型的 BM25 排名結果數量,來調整混合式查詢的輸入。 控制 BM25 排名的輸入可讓您在混合式案例中獲得更多用於微調相關性的選項。

提示

另一個要考量的選項是補充或取代技術,這是向量加權,會增加要求中的向量查詢重要性。

  1. 在 2024-05-01-preview 中使用搜尋 - POST (部分機器翻譯) 或搜尋 - GET (部分機器翻譯) 來指定這些參數。

  2. 新增 hybridSearch 查詢參數物件,以設定透過混合式查詢的 BM25 排名結果所回收的文件數目上限。 其具有兩個屬性:

    • maxTextRecallSize 會指定要提供給混合式查詢中所用倒數排名融合 (RRF) 排名工具的 BM25 排名結果數目。 預設值為 1,000。 上限為 10,000。

    • countAndFacetMode 會報告 BM25 排名結果的計數 (如果您使用 Facet,則會報告 Facet 的計數)。 預設值為符合查詢的所有文件。 (選擇性) 您可以將「count」範圍設定為 maxTextRecallSize

  3. 如果向量相似性搜尋的效果通常優於混合式查詢的文字側,請減少 maxTextRecallSize

  4. 如果您有大型索引,且預設值並未擷取足夠的結果數目,則增加 maxTextRecallSize。 使用較大的 BM25 排名結果集時,您也可以設定 topskipnext 來擷取這些結果的一部分。

下列 REST 範例顯示兩個用於設定 maxTextRecallSize 的使用案例。

第一個範例會將 maxTextRecallSize 縮減為 100,以將混合式查詢的文字側限制為只有 100 份文件。 其也會設定 countAndFacetMode,以便只包含來自 maxTextRecallSize 的結果。

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

設定查詢回應

當您設定混合式查詢時,請考慮回應結構。 回應是扁平化資料列集。 查詢上的參數會決定每個資料列中有哪些欄位,以及回應中有多少個資料列。 搜尋引擎會對相符的文件進行排名,並傳回最相關的結果。

回應中的欄位

搜尋結果是由搜尋索引中的 retrievable 欄位所組成。 結果為:

  • 所有 retrievable 欄位 (REST API 預設值)。
  • 在查詢的 "select" 參數中明確列出的欄位。

本文中的範例使用了 "select" 陳述式來指定回應中的文字 (非向量化) 欄位。

注意

向量無法以反向工程處理為人類可讀的文字,因此請避免在回應中傳回向量。 相反地,請選擇代表搜尋文件的非向量欄位。 例如,如果查詢以「DescriptionVector」欄位為目標,則若您在回應中有一個 (「Description」),則會傳回對等的文字欄位。

結果數

如果搜尋準則薄弱,查詢可能會與任意數目的文件相符(例如 null 查詢的「search=*」)。 因為傳回未繫結的結果大多不實用,因此請為「整體回應」指定最大值:

  • "top": n 個只有關鍵字之查詢的結果 (沒有向量)
  • 僅限向量查詢的 "k": n 結果
  • "top": n 個包含「搜尋」參數之混合式查詢 (包含或不含語意) 的結果

「k」和「top」都是選用。 未指定,回應中的預設結果數目為 50。 您可以設定「top」和「skip」,逐頁檢視更多的結果或變更預設值。

注意

如果您在 2024-05-01-preview API 中使用混合式搜尋,則可以使用 maxTextRecallSize 來控制關鍵字查詢的結果數目。 將此參數與「k」的設定結合,則可控制每個搜尋子系統 (關鍵字和向量) 的表示法。

語意排名工具結果

注意

語意排名工具最多可能需要 50 個結果。

如果您在 2024-05-01-preview API 中使用語意排名,最佳做法是將「k」和「maxTextRecallSize」設定為總共至少 50 個。 然後,您可以使用「top」參數來限制傳回給使用者的結果。

如果您在先前的 API 中使用語意排名,請執行下列動作:

  • 如果執行只有關鍵字的搜尋 (沒有向量),請將「top」設定為 50
  • 如果執行混合式搜尋,請將「k」設定為 50,以確保語意排名工具可獲得至少 50 個結果。

排名

系統會針對混合式查詢建立多個集合,且不需要選用的語意重新排名。 結果的排名是由倒數排名融合 (RRF) 計算。

在本節中,比較單一向量搜尋與最上層結果的簡單混合式搜尋之間的回應。 不同排名演算法 HNSW 的相似度計量和 RRF 就是這種情況,會產生不同程度的分數。 這是依照設計的行為。 RRF 分數看起來相當低,即使有很高的相似度比對。 較低的分數是 RRF 演算法的特性。 在與 RRF 的混合式查詢中,由於 RRF 排名文件的分數相對較小,而不是純向量搜尋,因此在結果中會包含排名文件的更多相互比較。

單一向量搜尋:依餘弦相似性排序之結果的 @search.score (預設向量相似性距離函式)。

{
    "@search.score": 0.8399121,
    "HotelId": "49",
    "HotelName": "Old Carrabelle 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。

{
    "@search.score": 0.032786883413791656,
    "HotelId": "49",
    "HotelName": "Old Carrabelle 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"
    }
}

下一步

做為下一個步驟,建議您檢閱 PythonC#JavaScript 的示範程式碼。