向量与全文检索解析:AI Agent 为何两者都需要
DataHot 速览
文章解释向量检索与全文检索的差异:全文检索用倒排索引和 BM25 匹配字面词,向量检索比较嵌入语义,二者互补。混合检索并行运行并合并结果,可用 RRF 按排名融合,避免分数不可比。面向 AI Agent 的检索还依赖租户过滤、权限和新鲜事务数据;统一 SQL 与向量数据可减少索引同步任务。文中称 Dify.AI 迁移到 TiDB Cloud 后基础设施成本降低 80%。
为什么值得关注:帮助数据从业者理解 AI Agent 混合检索的召回机制、RRF 排序融合,以及权限、数据新鲜度和 SQL+向量统一架构的工程取舍。
本文目录 28 节
- 关键要点
- 什么是向量搜索和全文搜索?
- 全文搜索找到你实际输入的词语
- 向量搜索找到超出确切措辞的含义
- 为什么向量搜索和全文搜索一起使用效果更好
- 嵌入的不足之处
- 关键词匹配的不足之处
- 为什么混合检索才是真正的答案
- AI 智能体检索在嵌入之外真正需要什么
- 面向智能体的检索不只是文档相似度
- 元数据过滤器和 SQL 约束会改变结果集
- 新鲜的操作数据与语义召回同样重要
- 混合搜索在 SQL 检索栈中如何工作
- BM25 和向量相似度扮演不同的角色
- 融合与重排序可提升最终相关性
- SQL 将连接和过滤保留在同一条检索路径中
- 团队对向量搜索和全文搜索的常见误解
- 检查清单:你的检索栈缺少搜索信号的迹象
- TiDB 在混合检索栈中的定位
- 为什么统一检索对生产级 AI 应用很重要
- TiDB 连接搜索、事务和新鲜的应用数据
- TiDB 如何在不增加数据蔓延的情况下支持 AI 检索
- 向量搜索和全文搜索常见问题
- 向量搜索比全文搜索更好吗?
- AI 智能体何时应使用混合搜索?
- 全文搜索中的 BM25 是什么?
- 什么是倒数排名融合?
- AI 智能体检索需要 SQL 吗?
译文
AI 逐段翻译关键要点
- 混合检索能捕获嵌入模型遗漏的标识符,以及关键词搜索遗漏的改写问题。
- 倒数排名融合按排名合并关键词和语义结果,无需协调不兼容的分数。
- 智能体检索不仅依赖文档相似度,同样依赖租户过滤器、权限和最新的交易数据。
- 统一 SQL 和向量数据可省去索引同步任务;Dify.AI 通过整合到 TiDB Cloud 将基础设施成本降低了 80%。
向 AI 支持智能体询问错误 E-4012,它可能会自信地给出关于 E-4021 的答案。这两个代码的嵌入几乎重叠在一起,因此智能体拉取了错误的运行手册,而日志中没有任何内容表明检索失败。
向量搜索和全文搜索是两种不同的信息检索方式。全文搜索将查询中的字面词项与倒排索引进行匹配,并使用 BM25 等评分函数对结果排序。向量搜索比较嵌入(即含义的数值表示)来找到用不同措辞表达相似内容的内容。
两者各有所短,也各有所长。混合检索同时运行两者并合并结果,这为 AI 智能体提供了比单独使用嵌入更好的召回率。本指南解释每种方法的工作原理、排名融合如何将它们组合起来,以及智能体检索在搜索之外还需要什么。
什么是向量搜索和全文搜索?
全文搜索检索包含查询词项的文档。向量搜索检索含义与查询接近的文档。两者都返回排序列表,但对于什么算作匹配存在分歧。
全文搜索找到你实际输入的词语
全文搜索将词元存储在倒排索引中,这是一个从每个词项到包含它的文档的查找表。BM25 是最常见的评分函数,它奖励在文档中频繁出现的词项,降低在几乎每个文档中都出现的词项的权重,并根据长度进行调整,这样一篇 10,000 词的页面不会仅仅因为长而获胜。
当查询是标识符时,关键词匹配胜出。开发者粘贴 ERR_CONN_REFUSED 或买家搜索 SKU TX-4471-B 时,想要的是包含该字符串的文档,而 BM25 会将它们排在最前面。
向量搜索找到超出确切措辞的含义
向量搜索将每个文档块通过嵌入模型运行,该模型将文本转换为一组几百到几千个数字。含义相似的文本彼此靠近。系统以相同方式嵌入查询,数据库通过余弦或欧几里得距离返回最近的向量。HNSW 等近似最近邻索引使其在大规模下保持快速。
当用户和文档使用不同词语时,语义相似度胜出。“我这个月被扣了两次费”与一篇题为“重复交易的退款”的帮助文章没有任何有用的词项重合,但嵌入模型却将它们放在一起。
因此这两种方法回答的是不同的问题。全文搜索问的是哪些文档包含这些词项。向量搜索问的是哪些文档表达的意思与此类似。
为什么向量搜索和全文搜索一起使用效果更好
向量搜索和全文搜索一起使用效果更好,因为各自能捕获对方遗漏的查询。关键词搜索处理标识符,嵌入处理改写的意图,将它们合并可为智能体提供一个覆盖两者的候选集。这一点很重要,因为检索失败很少看起来像错误。系统返回一些看似合理的内容,模型在其上写出流畅的答案,直到客户发现之前没人注意到。
嵌入的不足之处
嵌入模型被训练来捕捉含义,而标识符所承载的含义很少。像 E-4012 和 E-4021 这样的代码,或仅相差一个字符的零件编号,通常会产生几乎相同的向量。政策语言也有同样的问题。“30 天退款窗口”和“90 天退款窗口”在语义上接近,但在合同上截然不同。
内部产品名称会导致相关的失败。如果嵌入模型在训练中从未见过某个词项,它会将其映射到恰好相似的任何内容上。
关键词匹配的不足之处
BM25 只知道它看到的词语。输入“我怎样才能停止被收费”的用户会错过题为“取消订阅”的文章,除非有人手工维护同义词列表。对话式查询——也就是人们与智能体交谈的方式——也会用“我想知道是否”之类的填充词稀释关键词分数。
为什么混合检索才是真正的答案
混合搜索针对同一语料库运行关键词查询和向量查询,然后合并两个排序列表。既包含错误代码又描述正确症状的文档会上升到顶部。只匹配一个信号的文档仍会进入候选集,因此两个盲点都不致命。
对智能体而言,这一理由比对人类更充分。浏览结果的人可以发现糟糕的结果并重新表述。智能体在一个任务中可能发出数十次检索调用,混合标识符查找和开放式问题,并且很少知道某次调用返回了错误结果。PingCAP 对向量搜索和混合搜索的演练展示了一个可用的实现。
AI 智能体检索在嵌入之外真正需要什么
AI 智能体检索需要语义召回、关键词匹配和关系过滤,而且往往是在同一个请求中。智能体还依赖权限和几秒前刚刚更改的运营数据,而这仅靠文档相似度无法提供。
面向智能体的检索不只是文档相似度
RAG 聊天机器人从一组文档中回答问题。智能体则是在做工作。在回复工单之前,支持智能体可能需要帮助文章、客户的套餐、他们最近的工单,以及它在前两步运行的诊断工具的输出。只有第一项是相似度搜索。其余是表中的结构化状态。
内部 copilot 看起来都很相似。当一位工程师询问为什么结账服务昨晚把 on-call 团队叫醒时,他需要事件记录(语义)、确切的告警名称(关键词),以及在那个时间窗口内部署了哪些版本(对时间戳的 SQL 查询)。
元数据过滤器和 SQL 约束会改变结果集
过滤器决定哪些文档有资格被纳入。在多租户 SaaS 产品中,每次检索调用都需要一个租户条件,而产品版本或区域通常也很重要。
过滤器在哪里运行会改变答案。先取出前 10 个向量,然后丢弃来自其他租户的向量,你可能只剩两个结果,或者一个都没有。通常的修复方法是在过滤前多取一个更大的候选池,或者当条件足够具有选择性、以致于对剩余行做精确搜索成本很低时,先进行过滤。
权限是这一点的严格版本。一个内部 copilot 如果检索到用户无权阅读的文档,那么当该文本进入提示词的那一刻,它就已经泄露了该文档。访问控制应属于查询内部,在任何内容到达模型之前完成。
新鲜的操作数据与语义召回同样重要
Agent 会基于业务的当前状态采取行动。如果某个订单在 30 秒前已发货,但你的搜索索引是从主数据库每晚同步的,那么 agent 会告诉客户它尚未发货。
事务感知的工作流会提高风险。退款 agent 必须先确认退款尚未发出,才能发起退款,这要求对当前数据进行一致性读取。单独索引中的过期副本可能变成重复付款。这就是为什么选择 最适合 RAG 和 LLM 应用的向量数据库实际上是一个关于你整个数据层的决策。
混合搜索在 SQL 检索栈中如何工作
混合搜索会并行运行关键词查询和向量查询,对两个候选集进行过滤,并将它们合并为一个排名。在 SQL 技术栈中,上述每一步都是针对同一批表的查询。流程通常如下:
- 运行全文查询,并按 BM25 分数保留排名靠前的候选,通常大约在 20 到 100 个之间。
- 运行向量查询,并按距离保留排名靠前的候选。
- 应用租户、权限和元数据过滤器,使每个候选项都有资格。
- 将两个列表融合为一个排名。
- 可选地,用同时读取查询和每个文档的模型对排名靠前的结果进行重排序。
BM25 和向量相似度扮演不同的角色
这两个分数处于不同的尺度上。BM25 分数没有固定上限,并取决于语料库,而余弦距离落在 0 到 2 之间。将它们相加会产生随着语料库增长而变化的排名,这正是融合要解决的问题。
融合与重排序可提升最终相关性
倒数排名融合(RRF)忽略原始分数,只关注位置。每个文档从它出现的每个列表中赢得 1 / (k + rank),然后将这些值相加。大多数实现将常数 k 设为 60。一个在关键词中排名第二、在向量中排名第五的文档,胜过一个在单个列表中排名第一的文档,因为信号之间的一致性比单一强信号更重要。
RRF 不需要训练数据或分数归一化,因此通常是默认选择。一旦评估数据表明某个信号应该拥有更大影响力,加权融合就有意义。然后,交叉编码器重排序器可以对排名前 20 左右的结果重新评分,代价是每次调用额外的延迟。
SQL 将连接和过滤保留在同一条检索路径中
当文本、向量和元数据共享同一张表时,每个候选查询都是普通 SQL。在 TiDB中,面向支持 agent 的两个候选查询可能如下所示。第一个向量查询先过度获取,然后进行过滤,这样它就可以使用 HNSW 索引。当租户持有数据中很大一部分时,这种方式有效。对于一个小租户,整体前 300 个可能只包含它的少数几行,因此第二个版本先按租户过滤,然后仅对这些行运行精确距离搜索。向量字面量已为可读性截断,因此请将其视为说明性示例,而非可直接复制粘贴:
— 关键词候选项,过滤到一个租户和产品版本
SELECT id, title FROM kb_articles
WHERE tenant_id = 42 AND product_version = ‘7.2’
AND fts_match_word(‘E-4012’, body)
ORDER BY fts_match_word(‘E-4012’, body) DESC
LIMIT 50;
— 语义候选项:先取最近邻,然后过滤
SELECT id, title FROM (
SELECT id, title, tenant_id, product_version,
VEC_COSINE_DISTANCE(embedding, ‘[0.012, -0.044, …]’) AS d
FROM kb_articles
ORDER BY VEC_COSINE_DISTANCE(embedding, ‘[0.012, -0.044, …]’)
LIMIT 300
) t
WHERE tenant_id = 42 AND product_version = ‘7.2’
ORDER BY d LIMIT 50;
— 小租户:先过滤,然后精确距离搜索
SELECT id, title FROM kb_articles
WHERE tenant_id = 42 AND product_version = ‘7.2’
ORDER BY VEC_COSINE_DISTANCE(embedding, ‘[0.012, -0.044, …]’)
LIMIT 50;
请注意,fts_match_word 匹配的是 token,而不是精确字符串。解析器可以将 E-4012 拆分成多个部分,因此提到 E-4021 的文档仍可能部分匹配。正确的文档应该排名更高,但这不是精确短语匹配。
你的应用程序可以用 RRF 融合两个结果集。或者,PyTiDB 在一次混合搜索调用中运行两种搜索并融合结果。无论哪种方式,将获胜者连接到 accounts 表只是又一条 SQL 语句。TiDB 的 原生全文搜索功能更详细地介绍了索引方面。
| 检索信号 | 最擅长 | 常见失败模式 | 为什么 AI agent 需要它 |
| BM25 全文 | 错误代码、SKU、名称、罕见关键词 | 遗漏改述和同义词 | Agent 经常收到直接从日志或工单中粘贴的标识符 |
| 向量相似度 | 改述过的、对话式的问题 | 混淆几乎相同的标识符和数字 | 用户用自己的话描述问题 |
| 元数据过滤器 | 租户、版本、区域、状态范围限定 | 检索后过滤导致结果太少 | 将答案保持在正确的客户和产品上下文中 |
| 查询中的权限 | 强制执行谁可以看什么 | 在检索后检查会泄露内容 | 提示词中的任何内容都可能出现在答案中 |
| 事务性读取 | 当前的订单、账户和工单状态 | 单独同步索引中的过期副本 | 智能体采取依赖于当前真实情况的行动 |
团队对向量搜索和全文搜索的常见误解
最昂贵的假设是认为嵌入就足够了。在演示中它们往往看起来足够,因为测试问题的表述方式与文档类似。生产流量则更加混乱。它充满了粘贴的堆栈跟踪、订单号和内部简写。
第二个错误是架构上的。团队把文本放在搜索引擎中,把向量放在向量存储中,把元数据放在主数据库中,然后用同步任务把它们连接起来,却没有明确的一致性模型。客户删除了一份文档,它在一个索引中仍可被检索数小时。权限变更到达了数据库,却没有到达向量存储。每个副本单独来看都没问题。合在一起它们就互相矛盾。
分块会造成更微妙的麻烦。按固定 token 数量拆分文档,可能会把错误代码与解释它的段落分开,导致两个分块单独来看排名都不理想。
检查清单:你的检索栈缺少搜索信号的迹象
- 对精确的 SKU、错误代码或工单 ID 的查询,在前三名结果中没有返回匹配的文档。
- 租户和权限过滤器在结果返回之后才在应用代码中运行。
- 没有人能说出一行数据发生变更后需要多久才会出现在搜索结果中。
- 删除一份文档意味着要更新不止一个系统。
- 你无法解释为什么某个结果能同时凭借关键词和语义信号排名第一。
TiDB 在混合检索栈中的定位
TiDB 作为数据库,保存文本、嵌入以及智能体所需的事务记录,并用 SQL 查询这三者。它作为检索的统一数据基础,而不是仅支持向量的存储。
为什么统一检索对生产级 AI 应用很重要
常见的初代 RAG 栈用搜索引擎处理文本,用向量存储处理嵌入,用 OLTP 数据库处理客户数据。各自都有自己的索引延迟和权限模型,而它们之间的胶水代码往往是应用中最缺乏测试的部分。
统一检索层将文本、嵌入和业务记录保存在相同的表中。一种查询语言覆盖全部内容,一个一致性模型决定智能体看到什么。
TiDB 连接搜索、事务和新鲜的应用数据
TiDB 是一个分布式 SQL 数据库,可水平扩展,并在节点之间保持 ACID 事务的强一致性。它兼容 MySQL,这在这里很重要,因为现有的 MySQL 驱动、ORM 和团队技能可以沿用。已经使用 MySQL 的团队可以保留其驱动、ORM 和 SQL 技能。检索来自一小组 TiDB 函数,例如用于 BM25 排序关键词搜索的 fts_match_word 和用于语义搜索的 VEC_COSINE_DISTANCE,它们在你们团队已经编写的查询中即可使用。我们的 向量搜索概览对此路径有更深入的介绍。
检索紧挨着事务数据运行。TiDB 具有原生 VECTOR 数据类型,TiFlash 副本为近似最近邻搜索提供 HNSW 索引。全文搜索使用 BM25 排序,并使用多语言解析器,因此不同语言的内容可以共处一张表。pytidb Python SDK 将两者封装为带有 RRF 或加权融合的混合搜索 API。向量搜索在 TiDB Cloud Starter 和 TiDB Self-Managed 上可用。全文搜索目前仅在受支持的 AWS 区域的 TiDB Cloud Starter 上可用。
生产团队已经在运行这种整合模式。Dify.AI 将近五十万个数据库容器整合到一个 TiDB Cloud 系统中,为其 RAG 功能将内容和向量嵌入存储在相同的表中,并报告基础设施成本降低了 80%。APTSell 在 TiDB Cloud Starter 上运行其 AI 销售副驾驶,在单一数据层中结合了事务数据、知识图谱遍历和语义向量搜索。同样的方法也出现在我们关于 使用嵌入式向量数据库实现 RAG 的实战手册中。
TiDB 如何在不增加数据蔓延的情况下支持 AI 检索
你添加到检索栈中的每个系统都会带来另一个同步任务、另一种访问模型,以及另一个数据漂移的地方。将 SQL、向量搜索和全文搜索放在一个数据库中,可以缩小这一范围。删除操作会立即在所有地方生效,因为无需管理单独的同步管道。用于排序结果的同一查询也执行权限控制。智能体读取你的应用刚刚写入的行。
统一数据库并非适合每一种工作负载。一个只有搜索功能、拥有数十亿向量且没有事务数据的产品,可能更适合使用专用引擎,而我们关于 用于 RAG 的最佳向量数据库 的指南详细介绍了这些权衡。对于检索必须尊重实时业务数据的 AI 应用,一个引擎更易于运维,也更容易信任。
正在评估用于 RAG 和 LLM 应用的最佳向量数据库?了解 TiDB 如何在一个引擎中处理向量搜索、全文搜索和 SQL,然后在 TiDB Cloud Starter 上运行你的第一个混合查询,创建时选择一个受支持的 AWS 区域。”
向量搜索和全文搜索常见问题
向量搜索比全文搜索更好吗?
- 两者都不占绝对优势。各自解决不同的检索问题。
- 全文搜索在标识符、错误代码和稀有关键词上占优。
- 向量搜索在改写过的和对话式的问题上占优。
- 混合搜索结合了两者,通常是更安全的生产默认选择。
AI 智能体何时应使用混合搜索?
- 当查询将标识符与开放式意图混合在一起时,例如“为什么更新后错误 E-4012 不断出现?”
- 当语料库中充满了嵌入模型可能不了解的产品名称、SKU 或内部术语时。
- 当漏掉一份文档可能触发错误行动,而不仅仅是让答案稍弱时。
全文搜索中的 BM25 是什么?
- 一种排名函数,用于评估文档与查询词项的匹配程度。
- 它权衡词项频率、每个词项在语料库中的稀有程度以及文档长度。
- 它无需训练,并且仍然是关键词相关性的一个强大基线。
什么是倒数排名融合?
- 一种使用位置而非原始分数来合并已排序列表的方法。
- 每个文档在每个列表中得分为 1 / (k + rank),并在各列表中求和。k 通常为 60。
- 团队使用它是因为 BM25 分数和向量距离不在可比较的尺度上。
AI 智能体检索需要 SQL 吗?
- 是的,当结果取决于租户、权限、区域或日期过滤条件时。
- 连接让智能体能够在检索到的文档之外拉取账户、订单或工单上下文。
- 事务型数据库为智能体提供当前数据,而不是滞后的副本。
- 没有用户特定上下文的静态文档问答可以不需要它。
这篇文章 向量和全文搜索解释:为什么 AI 智能体需要两者 首次出现在 TiDB。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