尧图精选

生成式召回:从向量匹配到意图构造的搜索范式跃迁

🕒 发布时间:2026/10/1 8:52:32 📁 来源:尧图网络
别再只卷向量检索了得物交易搜索如何用“生成式”实现召回范式跃迁这两年做搜索召回的同学几乎人人都在聊向量检索。从双塔到 ANN从 HNSW 到量化压缩大家把 Faiss、Milvus 调得越来越溜召回率也一点点往上磨。但说实话我越来越觉得这条路有点“卷”错方向了——向量检索解决的是“相似怎么算”而搜索真正难的是“需求怎么被理解”。最近我得物交易搜索团队做了一次新的尝试把召回从“判别式匹配”切换到“生成式构造”这个过程让我重新理解了什么叫检索范式的跃迁。先说一下背景。得物交易搜索的场景比通用搜索要复杂不少用户搜“篮球鞋 实战 耐磨”背后可能对应的是品牌、品类、材质、场景、价格带多个维度的组合条件搜“送男友 千元 礼物”这种 Query压根没有明确品类完全是意图推断。传统的向量召回在这里暴露了一个很尴尬的问题它擅长找“长得像”的东西但不擅长“生成”一个用户脑子里还没说全的答案。这篇文章不准备讲太多理论重点聊聊我们为什么从向量检索转向生成式召回、生成式召回具体是怎么做的、落地时踩了哪些坑以及这套思路对交易搜索乃至更广的搜索场景有什么启发。如果你正在做搜索、推荐或者任何跟“理解用户需求”相关的系统这篇文章应该能给你一些不一样的抓手。1. 向量检索的天花板召回率不是唯一指标召回“正确的东西”才是1.1 向量召回的本质是“近似”不是“理解”我们先回到最基础的问题向量检索到底在做什么把商品、Query 各自编码成向量然后用内积或者余弦相似度找最近邻。这个流程大家都很熟了。本质上它是在一个高维空间里做近似匹配——Query 和商品的语义距离足够近就把商品捞出来。但这里有个很微妙的偏差“语义距离近”不等于“需求满足”。尤其是交易搜索里用户的需求往往是组合式的、条件化的甚至是带排除语义的。举个例子。用户搜“黑色 羽绒服 中长款”在向量空间里它确实能召回一堆黑色羽绒服但“中长款”到底怎么定义衣长到哪个位置算中长不同类目对“中长款”的标注标准还不一样。向量模型很难精确表达这种条件约束它更像是在做一个“模糊联想”。你问它“中长款”它给你返回的可能是“稍微有点长”的、也可能是“长到膝盖”的取决于训练语料里怎么共现。这还不是最麻烦的。更麻烦的是否定语义和条件组合。比如“不要白色的”、“200-300 之间”、“适合外场”这种带过滤性质的意图向量检索天然就不擅长。你可以说这类需求交给后面的精排去过滤不就行了但问题是如果召回层根本没把足够多的候选集捞出来精排再强也巧妇难为无米之炊。1.2 向量召回的一个隐蔽缺陷Query 稀疏性与长尾表达另一个我在实践中体会很深的问题是Query 稀疏性。向量模型是靠“见过足够多相似的 Query-Item 对”才能学好映射的。但真实线上 Query 是极度长尾的尤其是交易搜索这种场景促销词、口语化描述、新款代号、网红叫法每天都在冒出来。“秋天的第一杯奶茶”这种 Query如果只看字面向量模型大概率会把它当成饮品搜索但实际上用户想搜的可能是一个可以发朋友圈的礼物。这类语义如果没有在训练数据里充分出现向量召回就只能靠运气。说白了向量检索的本质是“记忆相似模式”。它把所有语义都压到一个固定维度的向量空间里然后用距离衡量相关性。它学到的是一种静态的、平均化的语义分布一旦用户的需求表达超出了它的记忆范围召回质量就会断崖式下跌。1.3 召回率 91.3% 的错觉当我们讨论召回率时到底在讨论什么最近看到华为云码道检视修复智能体提到“召回率 91.3%”很多人觉得这数字很漂亮。但我在实际做搜索系统时养成了一个习惯先看召回集里到底有没有“正确的东西”再看召回率数字。因为召回率本质上是一个“相对指标”它取决于你怎么定义 Ground Truth。如果 Ground Truth 只包含“跟 Query 字面匹配的商品”那召回率很容易做高。但如果 Ground Truth 定义成“用户真正想买的东西”那大多数向量召回系统可能连 50% 都到不了。这不是说向量检索没用。它依然是我们系统里最基础、最重要的召回通道之一。但我们必须承认向量召回解决的是“语义相似性召回”而交易搜索真正需要的是“需求满足性召回”。这两个目标之间有 gap而这个 gap 靠继续调向量模型是填不满的。2. 从“匹配”到“生成”生成式召回的核心思路与架构设计2.1 生成式召回的基本思想先构造答案再匹配答案那怎么填这个 gap我们当时的想法是与其让模型去“猜”用户要什么不如让模型直接“生成”用户可能想要的商品描述然后再拿生成的结果去做检索。这就是生成式召回的核心逻辑——把召回问题从“Query 到 Item 的匹配”转变成“Query 到查询表达的生成再基于生成的表达去匹配 Item”。用大白话说传统方法是用户说“我要一双实战篮球鞋”系统直接去商品池里找“实战篮球鞋”生成式方法是系统先自己脑补出“Nike LeBron 系列、缓震好、抓地强、适合外场、中帮”再拿这一串扩展出来的属性去商品池里捞。这里的关键突破在于生成式模型不是一个“匹配器”而是一个“需求补全器”。它不直接回答“哪个商品最相关”而是回答“用户到底在说哪些条件、哪些条件没说但可以推断出来”然后把推断结果变成一个中间表示——我们叫它Query 结构化描述——再基于这个结构化描述做检索。2.2 中间表示怎么设计从“自然语言”到“逻辑表达式”中间表示是整个生成式召回的地基。如果第一步就生成错了后面全白搭。我们参考了业界比较成熟的 NL2SQL 思路但针对交易搜索做了定制化改造。我们把每个用户 Query 解析成一个由条件簇组成的逻辑表达式精确条件品牌、类目、价格区间、颜色等能够直接映射到商品结构化字段的条件。模糊条件风格、场景、人群、功能等需要模型推断的软性条件。关系条件条件之间的逻辑关系包括 AND、OR、NOT以及一些特殊的约束比如“不要某个品牌”。举个例子Query“送男友的千元实战篮球鞋不要白色的”解析结果{ 场景: 送礼, 对象: 男友, 类目: 篮球鞋, 价格带: 约1000元, 功能: 实战, 排除: [白色] }这个结构化描述跟原始 Query 的区别是它把隐含的信息显式化了。“送男友”这个短语字面没有任何一个词是“性别男 礼物场景”但生成模型会根据常识和用户行为模式把它推断成“礼物场景 男性偏好”。这一步非常关键。因为一旦信息被显式化后面无论是走 ES 倒排、还是走向量召回都非常好办——因为查询条件已经是“可执行”的了。2.3 生成模型的选型为什么我们没有一上来就上大模型可能有人会问既然叫“生成式”是不是直接上 LLM 就完事了说实话我们在最初做技术选型时确实考虑过直接用大模型。调研一轮之后发现几个现实问题延迟不可控。大模型推理一次至少几百毫秒到了大促峰值流量下搜索链路根本等不起这一轮生成。成本太高。交易搜索的 Query 量级很大全部走 LLM 的话推理成本会是传统检索的好几倍。可解释性不足。LLM 生成的结果是一个黑盒一旦生成出离谱的解析结果排查问题的难度非常大。所以我们最终选了分层生成策略第一层轻量 NLU 模型基于预训练模型微调负责处理高频、明确、常见的 Query 模式。这层大约覆盖 80% 的流量延迟控制在 10ms 以内。第二层LLM规则约束 小模型兜底负责处理长尾、复杂、口语化的 Query。这层只覆盖剩余 20% 的流量但恰恰是这 20% 贡献了绝大部分的召回增益。第三层规则兜底负责处理模型完全搞不定的极短 Query 或者纯泛搜词保证不跌穿底线。这套分层设计的好处是用 80% 的高频流量摊薄了成本用 20% 的长尾流量换取了效果上限。而且因为高频流量走的是轻量模型整个系统的稳定性和可解释性都有了保障。2.4 生成结果怎么用两路召回合并的实操细节生成式模型产出的结构化描述本身不直接是一个商品集合它还需要过一道“召回执行”的工序。我们的做法是同时走两路。第一路结构化查询召回。把生成的结构化描述转成 ES 的 Bool Query去做精确匹配。这一步的作用是“保准”只要是品牌、价格、颜色这类能精确命中的条件都尽量命中。第二路扩展向量召回。把结构化描述里的模糊条件风格、场景、人群拼接成一段“伪自然语言”再走向量召回。这一步的作用是“扩量”把那些无法精确映射到结构化字段的商品也捞回来。两路结果做合并、去重、粗排之后进入精排阶段。这里有个实操细节可以分享一下两路结果不是简单做 Union而是要给两路分别设定“置信度权重”。结构化查询召回的结果权重高因为它精确向量召回的结果权重稍低因为它模糊。如果两路都命中了同一商品那这个商品会获得一个较高的加权得分相当于在精排阶段天然获得了优势。这么做的好处是生成式召回不是“替代”传统的向量召回而是给向量召回加了一层“条件约束”的上限。它让向量召回不再完全靠“猜”而是有了一个生成式模型给出的方向性指引。3. 实战中的系统落地从离线验证到线上 A/B 的完整链路3.1 离线评测怎么做先别急着看线上指标重点看“召回集构成”任何新召回方案上线前最怕的就是“自我感觉良好”。我们当时的离线评测思路跟传统做法做了点区分。传统做法拿历史日志里的曝光点击数据切成训练集和测试集然后算 RecallK、NDCGK 这些指标。这种做法的问题在于它只能衡量“模型是否记住了历史行为”不能衡量“模型是否理解了用户意图”。也就是说你只是在检验旧系统能不能被更准确地复现而不是在检验新系统能不能做得比旧系统更好。我们的做法是除了常规指标还额外标注了一份“需求满足集”。具体做法是从线上日志里抽了一批长尾 Query由业务同学逐个标注“如果这个 Query 让我去买我最想看到哪 3-5 个商品”。这里的商品不一定在历史点击里出现过甚至可能是完全没曝光过的商品。然后用这个标注集去算“需求满足率”。这一步非常关键。因为它衡量的是系统的上限能力而不是“对历史行为的拟合能力”。我印象很深刻当时我们传统的 RecallK 只提升了不到 2 个点但需求满足率提升了接近 9 个百分点。这两个数字放在一起才能真实反映生成式召回的价值。3.2 线上 A/B 实验的坑别拿“点击率”当唯一决策指标线上 A/B 我们做了大概三轮每轮跑一周以上。第一轮结果出来的时候团队内部差点吵起来——点击率几乎没涨但搜索成交转化率涨了。这就很有意思了。后来一分析原因是生成式召回确实把更符合用户需求的商品捞出来了但这些商品不一定是用户最想“点”的。用户可能看到商品列表第一眼还是会先去点最熟悉的品牌、最常买的款式但真正决定“买不买”的是列表里有没有那个“我想要的”。如果列表里出现了那个“对的商品”用户就会搜得更深、买得更果断。所以如果你只盯着 CTR 做决策很可能会得出“生成式召回没用”的错误结论。搜索系统的最终目标不是让人点得更多而是让人更快地找到想要的东西。CTR 只是过程指标转化率和成交才是结果指标。3.3 稳定性保障生成式模型也会“抽风”怎么办生成式模型跟传统检索模型最大的不一样就在于它的输出不确定性。同样是“实战篮球鞋”今天生成出来的结构化描述可能是“外场、耐磨、缓震”明天可能就变成“包裹性、透气、抓地力”。这带来的直接问题是同一 Query 在不同时段召回的候选集可能不一样这会导致用户体验上的抖动。我们当时做了三个措施来缓解温度参数调低让生成结果的随机性降到最低尽量保持同一 Query 的输出稳定。结果缓存对高频 Query 的生成结果做缓存设置一个合理的过期时间比如 10 分钟避免短时间内反复生成产生抖动。最小改动原则模型生成的字段里如果某些字段的置信度比较低就不让它进入结构化查询条件只作为扩展召回的参考词。这样即使生成结果有波动主路径也不会受太大影响。3.4 一个印象深刻的 Case长尾 Query 带来的真实增量说一个让我印象特别深刻的 case。有个用户搜的是“打球穿啥鞋不心疼”。这个 Query 如果走传统向量召回几乎必死——因为向量模型根本不知道怎么把“不心疼”映射到商品属性上。但我们生成式模型解析出了几个维度场景打球/运动价格偏好偏低/性价比高心理特征耐磨耐操、不心疼基于这个解析系统把一批“耐磨、性价比高、适合外场实战”的篮球鞋召回到了列表里。最后这个 Query 的成功转化率比传统方案高了 15%。这类 Query 在日志里占了很大比例用户根本不会像写搜索词一样说“耐磨外场篮球鞋 300 元以内”而是会用非常口语化、情绪化的方式表达需求。传统向量检索的问题就在这里它能理解字面但理解不了潜台词。而生成式召回恰恰是把潜台词翻译成了可执行的检索条件。4. 生成式召回踩过的坑与应对方案每一条都是真实教训4.1 坑一生成结果太“发散”结构化字段满天飞第一版模型上线后我们发现它特别喜欢“脑补”。比如用户搜“卫衣”它能生成出“宽松版型、美式复古、重磅棉、落肩设计、男女同款”一堆属性。单个看都没错但把这些属性全部当成硬条件去检索召回集瞬间就窄了——因为市场上并没有那么多同时满足所有条件的卫衣。解决方案是给生成式模型加一个**“条件置信度约束”**。每个生成字段必须附带一个置信度打分只有分数超过阈值的字段才进入硬性检索条件其余字段则当作软性扩展只提升该商品的排序权重不参与过滤。这个改动的效果立竿见影硬条件平均从 5 个降到了 2-3 个召回池的覆盖率恢复到了正常水平同时排序质量反而提升了。4.2 坑二排除条件太容易误伤生成式模型能理解“不要白色”这是好事。但问题是如果它对“不要”的理解稍有偏差比如把“不要太贵”理解成了“不要 1000 以上”就会把用户原本可能接受的高价商品全部过滤掉造成召回质量的断崖式下跌。我们在第二轮实验里就吃过这个亏。后来加了一条规则排除条件必须有 0.9 以上的置信度才能进检索条件。同时模型生成的所有排除条件在粗排阶段还要再做一次“宽松化”——不是直接过滤而是给带排除属性的商品降权让它在精排阶段再被真正淘汰。这套“先降权、后过滤”的机制大大降低了一句话理解错导致全盘皆输的风险。4.3 坑三生成式召回和粗排之间的“理解断层”生成式模型解析得再好如果下游的粗排模型不能理解这个结构化描述效果也会打折扣。我们的粗排模型原本是基于向量相似度的它只知道“Query 编码向量”和“Item 编码向量”之间的夹角。但生成式模型产出的结构化描述不是单纯的文本它是一组有逻辑关系的条件簇。直接把条件簇拼成文本丢给粗排模型等于把已经结构化的信息又重新打散成了模糊的序列损失非常大。所以我们调整了粗排模型的结构在输入层增加了结构化特征。我们把生成式模型输出的品牌、类目、价格带、风格、场景等字段单独编码成特征向量跟原有的文本向量拼在一起再输入粗排模型。这个改造让粗排模型能够“看到”生成式模型的分析结论而不是只看到一句话。上线之后粗排到精排的流转率明显提升。4.4 坑四线上延迟抖动超时导致大量请求走兜底生成式模型不管怎么轻量化都会增加一部分延迟。特别是第二层 LLM虽然只覆盖 20% 的流量但碰上峰值时段还是会在 P99 延迟上产生明显抬升。我们的应对思路是“降级不等于放弃”LLM 调用一旦超过 50ms就直接放弃生成让请求降到第一层轻量模型如果轻量模型也超时再降到最后一级纯规则兜底。这样保证 P99 延迟不穿底线同时长尾 Query 在非峰值时刻仍能享受生成式召回的增益。这里有个经验值得强调在做生成式召回时一定要给链条每一层都设计降级路径。因为生成式模型跟传统检索模型不一样它天然带有不确定性超时、异常、幻觉都是常态不是偶发。4.5 踩坑小结一遍遍调整之后我们沉淀的四条原则经过几轮迭代我们把踩坑的经验沉淀成了四条“军规”现在团队里任何新同学上手都得先过一遍这个:生成结果必须有置信度不能用“我觉得”代替“数据说”。每个字段、每个条件都要可量化、可过滤、可降级。生成式召回是“增强”不是“替代”。它给传统召回提供方向性指导而不是试图包办一切。结构化的中间表示是灵魂。只有把生成结果结构化才能让它真正变成可执行的检索条件而不是另一段模糊的自然语言。线上稳定性优先于单点效果。任何一个想上线的模型先证明自己“不会闯祸”再证明自己“很有用”。5. 不止于搜索生成式召回对推荐、广告等场景的复用思路5.1 推荐场景从“猜你喜欢”到“替你表达需求”生成式召回这套思路其实不止能用在搜索。推荐系统里也有类似的痛点用户没有主动输入 Query系统只能靠行为历史来猜。但行为历史是稀疏的、多义的、充满噪声的。比如一个用户最近看了很多篮球鞋但可能只是在帮朋友挑礼物。如果推荐系统直接按照“篮球鞋”这个品类去推大概率推不到点子上。但如果我们用生成式模型去推断用户的**“当前潜在意图”**生成一个类似“送礼场景、预算千元、偏实战”的结构化描述再基于这个描述去召回商品推荐的准确率会高很多。这块我们还没有完全落地但已经在做方向性验证了。初步结果看用生成式召回替代一部分纯行为序列召回在挖掘新意图方面的优势非常明显。5.2 广告场景创意文案与定向条件的自动生成广告系统里生成式召回还可以做一件很有意思的事自动生成定向条件。传统广告定向是广告主自己设定人群标签、地域、年龄段、兴趣分类。但很多中小广告主根本说不清自己的目标人群是谁。这时候可以用生成式模型把广告主的落地页内容、商品信息、历史转化数据作为输入自动生成一串“目标人群描述”再把这串描述转成定向标签。这跟搜索里的“Query 解析成结构化条件”几乎是一个逻辑。本质都是把人的模糊表达翻译成机器可执行的精确条件只是输入和输出的形式换了一下而已。5.3 供应链与运营场景商品标签的自动补全还有一个比较意外的复用方向商品标签自动补全。生成式召回里有一个基础环节是把商品的原始信息标题、描述、图片识别的结果转化成一个完整的“商品特征描述”。这个特征描述不光能用于检索还能反哺商品的标签体系。比如得物上有大量潮流单品标题可能只写了“某某品牌联名鞋款”但生成式模型可以根据它的详情页描述、社区内容补全出“街头风、复古感、限量、高帮、深色系”这些标签。这些自动补全的标签不仅能提升召回效果还能让运营在做专题、做活动时更容易选品。5.4 但别急着照搬三个前提条件必须具备如果你想把这套方案迁移到你自己的场景里我觉得有三个前提条件必须具备你的场景里存在“结构化可枚举的约束维度”。比如品牌、类目、价格、颜色这些字段在商品数据里是存在的、可查询的。如果商品数据本身就是一堆无结构的文本生成式召回的优势发挥不出来。你的用户表达里存在“隐含需求”。如果用户的搜索词都写得很直白比如“耐克篮球鞋”那生成式召回带来的增量有限传统向量召回基本够了。你有能力承担一部分不确定性的调试成本。生成式模型不是确定性算法它需要你有一套完整的置信度、降级、监控机制去兜底。如果你连基本的 A/B 实验能力都没有建议先把地基打好再上这个方向。6. 效果数据与下一步规划生成式召回的进化路径6.1 目前拿到的结果增量是实打实的但不是“颠覆式”的到目前为止我们的生成式召回方案已经在得物交易搜索全量上线一段时间了。拿到的核心结果如下长尾 Query 的需求满足率提升约 9 个百分点。整体搜索成交转化率相对提升约 6%。P99 延迟控制在要求范围内核心链路无明显劣化。覆盖线上约 20% 的长尾流量这类流量的召回相关性提升尤其明显。说实话这个增量没有到“颠覆式”的程度但它是实打实的增量而且主要来自于过去向量检索完全覆盖不到的那部分长尾流量。对于搜索这种已经很成熟、提升空间极度收窄的系统来说这个量级已经相当可观了。6.2 技术上最大的转变从“Embedding 一切”到“结构化一切”我个人感受最深的技术转变是团队对“向量检索”这件事的认知发生了根本性的变化。前两年大家都信奉“Embedding 一切”觉得万物皆可向量化所有语义都能映射到向量空间里。这个思路确实解决了很多问题但也把很多问题“糊”在了向量距离里——你说不清模型为什么觉得这个商品相关也说不好哪些维度贡献了相关性。生成式召回的思路逼着我们回到“结构化”这个老路上来。不是因为结构化更简单而是因为结构化更可控、更可解释、更容易优化。向量负责模糊联想结构化负责精确约束两者结合效果远好于只押注任何一边。6.3 下一步规划从“生成召回”到“生成排序”再到“生成交互”当前我们做的还是“生成召回”下一步有三条线在规划里生成排序利用生成式模型产出 Query 的核心需求点在 LTR 阶段直接作为特征输入让排序模型更清楚用户真正关心什么。生成摘要在召回结果里自动生成商品的“推荐理由”沿着“你搜的‘送男友’→ 这款鞋的‘实战性能’→ 适合场景”的逻辑链去解释为什么推荐这个商品。生成交互用生成式模型做“多轮澄清”。当系统不确定用户意图时主动生成澄清问题“你是想要实战款还是穿搭款预算大概多少”用提问的方式把模糊 Query 变成明确 Query。这几条线本质都是在把“生成”这件事从召回层往整个搜索链路延伸。我个人的判断是未来两三年里搜索系统的核心竞争力会从“谁能把相似度算得更准”转向“谁能把用户意图理解得更透”而生成式方法大概率会是这个转变的主要抓手。6.4 想对做搜索的同行说别被热门概念绑架回到问题本身最后我想说点跟技术无关但很重要的体会。现在整个行业有一个倾向什么热就卷什么。向量检索热大家都去卷向量大模型热大家都去卷大模型。但我觉得真正高效的做法是回到问题本身——先搞清楚你的系统到底在哪里漏掉了需求再选择合适的技术去补。对我们来说问题出在长尾 Query 的需求理解上所以生成式召回的思路天然合适。如果你的问题出在高频 Query 的精度上那优化的重点可能是精排而不是召回。如果出在商品冷启动上那要解决的问题是内容理解而不是检索策略。技术永远是为了解决问题而存在的。当你能把一个模糊的、口语化的、带潜台词的 Query变成一个精确的、可执行的、结构化的检索条件时你就已经完成了一次范式的跃迁——不是因为你用了生成式而是因为你真正理解了用户想要什么。这个方向我会继续做下去后续如果有了新的阶段性成果再回来跟大家分享细节。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →