查询 AI 搜索索引

可以使用 Python SDK、REST API 或 SQL vector_search() 函数查询 AI 搜索索引。 AI 搜索支持 ANN、混合和全文查询等查询类型,以及分页、筛选条件和重排序,用于优化检索质量。

有关演示如何创建和查询 AI 搜索终结点和索引的示例笔记本,请参阅 AI 搜索示例笔记本。 有关参考信息,请参阅 Python SDK 参考

Databricks AI 搜索以前称为 Databricks 矢量搜索。

安装

若要使用 AI 搜索 SDK,必须在笔记本中安装它。 使用以下代码安装包:

%pip install databricks-ai-search
dbutils.library.restartPython()

然后使用以下命令导入 AISearchClient

from databricks.ai_search.client import AISearchClient

有关身份验证的信息,请参阅 数据保护和身份验证

如何查询 AI 搜索索引

只能使用 Python SDK、REST API 或 SQL vector_search() AI 函数查询 AI 搜索索引。

注意

如果查询索引的用户不是 AI 搜索索引的所有者,则用户必须具有以下 UC 权限:

  • USE CATALOG 在包含 AI 搜索索引的目录上。
  • USE SCHEMA 在包含 AI 搜索索引的架构上。
  • SELECT 在 AI 搜索索引中。

默认查询类型为 ann (近似近邻)。 有关不同检索算法的详细信息,请参阅 检索算法

  • 若要执行混合关键字相似性搜索,请将参数 query_type 设置为 hybrid。 默认情况下,混合搜索包括所有文本元数据列,最多返回 200 个结果。
  • 若要在查询中使用重新调用程序,请参阅 在查询中使用重新调用程序

Important

全文搜索可用作 beta 功能。 若要执行全文搜索,请将参数 query_type 设置为 FULL_TEXT. 使用全文搜索,可以基于关键字匹配最多检索 200 个结果,而无需使用矢量嵌入。 标准终结点和存储优化终结点都支持全文查询。 在存储优化终结点上,还可以创建专用全文搜索索引,而无需嵌入。 请参阅创建全文搜索索引(Beta)。 若要搜索所选文本列、排序结果或返回全文查询和混合查询的聚合计数,请参阅“搜索所选文本列”、“排序结果”和“返回聚合”(Beta)。

Python SDK 标准终结点

有关详细信息,请参阅 Python SDK 参考

# Delta Sync Index with embeddings computed by Databricks
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "field2"],
    num_results=2
    )

# Delta Sync Index using hybrid search, with embeddings computed by Databricks
results3 = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "field2"],
    num_results=2,
    query_type="hybrid"
    )

# Delta Sync Index using full-text search (Beta)
results4 = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "field2"],
    num_results=2,
    query_type="FULL_TEXT"
    )

# Delta Sync Index with pre-calculated embeddings
results2 = index.similarity_search(
    query_vector=[0.9] * 1024,
    columns=["id", "text"],
    num_results=2
    )

Python SDK 存储优化端点

有关详细信息,请参阅 Python SDK 参考

现有筛选器接口已重新设计为存储优化的 AI 搜索索引,以采用更类似于 SQL 的筛选器字符串,而不是标准 AI 搜索终结点中使用的筛选器字典。

client = AISearchClient()
index = client.get_index(index_name="vector_search_demo.vector_search.en_wiki_index")

# similarity search with query vector
results = index.similarity_search(
    query_vector=[0.2, 0.33, 0.19, 0.52],
    columns=["id", "text"],
    num_results=2
)

# similarity search with query vector and filter string
results = index.similarity_search(
    query_vector=[0.2, 0.33, 0.19, 0.52],
    columns=["id", "text"],
    # this is a single filter string similar to SQL WHERE clause syntax
    filters="language = 'en' AND country = 'us'",
    num_results=2
)

REST API

请参阅 REST API 参考文档: POST /api/2.0/vector-search/indexes/{index_name}/query

对于生产应用程序,Databricks 建议使用服务主体而不是个人访问令牌。 除了增强安全性和访问管理之外,使用服务主体还可以将每个查询的性能提高最多至 100 毫秒。

