跳到主要内容

语义搜索作为产品:当检索理解意图时,什么发生了改变

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数构建语义搜索的团队都从 RAG 概念验证出发:对文档分块、生成嵌入向量、存储到向量库、用余弦相似度查询。在演示中效果不错。然后他们把它发布给用户,结果有一半的查询以与检索质量毫无关系的方式失败了。

原因在于 RAG 和面向用户的语义搜索解决的是不同的问题。RAG 在问"给定一个问题,检索上下文供 LLM 回答"。语义搜索在问"给定用户的查询,呈现真正符合其需求的结果"。第二个问题有一层 RAG 基准系统性忽视的复杂性——而这种复杂性几乎完全存在于检索开始之前。

所有人都忽视的检索前问题

在 RAG 管道中,查询通常是结构良好的。有人提出一个问题,系统检索上下文,LLM 给出回答。查询很少模糊,因为通常是人或另一个 LLM 在刻意组织它。

真实用户不会刻意组织查询。他们在想了解 sort()sorted() 区别时,会输入"python sort list reverse"。他们的意思是"OAuth refresh token 过期处理",却搜索"login not working"。他们缩写、拼写错误、使用文档中根本没有的内部术语,同一个会话里重新表述三次却始终找不到想要的内容。

结果就是:面向用户的语义搜索中,有相当大比例的失败发生在任何向量被触及之前。如果你像监控 RAG 管道一样监控系统——跟踪检索召回率、检查返回文档是否相关——你就会错过那些查询本身从未公平测试过索引时所发生的失败。

检索前失败有几种具体形式:

  • 查询与语料库的词汇不匹配:用户的措辞与语料库描述同一概念的方式几乎没有语义重叠。嵌入模型可以处理同义改写,但对于训练数据中未出现的领域特定缩写、首字母缩略词或行话则举步维艰。
  • 表述不足的查询:短小模糊的查询会产生质量平庸的嵌入。"How to do authentication"生成的向量与数十个文档等距,检索返回的是噪声样本而非排名结果。
  • 多意图查询:"Is product X worth buying and where can I get it cheapest"包含两个独立意图。单个嵌入向量无法忠实表示两者。传统嵌入模型每个查询只产生一个表示,该表示在两种意图之间插值,而非服务于任何一个。

解决检索前失败的方案不是更好的嵌入模型,而是查询预处理——一个发生在向量查找之前的步骤。

查询改写是最大的杠杆点

所有构建出高留存率搜索产品的团队都会进行某种形式的查询规范化。最简单的版本:拼写校正和同义词扩展。更复杂的版本:神经查询改写,将模糊的用户输入转化为与语料库结构相匹配的查询。

生产搜索系统的核心洞察是:用户查询和文档语言是由目标不同的人写就的。文档是为了传递信息而写;查询是为了检索而写。搜索"why does my connection keep dropping"的用户,找的是可能描述"间歇性连接问题"或"TCP 超时配置"的文档。这两种表述几乎没有共同词汇。

查询改写通过将用户的查询重写为更匹配索引的形式来弥合这一差距——不是改变用户想要什么,而是把他们的表达方式翻译成检索系统能够实际服务的形式。

行为信号使这个循环能够自我改进。当用户在一个会话中改写查询——先输入"python list sort",看到令人失望的结果后,再尝试"python sorted function descending"——他们就给了你一对高质量的训练样本。第一个查询是输入,第二个是更好的版本。在规模化之后,这些会话级改写链条成为查询改写模型的训练数据,无需任何标注开销便能持续改进。

这就是为什么像监控 RAG 一样监控产品的搜索团队会错过一半失败。RAG 评估问"检索到的文档与查询相关吗?"它不问"用户是否改写了三次才放弃?"后者才是能告诉你搜索产品是否真正有效的问题。

多意图查询需要不同的架构

单嵌入检索在查询只有一个意图时有效。许多用户查询并非如此。

处理多意图查询的标准方法是在查询层面检测意图,并路由到专门的检索器。关于产品库存的查询可能去商品目录索引;关于产品故障排除的查询可能去支持文档索引;同时包含两者的查询则由能够合并两者结果的系统处理。这并不复杂——就是一个分类器加一个路由层——但其表现远优于试图从单个通用嵌入搜索服务所有意图。

更先进的架构使用神经多意图表示(NMIR)模型,为每个检测到的意图生成不同的查询嵌入。你得到的不是一个代表查询的向量,而是一组向量,每个向量针对不同的方面。检索在所有向量上进行,重排序步骤决定哪些结果最能满足意图的组合。

架构层面的含义是:面向用户的语义搜索需要一个位于检索系统上游的查询理解层。该层负责意图检测、查询扩展、消歧和改写。在 RAG 中,这一层要么不存在,要么由构建检索查询的 LLM 隐式处理。在搜索产品中,它需要是显式的、有监控的——因为它是大多数机会和大多数失败所在之处。

行为信号取代人工相关性判断

正确地评估搜索质量代价高昂。黄金标准是人工相关性判断:经过训练的标注员对每个查询-文档对进行评分。在规模化时,这既缓慢又昂贵,随着语料库变化,判断结果还会过时。

生产搜索团队使用行为信号作为可扩展的替代方案。两个最可靠的指标:

停留时间——用户点击结果后在页面上停留的时长。停留时间短(不足 10 秒)并返回搜索结果,是强烈的无关信号。停留时间长是强烈的相关信号。这个信号本身有噪声——有些页面内容密集,有些可以快速扫读——但在数千个会话的汇总数据中,它能可靠地追踪结果质量。研究一致发现,将点击信号与停留时间结合使用,产生的隐式相关性判断质量高于单独使用点击数据。

查询改写模式——当用户搜索、点击,然后重新表述时,改写告诉你之前的结果没有满足意图。在汇总层面,持续触发改写的查询正在呈现糟糕的结果。在模型层面,成功的会话(用户无需改写就找到了所需内容)和失败的会话(用户进行了改写或直接放弃)成为训练改进排名的隐式标签。

这种方式的运营优势在于:这些信号是自动收集的、实时可用的,并且随查询量扩展。一个需要数周才能产出相关性标签的标注管道,能实时产生点击和停留数据。对于相关性频繁变化的快速迭代产品——新内容、变化的用户需求、更新的语料库——行为信号是唯一能跟上节奏的评估循环。

一个重要警告:行为信号存在选择偏差。你只能观察到出现在 top-K 中的结果的行为,这意味着从未排名靠前的结果永远不会产生信号。一个高度相关但从未被展示过的结果无法通过行为反馈改善其排名。这是搜索排名中的探索-利用问题,需要刻意的应对措施——偶尔注入随机或多样化的结果,让系统接触到当前 top-K 之外的内容。

没有标注数据集时的搜索评估方法

标准信息检索评估流程——构建查询集、标注相关文档、计算 NDCG 或 MAP——代价高昂、速度缓慢,并且在语料库变化后数周内就会与生产质量出现偏差。

生产团队用两种方法来规避这一问题。

第一种是基于重叠的评估。如果你有多个检索系统(关键词、稠密向量、混合),只有单个系统检索到而其他系统没有认可的文档,往往质量较低。多样化检索策略之间的共识是相关性的弱信号,缺乏共识是质量存疑的信号。这不是完美的评估,但完全自动化且无需标注数据。

第二种是使用业务指标进行在线评估。从操作层面定义成功:一个成功的搜索会话以一次点击和超过阈值的停留时间结束,或者以转化结束,或者零次改写。这些代理指标并不完美,但它们衡量的是真实用户行为,而非对它的模拟。针对这些指标对检索变更进行 A/B 测试,比对比静态标注基准更可靠,因为它在真实语料库上针对真实用户查询进行测试。

陷阱在于只优化点击率。点击率很容易被刷高——更好的标题无论内容质量如何都能带来更多点击,标题党是经典的失败模式。将点击率与停留时间或下游参与度指标配对可以弥合这一差距。一个被点击但立即被放弃的结果,比一个没有被点击的结果更糟糕,你的评估方法应该体现这一点。

生产环境中真正会出问题的地方

Uber 将他们面向用户的语义搜索迁移到了一个处理近 400 维、共 15 亿个向量的系统。工程层面不是难点。难点在于他们的初始原型是在固定测试集上测量检索召回率后就上线了。生产流量立即暴露了差距:在测试集上运行良好的查询,在真实用户措辞的长尾部分失败了,而检测和修复这些失败的反馈循环根本不存在。

这种模式普遍到值得明确命名。基于嵌入检索构建的搜索团队通常会遭遇相同的失败序列:

  1. 演示有效——在干净语料库上精心挑选的查询集产生令人印象深刻的结果。召回率高,结果看起来不错。
  2. 生产查询分布不同——真实用户的措辞方式超出了演示查询的覆盖范围。查询分布的头部没问题,尾部是坏的。
  3. 没有监控来查看尾部——团队在追踪一个不代表生产流量的测试集上的平均精度。
  4. 用户改写后放弃——失败在指标中不可见,却在留存率中可见。用户停止使用搜索功能,因为它无法可靠地找到他们需要的内容。

修复方案直截了当,但需要构建大多数团队跳过的基础设施:会话级日志,追踪包括改写和放弃在内的完整查询序列,而不仅仅是单个查询-结果对。这才是能告诉你搜索产品是否有效的数据。

构建一个能持续进化的搜索产品

搜索功能和搜索产品的区别在于反馈循环。功能检索文档;产品从用户行为中学习,随着时间推移检索出更好的文档。

这个复利循环有三个组成部分:行为信号收集(点击、停留时间、改写),将这些信号转化为改进的查询理解和排名的训练管道,以及在真实流量而非静态基准上衡量系统是否在改进的评估方法。

让这个循环运转起来的团队,在不对底层检索基础设施做任何改动的情况下,就能看到搜索质量的稳步提升。嵌入模型不变,向量索引不变,变化的是查询预处理层和排名函数,两者都在持续从用户行为中学习。

随着各组织意识到关键词匹配已不足以处理其产品需要应对的查询量和多样性,语义搜索市场正以 23% 的年复合增长率扩张。基础设施现已商品化——托管向量数据库、托管嵌入 API、开源检索库。差异化在于 RAG 基准不衡量的那些层:检索前对查询的理解程度、检索后从用户行为中学习的能力,以及在真实流量而非精心策划的测试集上进行评估的能力。

先构建那些层。嵌入模型是容易的部分。

References:Let's stay in touch and Follow me for more thoughts and updates