在 Azure AI 搜尋服務中建立向量查詢

在 Azure AI 搜尋中,如果您有 搜尋索引中的向量字段 ,本文將說明如何:

本文使用 REST 進行說明。 如需其他語言的程式代碼範例,請參閱 azure-search-vector-samples GitHub 存放庫,以取得包含向量查詢的端對端解決方案。

必要條件

提示

若要快速判斷您的索引是否有向量,請尋找類型 Collection(Edm.Single)為 的字段、具有 dimensions 屬性和 vectorSearchProfile 指派。

將查詢字串輸入轉換成向量

若要查詢向量欄位,查詢本身必須是向量。 將使用者的文字查詢字串轉換成其向量表示法的其中一種方法,就是在應用程式程式代碼中呼叫內嵌連結庫或 API。 最佳做法是, 一律使用相同的內嵌模型,以在源文件中產生內嵌。

您可以找到程式代碼範例,示範如何在 azure-search-vector-samples 存放庫中產生內嵌

以下是提交至 Azure OpenAI 內嵌模型部署之查詢字串的 REST API 範例:

POST https://{{openai-service-name}}.openai.azure.com/openai/deployments/{{openai-deployment-name}}/embeddings?api-version={{openai-api-version}}
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "input": "what azure services support generative AI'"
}

預期的回應為 202,表示成功呼叫已部署的模型。 回應本文中的「內嵌」欄位是查詢字串 "input" 的向量表示法。 基於測試目的,您會使用後續數節所示的語法,將 「embedding」 陣列的值複製到查詢要求中的 「vectorQueries.vector」。。

此 POST 呼叫已部署模型的實際回應包含 1536 個內嵌,並在這裡修剪為僅前幾個可讀性的向量。

{
    "object": "list",
    "data": [
        {
            "object": "embedding",
            "index": 0,
            "embedding": [
                -0.009171937,
                0.018715322,
                ...
                -0.0016804502
            ]
        }
    ],
    "model": "ada",
    "usage": {
        "prompt_tokens": 7,
        "total_tokens": 7
    }
}

在此方法中,您的應用程式程式代碼會負責連線到模型、產生內嵌,以及處理回應。

提示

嘗試 使用目前處於公開預覽狀態的整合向量化查詢,讓 Azure AI 搜尋處理查詢向量化輸入和輸出。

向量查詢要求

本節說明向量查詢的基本結構。 您可以使用 Azure 入口網站、REST API 或 Azure SDK 來制定向量查詢。 如果您要從 2023-07-01-Preview 移轉,則有重大變更。 如需詳細資訊,請參閱 升級至最新的 REST API

2023-11-01 是搜尋 POST穩定 REST API 版本。 此版本支援:

  • vectorQueries 是用於向量搜尋的建構。
  • kind 設定為 , vector 指定查詢是向量陣列。
  • vector 是查詢(文字或影像的向量表示法)。
  • exhaustive (選用) 會在查詢時叫用詳盡的 KNN,即使欄位是針對 HNSW 編製索引也一樣。

在下列範例中,向量是這個字串的表示法:「什麼是 Azure 服務支援全文搜索」。 查詢會 contentVector 以欄位為目標。 查詢會傳回 k 結果。 實際向量有 1536 個內嵌,因此為了可讀性會在此範例中修剪此向量。

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}}
{
    "count": true,
    "select": "title, content, category",
    "vectorQueries": [
        {
            "kind": "vector",
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "exhaustive": true,
            "fields": "contentVector",
            "k": 5
        }
    ]
}

向量查詢回應

在 Azure AI 搜尋中,查詢回應預設包含所有 retrievable 欄位。 不過,在語句中列出搜尋結果,將搜尋結果限製為select字段子retrievable集很常見。

在向量查詢中,請仔細考慮您是否需要在回應中向量字段。 向量欄位無法讀取,因此,如果您要將回應推送至網頁,您應該選擇代表結果的非函式欄位。 例如,如果查詢針對 contentVector執行,您可以改為傳回 content

如果您想要結果中的向量字段,以下是響應結構的範例。 contentVector 是內嵌的字串數位,這裡為了簡潔起見而修剪。 搜尋分數表示相關性。 其他非函式欄位則包含在內容中。

{
    "@odata.count": 3,
    "value": [
        {
            "@search.score": 0.80025613,
            "title": "Azure Search",
            "category": "AI + Machine Learning",
            "contentVector": [
                -0.0018343845,
                0.017952163,
                0.0025753193,
                ...
            ]
        },
        {
            "@search.score": 0.78856903,
            "title": "Azure Application Insights",
            "category": "Management + Governance",
            "contentVector": [
                -0.016821077,
                0.0037742127,
                0.016136652,
                ...
            ]
        },
        {
            "@search.score": 0.78650564,
            "title": "Azure Media Services",
            "category": "Media",
            "contentVector": [
                -0.025449317,
                0.0038463024,
                -0.02488436,
                ...
            ]
        }
    ]
}

