在 Azure AI 搜尋中建立混合式查詢
混合式搜尋 會在單一搜尋要求中結合文字(關鍵詞)和向量查詢。 要求中的所有子查詢都會以平行方式執行。 結果會使用倒數排名融合 (RRF) 以新的搜尋分數加以合併並重新排序,以傳回統一的結果集。 在許多情況下,根據效能評定測試 (英文),具有語意排名的混合式查詢會傳回最相關的結果。
在本文中,了解如何:
- 設定基本要求
- 使用更多參數和篩選來制定混合式查詢
- 使用語意排名或向量權數改善相關性
- 藉由控制文字和向量輸入來優化查詢行為
注意
2024-09-01-preview 的新功能是能夠將篩選目標設為混合式要求中的向量子查詢。 這可讓您更精確地套用篩選。 如需詳細資訊,請參閱 本文中的將篩選目標設為向量子查詢 。
必要條件
包含
searchable
向量和非向量欄位的搜尋索引。 我們建議匯 入和向量化數據精靈 ,以快速建立索引。 否則,請參閱 建立索引 並將 向量字段新增至搜尋索引。(選擇性)如果您想要查詢字串的內建文字到向量轉換, 請建立向量化工具 ,並將其指派給搜尋索引中的向量字段。
選擇 API 或工具
Azure 入口網站 中的搜尋總管(同時支援穩定和預覽 API 搜尋語法)具有 JSON 檢視,可讓您貼上混合式要求。
如果您使用 maxTextRecallSize 和 countAndFacetMode(preview)等預覽功能,則為 2024-07-01 穩定版本或最近的預覽 API 版本。
為了瞭解可讀性,我們會使用 REST 範例來說明 API 的運作方式。 您可以使用像是 Visual Studio Code 的 REST 用戶端搭配 REST 擴充功能來建置混合式查詢。 如需詳細資訊,請參閱 快速入門:使用 REST API 進行向量搜尋。
較新的穩定或 Beta 版 Azure SDK 套件(請參閱 SDK 功能支援的變更記錄)。
在搜尋總管中設定混合式查詢
在 搜尋總管中,確定 API 版本為 2024-07-01 或較新的預覽 API 版本。
在 [檢視] 底下,選取 [JSON 檢視],以便貼上向量查詢。
以混合式查詢取代預設查詢範本,例如從向量快速入門第 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 } ] }
選取 [搜尋]。
提示
如果您隱藏向量,搜尋結果會更容易閱讀。 在 [查詢選項] 中,開啟 [ 隱藏搜尋結果中的向量值]。
混合式查詢要求 (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=2024-07-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=2024-07-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。
以向量子查詢為目標的篩選混合式搜尋 (預覽)
使用 2024-09-01-preview,您可以套用以混合式要求中向量子查詢為目標的次要篩選,以覆寫搜尋要求的全域篩選。
這項功能藉由確保篩選只會影響向量搜尋結果,讓關鍵詞型搜尋結果不受影響,以提供更細緻的控制。
目標篩選會完整覆寫全域篩選,包括用於 安全性修剪 或地理空間搜尋的任何篩選。 如果需要全域篩選條件,例如安全性調整,您必須在最上層篩選和每個向量層級篩選中明確包含這些篩選條件,以確保一致地強制執行安全性和其他條件約束。
若要套用目標向量篩選:
使用最新的預覽搜尋檔 REST API 或提供此功能的 Azure SDK Beta 套件。
修改查詢要求,將新的
vectorQueries.filterOverride
參數集新增至 OData 篩選表達式。
以下是新增篩選覆寫的混合式查詢範例。 篩選條件Ovrride 會在運行時間取代全域篩選 「Rating gt 3」。。
POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-09-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=2024-07-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=2024-07-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 份文件傳遞給語意排名器。 如果您使用語意排名,請記住這點。 語意排名器在有 50 份檔做為輸入時效果最佳。
設定 maxTextRecallSize 和 countAndFacetMode (預覽)
本節說明如何藉由控制流向混合式排名模型的 BM25 排名結果數量,來調整混合式查詢的輸入。 控制 BM25 排名的輸入可讓您在混合式案例中獲得更多用於微調相關性的選項。
我們建議預覽 REST API 版本 2024-05-01-preview。
提示
另一個要考量的選項是補充或取代技術,這是向量加權,會增加要求中的向量查詢重要性。
在 2024-05-01-preview 中使用搜尋 - POST (部分機器翻譯) 或搜尋 - GET (部分機器翻譯) 來指定這些參數。
新增
hybridSearch
查詢參數物件,以設定透過混合式查詢的 BM25 排名結果所回收的文件數目上限。 其具有兩個屬性:maxTextRecallSize
會指定要提供給混合式查詢中所用倒數排名融合 (RRF) 排名工具的 BM25 排名結果數目。 預設值為 1,000。 上限為 10,000。countAndFacetMode
會報告 BM25 排名結果的計數 (如果您使用 Facet,則會報告 Facet 的計數)。 預設值為符合查詢的所有文件。 (選擇性) 您可以將「count」範圍設定為maxTextRecallSize
。
如果向量相似度搜尋的效果通常優於混合式查詢的文字端,請減少
maxTextRecallSize
。如果您有大型索引,且預設值並未擷取足夠的結果數目,則增加
maxTextRecallSize
。 使用較大的 BM25 排名結果集時,您也可以設定top
、skip
和next
來擷取這些結果的一部分。
下列 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": "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。
{
"@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"
}
}
下一步
做為下一個步驟,建議您檢閱 Python、C# 或 JavaScript 的示範程式碼。