创建矢量存储
在 Azure AI 搜索中,矢量存储具有定义矢量和非矢量字段的索引架构、用于创建嵌入空间的算法的矢量配置,以及查询请求中使用的矢量字段定义的设置。 创建索引 API 将创建矢量存储。
请按照以下步骤为矢量数据编制索引:
- 定义具有一个或多个矢量配置的架构,该配置可指定索引和搜索所用的算法
- 添加一个或多个矢量字段
- 加载预矢量化的数据作为单独的步骤,或在索引编制期间使用集成矢量化(预览版)进行数据分块和编码。
本文适用于正式版而非预览版的矢量搜索,正式版假设应用程序代码调用外部资源来进行分块和编码。
注意
需要 2023-07-01-preview 迁移指南? 请参阅升级 REST API。
先决条件
在任何区域内、任何层级上的 Azure AI 搜索。 大多数现有服务都支持矢量搜索。 对于在 2019 年 1 月之前创建的服务,有一小部分服务不支持矢量搜索。 如果包含矢量字段的索引的创建或更新失败,则这是一个指示器。 在这种情况下,必须创建新服务。
源文档中现有的矢量嵌入。 Azure AI 搜索在 Azure SDK 和 REST API 的正式发布版本中不生成矢量。 我们建议使用 Azure OpenAI 嵌入模型,但你可以使用任何模型进行矢量化。 有关详细信息,请参阅生成嵌入。
应该了解用于创建嵌入的模型的维度限制,以及如何计算相似性。 在 Azure OpenAI 中,对于 text-embedding-ada-002,数值矢量的长度为 1536。 相似性是使用
cosine
计算的。 有效值为 2 到 3072 维度。你应该知道如何创建索引。 架构必须包含文档键的字段、要搜索或筛选的其他字段,以及索引编制和查询期间所需行为的其他配置。
准备为文档编制索引
在编制索引之前,请汇编一个包含矢量和非矢量数据字段的文档有效负载。 文档结构必须符合索引架构。
确保文档:
提供用于唯一标识每个文档的字段或元数据属性。 所有搜索索引都需要文档键。 若要满足文档键要求,源文档必须包含一个可以在索引中唯一标识它的字段或属性。 此源字段必须映射到搜索索引中类型为
Edm.String
和key=true
的索引字段。在源字段中提供矢量数据(单精度浮点数的数组)。
矢量字段包含嵌入模型生成的数字数据,每个字段包含一个嵌入。 我们建议使用 Azure OpenAI 中的嵌入模型,例如用于文本文档的 text-embedding-ada-002 或用于图像的图像检索 REST API。 仅支持索引顶级向量字段:目前不支持向量子字段。
为查询响应以及在同一请求中包含全文搜索的混合查询方案提供其他含人类可读的字母数字内容的字段。
搜索索引应包含你想要支持的所有查询方案的字段和内容。 假设你想要搜索或筛选产品名称、版本、元数据或地址。 在这种情况下,相似性搜索并不是特别有用。 关键字搜索、地理搜索或筛选器是更好的选择。 包含矢量和非矢量数据综合字段集合的搜索索引为查询构造和响应组合提供了最大的灵活性。
本文的加载矢量数据部分提供了包含矢量和非矢量字段的文档有效负载的简短示例。
添加矢量搜索配置
矢量配置指定在索引编制过程中使用的矢量搜索算法和参数,以便在矢量节点之间创建“最近邻域”信息:
- 分层可导航小世界 (HNSW)
- 穷举 KNN
如果在字段中选择 HNSW,则可以在查询时选择穷举 KNN。 但另一个方向不起作用:如果选择详尽,则以后无法请求 HNSW 搜索,因为实现近似搜索的额外数据结构不存在。
需要预览版到稳定版的迁移指南? 请参阅升级 REST API 了解相关步骤。
REST API 版本 2023-11-01 支持包含以下设置的矢量配置:
vectorSearch
算法、hnsw
和exhaustiveKnn
最近的邻域,含索引和评分的参数。- 用于对算法配置进行多种组合的
vectorProfiles
。
请务必制定矢量化内容的策略。 稳定版不提供用于内置嵌入的矢量化器。
使用创建或更新索引 API 创建索引。
在索引中添加
vectorSearch
节,以指定用于创建嵌入空间的搜索算法。"vectorSearch": { "algorithms": [ { "name": "my-hnsw-config-1", "kind": "hnsw", "hnswParameters": { "m": 4, "efConstruction": 400, "efSearch": 500, "metric": "cosine" } }, { "name": "my-hnsw-config-2", "kind": "hnsw", "hnswParameters": { "m": 8, "efConstruction": 800, "efSearch": 800, "metric": "cosine" } }, { "name": "my-eknn-config", "kind": "exhaustiveKnn", "exhaustiveKnnParameters": { "metric": "cosine" } } ], "profiles": [ { "name": "my-default-vector-profile", "algorithm": "my-hnsw-config-2" } ] }
要点:
- 配置的名称。 该名称在索引中必须唯一。
profiles
添加一个抽象层以容纳更丰富的定义。 配置文件在vectorSearch
中定义,然后在每个矢量字段中按名称引用。"hnsw"
和"exhaustiveKnn"
是近似最近邻域 (ANN) 算法,用于在索引编制期间组织矢量内容。"m"
(双向链接计数)默认值为 4。 范围为 4 到 10。 较低的值应在结果中返回较少的干扰数据。"efConstruction"
默认值为 400。 范围为 100 到 1,000。 它是索引编制期间使用的最近邻域数量。"efSearch"
默认值为 500。 范围为 100 到 1,000。 它是搜索期间使用的最近邻域数量。- 如果使用的是 Azure OpenAI,则
"metric"
应为“cosine”,否则请使用与你正在使用的嵌入模型关联的相似性指标。 支持的值为cosine
、dotProduct
、euclidean
。
将矢量字段添加到字段集合
字段集合必须包含文档键字段、矢量字段以及混合搜索方案所需的任何其他字段。
矢量字段的类型为 Collection(Edm.Single)
和单精度浮点值。 此类型的字段还具有 dimensions
属性并指定矢量配置。
如果你只想使用正式发布的功能,请使用此版本。
使用创建或更新索引创建索引。
使用以下属性定义矢量字段。 可为每个字段存储一个生成的嵌入。 对于每个矢量字段:
type
必须为Collection(Edm.Single)
。dimensions
是嵌入模型生成的维度数。 对于 text-embedding-ada-002,它是 1536。vectorSearchProfile
是在索引中其他位置定义的配置文件的名称。searchable
必须为 true。retrievable
可以为 true 或 false。 True 以纯文本形式返回原始矢量(1536 个)并消耗存储空间。 如果你要将矢量结果传递给下游应用,请设置为 true。filterable
、facetable
、sortable
必须为 false。
如果要在向量查询调用预筛选或后期筛选,请将可筛选的非函数字段添加到集合,例如
filterable
设置为 true 的“title”。添加其他字段用于定义你要编制索引的文本内容的主旨和结构。 至少需要一个文档键。
还应该添加在查询或其响应中有用的字段。 以下示例显示了标题和内容(等效于矢量)的矢量字段(“titleVector”、“contentVector”)。 它还提供了等效文本内容的字段(“title”、“content”),可用于在搜索结果中进行排序、筛选和读取。
以下示例显示了字段集合:
PUT https://my-search-service.search.azure.cn/indexes/my-index?api-version=2023-11-01&allowIndexDowntime=true Content-Type: application/json api-key: {{admin-api-key}} { "name": "{{index-name}}", "fields": [ { "name": "id", "type": "Edm.String", "key": true, "filterable": true }, { "name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "retrievable": true }, { "name": "titleVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "my-default-vector-profile" }, { "name": "content", "type": "Edm.String", "searchable": true, "retrievable": true }, { "name": "contentVector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "my-default-vector-profile" } ], "vectorSearch": { "algorithms": [ { "name": "my-hnsw-config-1", "kind": "hnsw", "hnswParameters": { "m": 4, "efConstruction": 400, "efSearch": 500, "metric": "cosine" } } ], "profiles": [ { "name": "my-default-vector-profile", "algorithm": "my-hnsw-config-1" } ] } }
加载要编制索引的矢量数据
你提供的要编制索引的内容必须符合索引架构,并包含文档键的唯一字符串值。 预矢量化数据将加载到一个或多个矢量字段中,这些矢量字段可与包含字母数字内容的其他字段共存。
可以使用推送或拉取方法进行数据引入。
使用为文档编制索引 (2023-11-01)、为文档编制索引 (2023-10-01-Preview) 或添加、更新或删除文档 (2023- 07-01-Preview) 推送包含矢量数据的文档。
POST https://{{search-service-name}}.search.azure.cn/indexes/{{index-name}}/docs/index?api-version=2023-11-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
"value": [
{
"id": "1",
"title": "Azure App Service",
"content": "Azure App Service is a fully managed platform for building, deploying, and scaling web apps. You can host web apps, mobile app backends, and RESTful APIs. It supports a variety of programming languages and frameworks, such as .NET, Java, Node.js, Python, and PHP. The service offers built-in auto-scaling and load balancing capabilities. It also provides integration with other Azure services, such as Azure DevOps, GitHub, and Bitbucket.",
"category": "Web",
"titleVector": [
-0.02250031754374504,
. . .
],
"contentVector": [
-0.024740582332015038,
. . .
],
"@search.action": "upload"
},
{
"id": "2",
"title": "Azure Functions",
"content": "Azure Functions is a serverless compute service that enables you to run code on-demand without having to manage infrastructure. It allows you to build and deploy event-driven applications that automatically scale with your workload. Functions support various languages, including C#, F#, Node.js, Python, and Java. It offers a variety of triggers and bindings to integrate with other Azure services and external services. You only pay for the compute time you consume.",
"category": "Compute",
"titleVector": [
-0.020159931853413582,
. . .
],
"contentVector": [
-0.02780858241021633,,
. . .
],
"@search.action": "upload"
}
. . .
]
}
检查矢量内容的索引
要进行验证,可以使用 Azure 门户中的搜索资源管理器或 REST API 调用来查询索引。 由于 Azure AI 搜索无法将矢量转换为人类可读的文本,因此请尝试从同一文档中返回提供匹配证据的字段。 例如,如果矢量查询针对“titleVector”字段,则你可以为搜索结果选择“title”。
必须将字段的属性设置为“retrievable”才能将其包含在结果中。
可以使用搜索资源管理器来查询索引。 搜索资源管理器有两个视图:查询视图(默认)和 JSON 视图。
使用 JSON 视图可以进行矢量查询,粘贴要执行的矢量查询的 JSON 定义。
使用默认查询视图可以快速确认索引是否包含矢量。 查询视图用于全文搜索。 尽管无法将其用于矢量查询,但可以发送空搜索 (
search=*
) 来检查内容。 所有字段(包括矢量字段)的内容均以纯文本形式返回。
更新矢量存储
若要更新矢量存储,请修改架构,并在必要时重新加载文档以填充新字段。 用于架构更新的 API 包括创建或更新索引 (REST)、Azure SDK for .NET 中的 CreateOrUpdateIndex、Azure SDK for Python 中的create_or_update_index,以及其他 Azure SDK 中的类似方法。
有关更新索引的标准指南,请参见删除并重新生成索引。
要点包括:
更新和删除现有字段通常需要进行删除并重新生成。
但是,你可以通过以下修改来更新现有架构,而无需重新生成:
- 向字段集合添加新字段。
- 添加新的矢量配置,该配置已分配给新字段而不是尚未矢量化的现有字段。
- 更改现有字段上的“可检索”(值为 true 或 false)。 矢量字段必须是可搜索和可检索的,但如果希望在无法删除和重新生成的情况下禁用对矢量字段的访问,则可以将“可检索”设置为 false。
后续步骤
接下来,我们建议在搜索索引中查询矢量数据。
azure-search-vector 存储库中的代码示例演示了包括架构定义、矢量化、索引和查询的端到端工作流。
有可参阅的 Python、C# 和 JavaScript 的演示代码。