重點︰

  • k 會決定傳回的近鄰結果數目,在此案例中為 3。 向量查詢一律會傳回 k 結果,假設至少有 k 檔存在,即使有檔相似度不佳,因為演算法會尋找查詢向量的任何 k 近鄰。

  • @search.score是由向量搜尋演算法所決定。

  • 搜尋結果中的欄位是子句中的所有retrievableselect欄位或欄位。 在向量查詢執行期間,會單獨對向量數據進行比對。 不過,回應可以在索引中包含任何 retrievable 欄位。 由於沒有譯碼向量字段結果的設施,所以包含非向量文字欄位對於其人類可讀值很有説明。

使用篩選條件進行向量查詢

查詢要求可以包含向量查詢和篩選條件運算式。 篩選會套用至 filterable 文字和數值字段,而且適用於根據篩選準則來包含或排除搜尋檔。 雖然向量欄位本身無法篩選,但查詢可以在相同索引中的其他欄位上指定篩選條件。

在較新的 API 版本中,您可以設定篩選模式,以在向量查詢執行之前或之後套用篩選條件。 如需每個模式的比較和以索引大小為基礎的預期效能,請參閱向量查詢中的篩選條件

提示

如果您沒有搭配文字或數值的來源欄位,請檢查可能在中繼資料篩選條件中很有用的文件中繼資料,例如 LastModified 或 CreatedBy 屬性。

2023-11-01 是此 API 的穩定版本。 其中包含:

  • 適用於預先篩選 (預設) 或後置篩選的 vectorFilterMode篩選結果
  • filter 會提供準則。

在下列範例中,向量是此查詢字串的表示法:「哪些 Azure 服務支援全文檢索搜尋」。 查詢會 contentVector 以欄位為目標。 實際向量有 1536 個內嵌,因此為了可讀性會在此範例中修剪此向量。

在搜尋引擎執行向量查詢之前,篩選準則會套用至可篩選的文字欄位(category 在此範例中)。

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}}
{
    "count": true,
    "select": "title, content, category",
    "filter": "category eq 'Databases'",
    "vectorFilterMode": "preFilter",
    "vectorQueries": [
        {
            "kind": "vector",
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "exhaustive": true,
            "fields": "contentVector",
            "k": 5
        }
    ]
}

多個向量欄位

您可以將 「vectorQueries.fields」 屬性設定為多個向量字段。 向量查詢會針對您在清單中提供 fields 的每個向量欄位執行。 查詢多個向量欄位時,請確定每個欄位都包含來自相同內嵌模型的內嵌,而且查詢也會從相同的內嵌模型產生。

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}}
{
    "count": true,
    "select": "title, content, category",
    "vectorQueries": [
        {
            "kind": "vector",
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "exhaustive": true,
            "fields": "contentVector, titleVector",
            "k": 5
        }
    ]
}

多個向量查詢

多查詢向量搜尋會在您的搜尋索引中跨多個向量欄位傳送多個查詢。 下列情況是此查詢要求的常見範例:針對相同模型可以向量化影像和文字內容的多模式向量搜尋,使用 CLIP 這類的模型。

下列查詢範例會同時在 myImageVectormyTextVector 中尋找相似性,但會分別以兩種不同的查詢內嵌方式傳送,而每個查詢內嵌都會以平行方式執行。 此查詢會產生一個使用 倒數排名融合 (RRF) 來評分的結果。

  • vectorQueries 會提供向量查詢的陣列。
  • vector 包含搜尋索引中的影像向量和文字向量。 每個執行個體都是個別的查詢。
  • fields 會指定要設為目標的向量欄位。
  • k 是要包含在結果中的最接近像素相符項目數目。
{
    "count": true,
    "select": "title, content, category",
    "vectorQueries": [
        {
            "kind": "vector",
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "myimagevector",
            "k": 5
        },
        {
            "kind": "vector"
            "vector": [
                -0.002222222,
                0.018708462,
                -0.013770515,
            . . .
            ],
            "fields": "mytextvector",
            "k": 5
        }
    ]
}

搜尋結果將會包含文字和影像的組合,前提是您的搜尋索引包含影像檔案的欄位 (搜尋索引不會儲存影像)。

使用整合向量化進行查詢 (預覽)

本節顯示向量查詢,其會叫用新的 整合向量化 預覽功能,以將文字查詢轉換成向量。 使用 2023-10-01-Preview REST API 或更新的 Beta Azure SDK 套件。

先決條件是搜尋索引已設定 向量化工具並指派給向量欄位。 向量化工具會將連線資訊提供給查詢時所使用的內嵌模型。

查詢會提供文字字串,而不是向量:

  • kind 必須設定為 text
  • text 必須具有文字字串。 其會傳遞至指派給向量欄位的向量化工具。
  • fields 是要搜尋的向量欄位。