下面的代码示例演示如何使用服务主体查询索引。

export SP_CLIENT_ID=...
export SP_CLIENT_SECRET=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...
export WORKSPACE_ID=...

# Set authorization details to generate OAuth token
export AUTHORIZATION_DETAILS='{"type":"unity_catalog_permission","securable_type":"table","securable_object_name":"'"$INDEX_NAME"'","operation": "ReadVectorIndex"}'
# If you are using an route_optimized embedding model endpoint, then you need to have additional authorization details to invoke the serving endpoint
# export EMBEDDING_MODEL_SERVING_ENDPOINT_ID=...
# export AUTHORIZATION_DETAILS="$AUTHORIZATION_DETAILS"',{"type":"workspace_permission","object_type":"serving-endpoints","object_path":"/serving-endpoints/'"$EMBEDDING_MODEL_SERVING_ENDPOINT_ID"'","actions": ["query_inference_endpoint"]}'

# Generate OAuth token
export TOKEN=$(curl -X POST  --url $WORKSPACE_URL/oidc/v1/token -u "$SP_CLIENT_ID:$SP_CLIENT_SECRET" --data 'grant_type=client_credentials' --data 'scope=all-apis' --data-urlencode 'authorization_details=['"$AUTHORIZATION_DETAILS"']' | jq .access_token | tr -d '"')

# Get index URL
export INDEX_URL=$(curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME | jq -r '.status.index_url' | tr -d '"')

# Query AI Search index.
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url https://$INDEX_URL/query --data '{"num_results": 3, "query_vector": [...], "columns": [...], "debug_level": 1}'

# Query AI Search index.
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url https://$INDEX_URL/query --data '{"num_results": 3, "query_text": "...", "columns": [...], "debug_level": 1}'

下面的代码示例演示如何使用个人访问令牌(PAT)查询索引。

export TOKEN=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...

# Query AI Search index with `query_vector`
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query --data '{"num_results": 3, "query_vector": [...], "columns": [...], "debug_level": 1}'

# Query AI Search index with `query_text`
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query --data '{"num_results": 3, "query_text": "...", "columns": [...], "debug_level": 1}'

SQL

Important

vector_search() AI 函数处于公共预览阶段

若要使用此 AI 函数,请参阅 vector_search 函数

Pagination

当查询请求超过 1,000 个结果时,结果将自动以最多 1,000 个页面返回。 单个查询可以跨所有页面返回的最大结果数为 10,000。 标准终结点和存储优化终结点都支持分页。

分页适用于所有查询类型。

Python SDK

Python SDK 以透明方式处理分页。 当设置为 num_results 大于 1,000 的值时,SDK 会自动检索所有页面并返回完整的结果集。 无需其他代码。

# The SDK automatically paginates and returns all 5000 results
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    num_results=5000
)

REST API

直接使用 REST API 时,必须手动处理分页。 如果有更多结果可用,响应将包括一个 next_page_token 字段。 若要检索下一页结果,请将此令牌传递给查询下一页终结点。

请参阅 REST API 参考文档: POST /api/2.0/vector-search/indexes/{index_name}/query-next-page

export TOKEN=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...

# Initial query - if num_results exceeds 1000, the response includes next_page_token
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
  --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query \
  --data '{"num_results": 5000, "query_text": "...", "columns": ["id", "text"]}'

# Use next_page_token from the response to get the next page
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" \
  --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query-next-page \
  --data '{"page_token": "<next_page_token from previous response>"}'

继续调用查询下一页终结点,每次使用响应中的 next_page_token,直到令牌为空或不存在,这表示所有结果均已返回。

对查询使用筛选器

查询可以根据 Delta 表中的任何列定义筛选器。 similarity_search 仅返回与指定筛选器匹配的行。

下表列出了支持的筛选器。

注意

对于存储优化终结点,结果将被过度提取。 如果将num_results设置为k,则将获取超过k的结果,并对获取的结果应用筛选器。 即使数据集中有与筛选条件匹配的结果,如果这些文档的分数不在顶部,也可能不会返回任何结果。

