从HyDE到RRF:大模型与多路融合如何实现召回率22%提升
1. 从“大海捞针”到“精准撒网”召回优化的核心挑战在信息检索和推荐系统的世界里我们常常面临一个经典的“效率与效果”的权衡。想象一下你有一个巨大的图书馆比如你的商品库、文档库或视频库用户走进来用一句话描述他想要的东西。你的任务是在几毫秒内从数以亿计的馆藏中找到最相关的那几本、几十本交给后续的排序模型去精挑细选。这个“快速初筛”的过程就是召回。召回阶段的核心矛盾在于召回率Recall与计算资源/响应速度的对抗。召回率简单说就是你从全库中找到所有相关物品的比例。理论上把整个库都拿出来召回率就是100%但这显然不现实因为后续排序模型算不过来用户也等不起。所以我们必须在有限的资源比如只允许从十亿数据中检索出几千条内尽可能多地找到相关结果。这就好比在茫茫大海中你只有一张有限大小的渔网如何撒网才能捞到最多的目标鱼群传统做法是依赖用户输入的原始查询词Query通过倒排索引等技术进行字面匹配。但问题来了用户的表达是模糊的、多样的、不完整的。“帮我找一下适合夏天穿的、透气又好看的男士衬衫”这个Query包含了风格好看、场景夏天、功能透气、品类男士衬衫多个意图。如果只用“男士衬衫”去搜会漏掉大量符合“透气”、“夏天”但标题没写“衬衫”的POLO衫、亚麻上衣如果拆成多个词分别搜结果如何融合又是难题。更常见的是用户Query很短比如“手机续航不行”其背后真实意图可能是“寻找高容量充电宝”、“手机电池维修服务”或是“省电技巧攻略”。因此Query改写和多路召回成为了提升召回率的“黄金搭档”。Query改写负责“理解与扩展”用户的意图将一句模糊的话翻译成系统更能理解的多种“搜索指令”。多路召回则负责“并行搜索与融合”利用不同的“渔网”不同的检索模型、索引策略、数据源同时撒网最后把各路的收获巧妙地合并起来确保不漏掉大鱼。我最近主导的一个项目正是围绕这套组合拳进行深度优化。目标很明确在保证响应时间毫秒级的前提下将核心场景的召回率提升至少15个百分点。经过一系列从理论到实践的折腾最终我们通过引入HyDE思想进行生成式Query改写并结合RRFReciprocal Rank Fusion等融合策略实现了**召回率提升22%**的实战效果。这不是纸上谈兵而是一个充满细节、踩坑和抉择的完整方案。接下来我将抛开复杂的公式用最直白的方式拆解我们是如何一步步做到的。2. Query改写的进化从词表扩展到大模型生成Query改写的目标是让系统“听懂人话”。它的发展大致经历了从“词典匹配”到“语义生成”的演变。2.1 传统方法的瓶颈同义词与规则最早我们依赖的是同义词词表。建立一个大词典把“手机”和“电话”、“移动电话”关联起来。当用户搜索“手机”时系统会自动用“手机 OR 电话 OR 移动电话”去检索。这种方法简单直接对于解决“一词多义”和“一义多词”的基础问题有效。但它的天花板很低维护成本高语言是活的新词、网络用语、特定领域的黑话层出不穷词典永远追不上变化。缺乏上下文“苹果”可能是水果也可能是手机品牌。仅靠词典无法区分。无法处理复杂意图对于“夏天透气男士衬衫”这样的复合Query词典无能为力。你不可能为每一种可能的组合都建立一条规则。于是我们引入了基于规则的意图解析。通过正则表达式或简单的语义模板识别Query中的实体和模式。例如匹配“XXX的YYY”可以解析出属性YYY和主体XXX。但规则同样脆弱泛化能力差且开发和维护规则本身就是一项繁重的工程。2.2 向量化检索的引入与局限随着深度学习的发展双塔模型和向量检索成了标配。我们将Query和文档都编码成高维向量通过计算余弦相似度来度量相关性。这带来了语义层面的飞跃“智能手机”和“高端手机”即使字面不匹配向量也会很接近。但问题转移了如何为用户的简短Query生成一个“好”的向量一个Query“续航好的手机”其向量应该靠近那些电池容量大、评测中续航表现好的手机文档。然而如果我们的文档向量主要来自标题和属性如“iPhone 13 Pro Max电池容量4352mAh”那么“续航好”这个抽象需求与具体参数“4352mAh”之间的向量关联可能并不直接尤其是当模型没有在“续航好”与“电池容量大”这个维度上充分训练时。这就引出了核心矛盾用户Query的抽象性、意图性与文档文本的具体性、描述性之间存在鸿沟。直接对原始Query编码可能无法准确命中那些最相关的文档因为它们的语义空间没有对齐。2.3 HyDE一种“假设性文档”的思想这正是我们引入HyDEHypothetical Document Embeddings的动机。HyDE的核心思想非常巧妙既然用户的Query是抽象的意图而我们要找的是具体的文档那么何不先让大模型根据这个意图“想象”或“生成”一篇理想的、假想的文档呢具体操作分三步生成假设文档将用户Query输入给一个大语言模型如ChatGPT、ERNIE等并给出指令“假设有一篇完美回答这个问题的文档请生成这篇文档的一段内容。” 例如对于“续航好的手机”模型可能生成“这是一款主打超长续航的智能手机它配备了高达5000mAh的大容量电池并采用先进的节能芯片和智能刷新率屏幕技术。在权威媒体的续航测试中其连续视频播放时间超过20小时足以满足用户两天以上的中重度使用需求。”编码假设文档将这个生成的、具体的、富含信息的“假设文档”文本通过我们训练好的文档编码器就是用来给真实文档生成向量的那个模型进行编码得到一个向量。用假设文档向量去检索用这个向量代替原始Query向量去向量数据库中进行相似度检索。为什么这样做更有效对齐语义空间我们用来检索的向量和库中所有文档的向量出自同一个编码器。这个编码器是在海量文档数据上训练擅长理解文档应该如何被表达。用生成的“假文档”去编码相当于让Query“伪装”成了一篇文档从而更自然地融入文档的语义分布中。信息富集生成的文本扩充了原始Query的信息。它把“续航好”这个模糊概念具体化为“大容量电池”、“节能芯片”、“长播放时间”等文档中更可能出现的词汇极大地丰富了查询的语义信号。注意这里的关键是生成假设文档的模型大语言模型和编码文档的模型双塔模型中的文档编码器可以是两个独立的模型。我们并不需要大语言模型理解我们的文档向量空间它只需要发挥其强大的语言生成和推理能力即可。这降低了技术栈耦合度。在我们的实践中我们对比了直接使用原始Query向量、使用Query扩展同义词核心词提取后的向量、以及使用HyDE向量三种方式。在同一个测试集上HyDE将首轮向量召回的召回率提升了约18%。这是一个巨大的飞跃它验证了“先翻译成系统语言再对话”这条路径的有效性。3. 多路召回策略设计为什么不能只靠一把锤子即使有了HyDE这把“神兵利器”我们依然不能只依赖单一召回路径。原因很简单任何单一模型或索引都有其固有的偏见和盲区。向量召回语义召回擅长处理语义相似但不一定字面匹配的情况如上文所述。但它可能对精确匹配、关键词、品牌型号等强信号不敏感。比如搜索“Python 3.11 release notes”向量召回可能会返回一堆关于Python编程的教程而字面召回能精准命中版本发布说明文档。倒排索引召回字面召回擅长处理精确匹配、前缀匹配、布尔逻辑。它对拼写错误、同义词、语义泛化无能为力。个性化召回基于用户历史行为召回其偏好的物品或内容。这能解决“千人千面”的问题但对于新用户冷启动或用户探索新兴趣时效果有限。热门/趋势召回召回当前热门的物品保证结果的时效性和流行度。但可能淹没长尾的、小众但精准的需求。基于知识图谱的召回通过实体关系进行扩展例如搜索“周杰伦”可以召回他的歌曲、专辑、演唱会信息等。这对理解实体和关系型Query至关重要。我们的策略是并行多条召回通路每路侧重不同的信号最后进行融合。在我们的系统里主要部署了以下四路召回HyDE向量召回路主力部队负责解决语义理解和意图泛化召回基数大。精排词召回路对原始Query进行分词、词干化、去除停用词后利用倒排索引进行AND或OR匹配保证核心关键词的精确命中。实体链接召回路通过NER识别Query中的实体如品牌、人名、地点、产品型号链接到知识图谱中的节点并召回与该实体直接相关的物品。用户历史行为召回路针对登录用户实时召回其近期点击、购买、收藏过的相似物品。每一路召回都会返回一个有序的列表Top K例如Top 1000。那么下一个核心问题来了如何将这四个不同的列表合并成一个最终的有序列表交给后续的精排模型这就进入了召回系统最精妙的环节——融合策略。4. 融合策略的深度对比从加权分到RRF融合策略的目标是综合各路的排序信息产生一个全局更优的排序。我们实验了多种方案其演进过程本身就是对问题理解的深化。4.1 方案一简单加权分数融合Naive Weighted Score最初的想法很直观每一路召回模型都会为每个物品打一个分数相似度分数、BM25分数等。我们尝试将它们归一化到同一尺度如0-1然后加权求和。最终分数 w1 * 分数_向量路 w2 * 分数_倒排路 w3 * 分数_实体路 w4 * 分数_行为路踩坑过程尺度不一致不同模型的分数分布差异巨大。向量相似度余弦值在[-1,1]BM25分数可能上千行为路的分数可能是点击次数。简单的Min-Max归一化在分布不均匀时效果很差。权重调参噩梦我们花了大量时间做网格搜索调参。更糟糕的是发现最优权重在不同类型的Query上差异很大对于导航类Query如“微信官网”倒排路的权重要极高对于探索类Query如“周末去哪玩”向量路和行为路更重要。一套静态权重无法适应所有情况。分数不可比性更深层的问题是不同路的分数含义根本不同。向量路的0.8分和倒排路的0.8分代表的“相关度置信度”是一样的吗显然不是。强行把它们加起来物理意义模糊。这个方案很快被放弃它过于粗糙且理论基础薄弱。4.2 方案二按路排序后加权Weighted Rank既然分数不可比那就比排名。我们将各路返回的列表只取其排序顺序Rank。例如某物品在向量路排第1在倒排路排第5在实体路未出现可视为排名无穷大或一个很大的数。 然后我们尝试对排名进行加权调和最终得分 w1 / rank_向量 w2 / rank_倒排 ...排名越靠前数字越小倒数越大贡献的得分越高。未出现的物品该项得分为0。这个方案的改进与遗留问题改进点避免了分数尺度问题只关注相对顺序。问题排名本身也是不平滑的。第1名和第2名的差距与第100名和第101名的差距在倒数计算中被视为同等重要这显然不合理。我们更关心头部排名的差异。此外权重的调优依然是个黑盒。4.3 方案三 Reciprocal Rank Fusion (RRF) —— 我们最终的选择在查阅了大量文献和业界实践后我们锁定了RRFReciprocal Rank Fusion。它的公式简洁而优美RRF Score(d) Σ (1 / (k rank_i(d)))其中d是某个文档物品。rank_i(d)是文档d在第i路召回结果中的排名从1开始计数。如果某一路没有召回d则这一项不参与求和或rank_i(d)视为无穷大使得该项为0。k是一个常数通常取一个较小的值如60目的是平滑排名靠前项的影响避免对排名第一的项给予过大的权重。为什么RRF解决了我们的痛点无需分数只依赖排名完美规避了不同模型分数不可比的问题。强调头部一致性公式中的倒数关系1/(krank)决定了排名越靠前其贡献的分数衰减得越快。排名第1贡献 ~1/61和第2贡献 ~1/62的差距远大于排名第100贡献 ~1/160和第101贡献 ~1/161的差距。这符合我们的直觉如果一个物品在多个召回路中都排在非常靠前的位置那么它极有可能是高度相关的应该被大幅提升。参数极少且鲁棒只有一个超参数k。实验表明k在60左右的一个较大范围内比如40-100效果都相对稳定这极大地减轻了调参负担。我们最终将k设为 60。自然处理未出现情况如果某一路没召回某个物品该项自然为0不影响其他路的贡献。我们的具体实现与调优 我们为四路召回分别计算RRF分数。但并非完全平等对待。我们引入了一个轻量级的路权重概念不是加权分数而是在求和前对每路的贡献值做一个缩放加权RRF Score(d) Σ [ w_i * (1 / (k rank_i(d))) ]这里的权重w_i不再是精细调节的魔法数字而是基于先验知识设定的粗粒度权重。例如w_HyDE向量路 1.0基准w_精排词路 0.8因为HyDE已经包含语义字面匹配作为强信号补充但权重略低w_实体路 0.7实体信号很重要但覆盖的Query范围相对较窄w_行为路 0.6个性化信号价值高但只对部分用户和场景有效且需注意回声室效应这些权重值我们只进行了少量分组实验如导航类Query组、探索类Query组来确定并没有进行全量精细网格搜索。最终我们为大部分场景设置了一套默认权重并为少数明确类型的Query通过Query分类器识别设置了特定的权重模板。例如对于明确包含品牌型号的Query会提升实体路和精排词路的权重。5. 全链路实战从工程架构到效果评估方案设计得再美最终都要落地到工程系统。这一部分我分享我们在实现这个“HyDE 多路召回 RRF融合”方案时在工程上的核心设计和踩过的坑。5.1 系统架构与数据流我们的召回服务部署在云上整体架构如下图所示此处用文字描述Query理解与路由层接收用户Query进行基础清洗、分词、Query分类判断是导航、交易、探索还是问答意图。这一层会决定后续召回策略的权重模板。并行召回执行层HyDE生成与向量召回这是一个相对耗时的环节。我们部署了一个异步微服务专门调用大语言模型API生成假设文档。为了平衡效果和延迟我们做了以下优化缓存对高频Query的生成结果进行缓存有效期设为1小时。这解决了大部分重复请求。超时与降级设置严格的超时时间如150ms。如果大模型服务超时或失败立即降级为使用原始Query的向量召回并打点报警。提示词工程我们精心设计了生成假设文档的提示词Prompt要求模型生成“一段客观、包含关键事实和参数的描述性文字”并限制在100字以内以避免生成过于冗长或虚构的内容。其他三路召回倒排、实体、行为则并发执行它们延迟较低。融合与重排序层所有召回路径的结果返回后进入融合模块。我们实现了一个灵活的融合框架支持配置不同的融合算法加权分、RRF等和参数。对于RRF核心逻辑就是遍历所有物品根据其在各路中的排名按公式计算加权RRF分数然后全局排序取Top N如200条输出。结果输出层将融合后的有序列表传递给下游的精排模型。5.2 效果评估与AB测试我们如何衡量那“22%”的提升召回阶段的评估不能只看线上业务指标如CTR、GMV因为这些指标受后续排序和展示的强烈影响。我们建立了离线、在线两套评估体系。离线评估 我们构建了一个高质量的人工标注测试集包含数千个Query每个Query都标注了全库中所有相关文档Recall Set。评估时我们让召回系统返回Top K如K500个结果然后计算召回率K系统返回的Top K结果中有多少比例命中了人工标注的相关集。这是我们最核心的指标。Mean Average Precision (MAP)考虑排序顺序的精度指标。在离线测试集上新方案HyDERRF相比旧方案传统向量加权分融合召回率500 从68%提升到了90%绝对提升22个百分点相对提升超过32%。这证明了方案在寻找相关物品能力上的巨大突破。在线AB测试 我们将用户流量随机分为实验组新方案和对照组旧方案进行为期两周的AB测试。核心观察指标召回多样性实验组召回结果中独特物品的数量和品类分布更广说明HyDE和RRF帮助发现了更多长尾相关物品。精排模型输入质量我们监控了输入给精排模型的候选集的相关性分数由一个人工智能评分器打分实验组平均分显著高于对照组。这意味着精排模型收到了“原料更好”的候选集。最终业务指标经过全链路召回精排重排后实验组的点击率CTR提升了5.2%转化率CVR提升了3.8%。这证实了召回率的提升最终能有效传导到业务价值上。5.3 踩坑实录与经验总结没有一帆风顺的项目分享几个让我们“掉头发”的坑坑一HyDE生成内容的“幻觉”与偏差大模型生成的内容可能存在事实错误幻觉或风格偏差。例如对于Query“2023年续航最强的手机”模型可能生成一篇虚构的、包含错误型号参数的文档。用这个向量去检索可能会召回一些不存在的或参数不实的商品。我们的应对Prompt约束在Prompt中强调“基于公开已知事实”、“避免具体未经验证的参数”。后过滤在向量召回后增加一个轻量级的规则校验层例如检查召回的商品是否与生成文本中的关键实体如品牌冲突。效果监控对生成内容进行采样人工审核并监控因HyDE路召回而新进入精排候选集的物品的后续转化情况发现异常及时调整。坑二RRF融合后的“头部固化”RRF公式天然倾向于提升在多路召回中都排名靠前的物品。这可能导致一些“大众情人”类物品总是排在前面而一些在某一路非常独特、高度相关但其他路未召回的“尖货”被埋没。我们的应对引入多样性打散在RRF融合后对最终Top 200列表按品类、品牌等维度进行轻微的打散确保头部结果不会过于同质化。探索加权RRF的变体我们尝试了1 / (k rank)^α的公式通过调整α1来进一步放大头部效应或减小α1来缓和。实验发现α略小于1如0.9时对长尾物品更友好但会轻微牺牲头部精度。需要根据业务目标权衡。坑三系统延迟与资源消耗增加HyDE生成和四路并行召回无疑增加了系统复杂度和延迟。我们的应对异步与缓存如前所述HyDE生成异步化并加缓存。超时设置与熔断为每一路召回设置独立超时。任何一路超时立即返回已获得的结果进行融合不影响整体服务可用性。资源隔离与扩容将向量检索、倒排检索等服务部署在独立的资源池并根据流量预估进行弹性扩容。6. 总结与展望召回系统的持续迭代回顾整个项目从明确召回率瓶颈到引入HyDE思想解决语义鸿沟再到设计多路召回并用RRF进行优雅融合最后在工程上实现并验证效果是一个完整的“发现问题-设计方案-实验验证-工程落地”闭环。22%的召回率提升不是一个魔法数字而是对每一个环节深入思考和精细调优的结果。它告诉我们理解比匹配更重要在NLP能力日益强大的今天用生成式方法如HyDE去“理解”用户意图并将其“翻译”成系统语言是突破传统检索天花板的关键。融合需要科学简单的加权求和是直觉但往往不是最优解。RRF这类基于排名的融合方法理论清晰、参数少、效果鲁棒是值得放入工具箱的利器。工程是实现效果的保障再好的算法也需要缓存、降级、超时、监控等工程手段来保证其在高并发、低延迟的线上环境中稳定运行。这个方案远非终点。我们已经在探索下一步的优化方向HyDE的迭代尝试用更轻量、更专用的生成模型如经过微调的T5替代通用大模型以降低成本和延迟。融合策略的动态化能否根据Query的实时特征如分类、长度、实体数量和用户上下文动态调整各路召回的权重w_i甚至融合算法多模态召回扩展对于图片、视频等内容如何将视觉特征向量也作为一路召回并融入融合框架召回系统是搜索和推荐引擎的“第一道关卡”它的好坏直接决定了后续环节的天花板。希望我们这套从HyDE到RRF融合的实战经验能为你打开一扇窗提供一些可借鉴的思路。毕竟在数据的海洋里织一张更智能、更精准的渔网永远是我们追求的目标。