以下是查詢時向量化的查詢簡單範例。 文字字串會向量化,然後用來查詢 descriptionVector 欄位。

POST https://{{search-service}}.search.windows.net/indexes/{{index}}/docs/search?api-version=2023-10-01-preview
{
    "select": "title, genre, description",
    "vectorQueries": [
        {
            "kind": "text",
            "text": "mystery novel set in London",
            "fields": "descriptionVector",
            "k": 5
        }
    ]
}

以下是 使用文字查詢整合向量化的混合式查詢 。 此查詢包含多個查詢向量字段、多個非函式欄位、篩選和語意排名。 同樣地,差異在於 kind 向量查詢和 text 字串,而不是 vector

在此範例中,搜尋引擎會在索引中對指派給 descriptionVectorsynopsisVectorauthorBioVector 的向量化工具進行三次向量化呼叫。 產生的向量用來針對各自的欄位擷取文件。 搜尋引擎還對查詢執行 search 關鍵詞搜尋,「倫敦的神秘小說集」。。

POST https://{{search-service}}.search.windows.net/indexes/{{index}}/docs/search?api-version=2023-10-01-preview
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "search":"mystery novel set in London", 
    "searchFields":"description, synopsis", 
    "semanticConfiguration":"my-semantic-config", 
    "queryType":"semantic",
    "select": "title, author, synopsis",
    "filter": "genre eq 'mystery'",
    "vectorFilterMode": "postFilter",
    "vectorQueries": [
        {
            "kind": "text",
            "text": "mystery novel set in London",
            "fields": "descriptionVector, synopsisVector",
            "k": 5
        },
        {
            "kind": "text"
            "text": "living english author",
            "fields": "authorBioVector",
            "k": 5
        }
    ]
}

來自這四個查詢的評分結果都是使用 RRF 排名融合的。 次要語意排名是透過融合式搜尋結果叫用的,但僅限在 searchFields 上,這會提升語意上最符合 "search":"mystery novel set in London" 的結果。

注意

向量化工具是在編製索引和查詢期間使用。 如果不需要索引中的資料區塊化和向量化,您可以略過建立索引子、技能集和資料來源等步驟。 在此倩況下,向量化工具只會在查詢時用來將文字字串轉換成內嵌。

向量查詢回應中排名的結果數量

向量查詢會指定 k 參數,決定結果中傳回多少個相符項目。 搜尋引擎一律會傳回 k 相符項目數目。 如果 k 大於索引中的文件數目,則文件數目會決定可以傳回的上限。

如果熟悉全文檢索搜尋,您就會知道,若索引未包含字詞或片語,則會預期零個結果。 不過,在向量搜尋中,搜尋作業會識別最接近像素,而且即使最接近像素不是那麼類似,此作業仍會一律 k 結果。 因此,您可能會取得無意義或偏離主題查詢的結果,特別是如果您未使用提示來設定界限。 較不相關的結果會有更差的相似度分數,但如果沒有任何更接近的項目,這些結果仍然是「最接近」的向量。 因此,不含有意義結果的回應仍然可以傳回 k 結果,但每個結果的相似度分數將會很低。

包含全文檢索搜尋的混合式方法可以緩解此問題。 另一個緩解方式是在搜尋分數上設定最小閾值,但限於查詢是純單一向量查詢時。 混合式查詢不利於最小閾值,因為 RRF 範圍非常小且不穩定。

影響結果計數的查詢參數包括:

  • 僅限向量查詢的 "k": n 結果
  • 混合式查詢的 "top": n 結果,而這些查詢包含 "search" 參數

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

向量查詢中使用的排名演算法

結果的排名是由下列其中一項計算:

  • 相似度計量
  • 倒數排名融合 (RRF),若有多個搜尋結果集的話。

相似度計量

相似度計量,其指定於僅限向量查詢的索引 vectorSearch 區段中。 有效值為 cosineeuclideandotProduct

Azure OpenAI 內嵌模型會使用餘弦相似度,因此如果您使用 Azure OpenAI 內嵌模型,則 cosine 是建議的計量。 其他支援的排名計量包括 euclideandotProduct

使用 RRF

如果查詢以多個向量字段為目標、平行執行多個向量查詢,或查詢是向量和全文搜索的混合式,且不含 語意排名,則會建立多個集合。

在查詢執行期間,向量查詢只能以一個內部向量索引為目標。 因此,對於多個向量欄位多個向量查詢,搜尋引擎會產生多個查詢,以每個欄位的個別向量索引為目標。 輸出是每個查詢的一組排名結果,這些結果會使用 RRF 融合。 如需詳細資訊,請參閱使用倒數排名融合的相關性評分(RRF)。

下一步

在下一個步驟中,請檢閱 PythonC#JavaScript 中的向量查詢程式碼範例。