筛选器运算符 Behavior 示例
NOT 标准:否定筛选器。 密钥必须以“NOT”结尾。 例如,值为“red”的“color NOT”与颜色不为红色的文档匹配。
存储优化:请参阅 !=(感叹号等于号)运算符
标准{"id NOT": 2}{“color NOT”: “red”}
存储优化"id != 2" "color != 'red'"
< 标准:检查字段值是否小于筛选器值。 键必须以 < 结尾。 例如, price < 值为 200 与价格小于 200 的文档匹配。
存储优化:请参阅 <(小于号)运算符
标准{"id <": 200}
存储优化"id < 200"
<= 标准:检查字段值是否小于或等于筛选器值。 键必须以 <= 结尾。 例如, price <= 如果值为 200,则匹配价格小于或等于 200 的文档。
存储优化:请参阅 <=(小于等于号)运算符
标准{"id <=": 200}
存储优化"id <= 200"
> 标准:检查字段值是否大于筛选器值。 键必须以 \> 结尾。 例如, price \> 值为 200 与价格大于 200 的文档匹配。
存储优化:请参阅 >(大于号)运算符
标准{"id >": 200}
存储优化"id > 200"
>= 标准:检查字段值是否大于或等于筛选器值。 键必须以 \>= 结尾。 例如, price \>= 如果值为 200,则匹配价格大于或等于 200 的文档。
存储优化:请参阅 >=(大于等于号)运算符
标准{"id >=": 200}
存储优化"id >= 200"
OR 标准:检查字段值是否与任何筛选器值匹配。 密钥必须包含 OR 以分隔多个子项。 例如,值为 color1 OR color2["red", "blue"]color1redcolor2blue 的文档匹配。
存储优化:请参阅 or 运算符
标准{"color1 OR color2": ["red", "blue"]}
存储优化"color1 = 'red' OR color2 = 'blue'"
LIKE 标准:匹配字符串中空格分隔的标记。
存储优化:请参阅 like 运算符
请参阅 关于 LIKE 用法的说明
未指定筛选器运算符 标准:筛选检查是否完全匹配。 如果指定了多个值,则它与任何值匹配。
存储优化:请参阅 =(等号)运算符in 谓词
标准{"id": 200}{"id": [200, 300]}
存储优化"id = 200""id IN (200, 300)"
to_timestamp (仅限存储优化终结点) 存储优化:根据时间戳进行筛选。 请参见 to_timestamp 函数 存储优化"date > TO_TIMESTAMP('1995-01-01')"

有关用法的说明 LIKE

LIKE 标准终结点的示例

{"column LIKE": "apple"}:匹配字符串“apple”和“apple pear”,但不匹配“菠萝”。 请注意,它不会与“菠萝”匹配,尽管它包含子字符串“apple”,因为它在空格分隔的标记上查找完全匹配,例如“苹果 梨”。

{"column NOT LIKE": "apple"} 则相反。 它匹配“菠萝”和“梨”,但不匹配“苹果”或“苹果梨”。

LIKE 存储优化终结点的示例

Format Matches
"column LIKE 'apple'" 等效于 = 运算符。 仅返回完全匹配项。
"column LIKE 'apple%'" 返回前缀匹配 apple的行,例如 applepie
"column LIKE '%apple'" 返回后缀匹配 apple的行,例如 pineapple
"column LIKE '%apple%'" 返回具有匹配 apple的子字符串的行,例如 pineapplecake

代码示例

Python SDK 标准终结点
# Match rows where `title` exactly matches `Athena` or `Ares`
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    filters={"title": ["Ares", "Athena"]},
    num_results=2
    )

# Match rows where `title` or `id` exactly matches `Athena` or `Ares`
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    filters={"title OR id": ["Ares", "Athena"]},
    num_results=2
    )

# Match only rows where `title` is not `Hercules`
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    filters={"title NOT": "Hercules"},
    num_results=2
    )
Python SDK 存储优化端点
# Match rows where `title` exactly matches `Athena` or `Ares`
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    filters='title IN ("Ares", "Athena")',
    num_results=2
    )

# Match rows where `title` or `id` exactly matches `Athena` or `Ares`
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    filters='title = "Ares" OR id = "Athena"',
    num_results=2
    )

# Match only rows where `title` is not `Hercules`
results = index.similarity_search(
    query_text="Greek myths",
    columns=["id", "text"],
    filters='title != "Hercules"',
    num_results=2
    )
REST API

请参阅 POST /api/2.0/vector-search/indexes/{index_name}/query

搜索所选文本列、排序结果和返回聚合 (Beta)

Important

搜索所选文本列、排序以及返回聚合结果的选项属于 矢量搜索:全文搜索 测试版的一部分。 若要使用 query_columnssort_columnsfacets,请启用 Vector Search: Full-Text Search 功能的公开预览版。 请联系帐户团队或查看 Manage Azure Databricks 预览版以启用预览。

使用这些选项搜索所选文本字段、应用显式结果顺序或返回匹配结果的聚合。

全文查询和混合查询支持这些选项。 它们不受 ANN 查询支持。

搜索所选文本列

使用 query_columns 仅搜索指定的文本列。 如果省略它,查询将搜索所有文本列。

query_columns=["title", "text"]

对结果进行排序

用于 sort_columns 按列值而不是默认相关性顺序对结果进行排序。 条目使用格式 "<column> ASC""<column> DESC".

sort_columns=["rating DESC", "publication_year DESC"]

返回聚合结果

使用 facets 返回匹配结果的聚合计数。

值方面按列中的非重复值(如语言或类别)对匹配结果进行计数。 TOP 限制返回的值数,如果省略,则默认值为 10。

facets=["language TOP 5"]

示例响应:

{
  "facet_result": {
    "facet_array": [
      ["language", "en", 28],
      ["language", "el", 14]
    ]
  }
}

数值存储桶计算属于指定数值范围(例如发布年份或价格)的匹配结果。 桶的边界值是包含在内的。

facets=["publication_year BUCKETS [[1900,1949],[1950,1999],[2000,2025]]"]

示例响应:

{
  "facet_result": {
    "facet_array": [
      ["publication_year", "[1900,1949]", 8],
      ["publication_year", "[1950,1999]", 14],
      ["publication_year", "[2000,2025]", 20]
    ]
  }
}

对于全文查询,AI 搜索会计算与查询和筛选器匹配的所有结果的聚合,而不仅仅是响应中返回的行。 对于混合查询,AI 搜索将排序和聚合应用于混合搜索生成的有限候选集,而不是应用于索引中的每个行。

有关 REST API 请求字段和响应架构,请参阅 POST /api/2.0/vector-search/indexes/{index_name}/query

在查询中使用重排序器

代理性能取决于检索查询的最相关信息。 重排序是一种技术,通过对检索到的文档进行评估,识别出在语义上最相关的文档,以提高检索质量。 Databricks 开发了一个基于研究的复合 AI 系统,用于识别这些文档。 还可以指定包含您希望重排序器用来评估每个文档相关性时提供额外上下文的元数据的列。

重新排序会产生较小的延迟,但可以显著提高检索质量和代理性能。 Databricks 建议对 RAG 代理的任何用例尝试重新排序。

AI 搜索重新调整器是一种 Databricks 指定服务 ,它使用 Databricks Geos 管理数据驻留。 位于美国和欧盟以外的客户可能需要启用跨地域处理才能使用重排器。

本节中的示例演示如何使用 AI 搜索重新调整器。 在使用重新排序器时,需分别设置要返回的列(columns)和用于重新排序的元数据列(columns_to_rerank)。 num_results 是要返回的最终结果数。 这不会影响用于重新排序的结果数。

查询调试消息包含有关重新排序步骤所用时间的信息。 例如:

'debug_info': {'response_time': 1647.0, 'ann_time': 29.0, 'reranker_time': 1573.0}

如果重新排序器调用失败,该信息将包含在调试消息中:

'debug_info': {'response_time': 587.0, 'ann_time': 331.0, 'reranker_time': 246.0, 'warnings': [{'status_code': 'RERANKER_TEMPORARILY_UNAVAILABLE', 'message': 'The reranker is temporarily unavailable. Results returned have not been processed by the reranker. Please try again later for reranked results.'}]}

注意

列在 columns_to_rerank 列表中的顺序非常重要。 重新计算按列列出的顺序获取列,并且只考虑它找到的前 2000 个字符。

Python SDK

# Install the most recent version.
# Databricks SDK version 0.57 or above is required to use the reranker.
%pip install databricks-ai-search --force-reinstall
dbutils.library.restartPython()
from databricks.ai_search.reranker import DatabricksReranker

results = index.similarity_search(
    query_text = "How to create an AI Search index",
    columns = ["id", "text", "parent_doc_summary", "date"],
    num_results = 10,
    query_type = "hybrid",
    reranker=DatabricksReranker(columns_to_rerank=["text", "parent_doc_summary", "other_column"])
    )

REST API

若要确保获得延迟信息,请将参数 debug_level 设置为至少 1。

export TOKEN=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...

curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query --data '{"num_results": 10, "query_text": "How to create an AI Search index", "columns": ["id", "text", "parent_doc_summary", "date"], "reranker": {"model": "databricks_reranker",
             "parameters": {
               "columns_to_rerank":
                 ["text", "parent_doc_summary"]
              }
             },
"debug_level": 1}'

点查找

若要执行点查找,请对任何主键列使用筛选器。

检索算法

本部分介绍不同的检索算法或查询类型,以及何时可以使用每个算法。 使用 query_type 参数指定要使用的检索算法。 若要自动比较索引的不同算法的性能,请参阅 评估 AI 搜索检索质量

Strategy 工作原理 最适用于
ANN (近似近邻) 使用矢量嵌入进行搜索,以在语义上查找类似的文档。 概念和语义查询,其中意义比确切的措辞更重要。
Full-text 与确切字词匹配的关键字搜索。 使用特定术语、专有名词、产品ID或技术术语进行查询。
混合 使用递归排序融合(RRF)将 ANN 和全文结果合并。 通用检索。 对于大多数用例,推荐的起始点。
混合 + 再排序器 运行混合搜索,然后使用跨编码器重新评分器模型对结果重新评分。 延迟允许时精度更高(每个查询额外 1.5 秒)。

ANN 搜索将查询转换为矢量嵌入,并查找嵌入内容最相似的文档。 这对于理解 意义是有效的。 例如,类似于“如何修复断管道”的查询与管道相关文档匹配,即使它们不包含这些确切的单词也是如此。

  • ANN 性能良好时:查询的概念性、对话性或使用与文档不同的词汇。
  • ANN 性能可能会不佳:查询依赖于确切的关键字、专有名词或领域特定的术语,而这些可能无法被嵌入技术精确捕获。

全文搜索匹配包含查询词的文档。 全文搜索具有很高的精度。 当用户搜索特定名称、代码或技术术语时,关键字匹配可以找到矢量搜索可能错过的确切匹配。

使用全文或混合查询选项搜索所选文本列、排序结果或返回聚合计数。 请参阅“搜索所选文本列”、“排序结果”和“返回聚合”(Beta)。

  • 全文性能良好时:查询包含特定标识符、产品名称、错误代码或特定于域的术语。
  • 全文检索可能出现性能不佳的情况:查询的措辞与文档不同,或采用同义词或改述。

混合搜索同时运行人工神经网络(ANN)和全文搜索,然后使用倒数排名融合(RRF)合并结果。 这结合了矢量搜索的语义理解与关键字匹配的精度。

  • 混合搜索性能良好时:查询工作负载是概念查询和关键字密集型查询的组合。 混合是最可靠的常规用途策略。

重排序器

重新排序器是可以应用于任何策略之上的可选第二步。 初始检索后,跨编码器模型会重新评估查询上下文中的每个结果,从而生成更准确的相关性排序。

重排器通常将质量提高约 10%,但会增加延迟。 它适用于质量最重要的应用程序,例如 RAG 聊天机器人,但可能不太适合高吞吐量、低延迟的搜索应用程序。