生成式召回:电商搜索从向量检索到生成式范式的跃迁 过完年回来好几个做电商搜索的朋友都在聊同一件事向量检索卷到头了。召回侧数据集越加越多向量召回从一路加到四路五路Offline 召回率涨一两个点线上 GMV 纹丝不动。其中有个在得物做交易搜索的同学提了一句说他们内部讨论最多的已经不是“再接一个向量通道”而是“生成式召回”——把召回从“检索”变成“生成”。这个思路我当时第一反应是炒概念吧但后来自己把资料翻了一圈又在一个相近场景里做了一版最小验证才发现“生成式召回”和单纯拿大模型改写 query、再走向量库完全是两回事。这篇文章我想把“得物交易搜索用生成式实现召回范式跃迁”这个标题背后的逻辑、工程落地和坑尽量讲透。先说清楚阅读对象如果你正在做搜索召回、推荐召回或者在想怎么把生成式 AI 接进在线导购链路那这篇文章适合你。我会把向量检索为什么不够用、生成式召回到底怎么做、怎么评估、以及我在实操里踩过哪些坑按我自己的复盘顺序写出来。文中涉及的架构取舍和参数更多是面向通用电商搜索场景的合理实践补充不是得物内部口径但足够让你拿去在自己系统里推演一遍。1. 先想想清楚为什么交易搜索里向量召回实际上不够用了这个章节很多人会跳过但我觉得恰恰是最值得先掰开揉碎的地方。毕竟“召回”在传统搜索引擎里是个成熟概念最近几年又被“向量检索”重新定义过一轮。你得先搞清楚旧范式为什么失效才能理解为什么“生成式召回”不只是在给召回加一路。1.1 我理解里“召回范式”的变迁过程我自己习惯把搜索召回的发展分成三个阶段。早期阶段是倒排索引召回也就是把用户输入的词切分后去和商品标题、品牌、类目这类文本字段做精确匹配或 BM25 相关度匹配。这个阶段的好处是可控、可解释坏处是遇到同义词、口语化 query、粉丝圈黑话就抓瞎。“倒钩”这个在球鞋圈几乎是标配的词如果商品标题里写的是“反钩设计”“Swoosh 倒置”纯倒排是永远匹配不到的。第二阶段就是大家都在做的向量检索。把 query 和商品文本分别编码成向量然后在向量空间里找近邻。它的本质还是“点到点的匹配”只是匹配空间从词表换成了语义空间。向量检索确实解决了一部分同义改写的问题比如“倒钩”和“反钩设计”在向量空间里可能距离很近可以被召回。第三阶段就是标题里说的“生成式召回”。它不是去一个已经建好的索引里找相似的东西而是让模型生成出一组“符合用户需求的商品描述、物料标识或者查询条件”再用这组生成结果去反查候选集。这个区别我觉得是整个范式跃迁的关键。1.2 向量检索在电商交易搜索里的四个天花板即便向量检索已经成了标配我还是在交易搜索里感受到了几个比较实际的局限。第一个天花板是“无效长尾”。用户搜“夏天的第一双鞋”或者“生日礼物送男生 2000 块”这类 query 的表达不在训练集里向量召回经常只能召回到一堆泛泛的品类命中率和业务价值都很低。第二个天花板是“结构化属性查询”。交易搜索和网页搜索最大的不同是用户很多时候是用“款式 价格 尺码 品牌”多条件组合来找商品。例如“AJ4 白绿 41 码”这种 query 对向量检索不太友好向量没法精确约束“41 码”也没法保证“白绿”指的是配色而不是别的意思。向量检索擅长模糊相似不擅长精确的属性推理。第三个天花板是“商品物料更新特别快”。得物这类平台新品、限量款、联名款上架节奏很快新品的文本描述往往很短部分跨境商品甚至只有一张图。向量模型如果需要重新训练才能认识这些新词那召回侧的更新周期就会拖累整个搜索链路。第四个天花板是我在做推荐系统时才慢慢摸出来的向量召回通常会把问题退化成一个“最邻近搜索”而交易搜索的目标不是“相似”而是“成交”。用户可能想要的是某种生活方式、某个人的同款穿搭、或者某种品牌联名背后的故事这些东西很难全部压缩进一个固定维度的向量里。向量空间能表达相似但不太擅长表达“组合条件”和“推理事实”。1.3 生成式召回解决的是哪个具体痛点那么“生成式”到底补了向量检索的什么边角我自己总结是四个字可控组合。生成式召回在模型内部其实是在做一个“约束求解”输入用户的自然语言 query输出一组结构化的搜索意图、属性约束、甚至直接虚构出一个候选商品编码。这个过程和向量检索有本质区别因为模型不需要依靠“找一个库里的近邻向量”而是可以把知识库里的概念拆开、重新组合得到库里面前没有显式出现的组合。你搜“薄荷绿配色的 AJ 编辑推荐”传统向量检索大概率凉掉因为没有任何一个商品标题同时包含薄荷绿、AJ、编辑推荐。但生成式召回可以把“薄荷绿”、“AJ”、“编辑推荐”拆成三个独立约束再根据知识库推理出一个候选集。这就是“找候选”变成“编候选”的核心变化。2. 生成式召回的核心设计用“知识坐标”替代“向量距离”“生成式召回”这个概念听上去很高级但真正落地成工程方案时你得把它拆得足够细。这一节我会从原理、实现路径、以及和向量检索的对比这几个角度展开这也是我觉得最容易看出范式的差别的地方。2.1 向量检索与生成式召回的原理性比较先摆一张对比表方便大家直接看区别。维度向量检索生成式召回核心操作将 query 和 item 编码为向量最近邻检索基于知识条件生成候选约束或候选 ID查询表达固定维度的向量结构化意图、属性组合、自然语言改写组合能力弱依赖语义近似强可以把不共现的属性解耦后重组可解释性弱只能给相似度分数相对较强能追踪生成链路和约束依据对实时新品的响应取决于 Embedding 模型更新周期取决于知识库和索引的刷新系统复杂度中等向量库和模型服务成熟较高要引入生成服务、解码约束、知识索引从这个表里能读出关键的一条向量检索的核心解决方法是“压缩”生成式召回的核心解决方法是“推理”。交易搜索里有很多复杂的组合条件推理比压缩更吃香。2.2 第一种实现路径先“生成意图”再走传统检索生成式召回并不是说一定要让模型直接生成商品 ID。目前最常见的做法是做一个“生成式查询理解模块”。输入用户 query 后模型不是直接去向量库找近邻而是先生成一组结构化的意图和属性核心类目如“球鞋/板鞋/跑鞋”品牌约束如“Nike / Air Jordan”视觉语义如“黑色鞋面白色中底”价格带如“1000-1500元”场景标签如“通勤”“送礼”“穿搭”商品卖点如“联名款”“限量款”这一步可以理解为把用户一句话拆解成知识库里的“属性坐标”。生成完这些属性约束后系统再去倒排索引或属性数据库里执行一次“确定性查询”。所以整个链路是“生成式理解 传统检索”在线改写的成分居多。我当时自己写过一个比较粗糙的伪代码核心逻辑大概是这个样子def generative_recall(query): intent generation_model.generate(query, modeintent) # intent { # category: [sneakers, lifestyle], # brand: [nike, air_jordan], # color_way: {upper: black, midsole: white}, # price_range: [1000, 1500], # scene_tag: [gift, streetwear] # } constraint_query build_constraint_query(intent) candidate_ids inverted_index.search(constraint_query) # 再用轻量向量检索引擎做扩展召回 similar_ids vector_index.search(query, top_k200) return merge(candidate_ids, similar_ids)这套路径的好处是工程改动小在线检索阶段完全复用现有系统坏处是它本质还是个“查询改写器”没有完全跳出“匹配”的框架。如果用户的 query 里的属性没法被意图模块完整捕捉那召回结果依然受限。2.3 第二种实现路径直接生成候选 ID 或候选物料第二种路径我个人觉得才配得上“范式跃迁”这四个字它也是我在复盘里花最多时间研究的一环。这套做法里模型不再只做意图分析而是直接输出一列商品 ID 或者组合后的商品描述。举个例子知识库里有一批商品 ID每个 ID 背后关联的是一组属性描述“D-0001234AJ4 白绿41 码2023 年发售中帮”。生成式模型在解码阶段不是从头自由发挥而是从候选字典中选择合法的 ID 片段组成一个商品 ID 序列。这样生成的每一步都带有知识库的“先验”而不是拿着一串随机 token 去匹配。这种模式下倒排索引反而是辅助了。系统真正依赖的是一个“商品 ID 词汇表”和一个“生成模型”。在线召回时模型根据 query 直接生成若干个可能满足需求的商品 ID然后送到商品中台校验再进入粗排。这在技术圈里对应的术语是“基于生成式检索的推荐”在搜索侧也类似于“直接生成文档 ID”。我自己的判断是直接生成物品 ID 适合得物这类“商品库规模可控、属性维度高、物料生命周期短”的垂直平台。如果是淘宝那种几十亿商品级别的通用搜索直接生成 ID 的词典太大解码效率和准确率都会出现问题。所以不同平台确实得选不同的落地路径。2.4 可控解码是生成式召回的技术基石既然“生成”这么自由怎么保证模型不胡言乱语呢这里的关键在于解码策略。我得先反驳一个观点生成式召回不是“让一个没有审核的 AI 随便发挥”。相反生产环境里要做非常严格的受控解码。具体做法是在 Beam Search 或者采样解码时给每一步接入一个“合法前缀校验器”。比如商品 ID 的词汇表里根本没有“888888”那解码到中间步骤就会被直接拦截。再比如模型想生成一个不存在的配色组合“荧光紫配夜光鞋底”知识库校验器发现这个组合没有对应物料也会把这条路径的分数压低。我见过不少团队一看生成式召回效果好就把解码放宽结果线上出现一堆“编出来的商品”——标题里从来没有、库里也不存在的货。这其实不是模型的问题是工程上少了受控解码和校验这一环。“无限制、无审核生成式 AI”这个标签在内容创作领域可能是个卖点但在交易搜索里它是最危险的隐患没有之一。3. 工程落地实操从商品知识库到在线召回服务聊完原理接下来是工程人最关心的环节这玩意儿到底怎么落地到线上。这节我会按离线数据准备、在线请求链路、和已有检索体系协同、以及存储选型四块来讲尽量贴近实际可操作的程度。3.1 离线预处理把商品库整理成生成器可消费的“知识坐标”生成式召回和传统排序模型最大的一个区别是它对数据结构的整洁度要求很高。如果你的商品库只有“标题 类目 品牌 价格”那生成式模型基本发挥不出来。它需要的是“多维知识坐标”。我在实际项目中通常会先做一次商品知识抽取把每个商品转成一组字段基础属性品牌、类目、价格、性别、上市年份外观属性颜色、材质、图案、鞋型/版型卖点属性联名对象、限量编号、设计师、系列名场景属性适用运动、穿搭风格、城市机能、通勤同义词与黑话比如“倒钩”关联到“反钩设计”这一步的产出就是“商品知识库”。它是生成式召回的底座。没有这个库生成式召回生成的约束条件没有任何锚点。知识库的构建可以用文本抽取、图像识别、人工标注组合完成不用追求一次做到 100% 准确但是覆盖率和更新时效一定要高。3.2 在线请求路径query 解析、约束生成、候选校验在线链路我会拆成 4 步。第一步是轻量意图路由。用户 query 进来后先用一个轻模型判断 query 类型是“品牌词”“品类词”“场景词”“穿搭词”还是“多条件组合”。这一步不需要大模型甚至可以用规则但能明显降低后面生成模型的压力。第二步是生成约束序列。将 query 送入生成模型输出结构化的约束序列。注意这里输出的单位不是拼音或词语而是“知识库键值对”。例如 “categorysneakers” “upper_materialleather” “color_waymint_green”。这个过程把生成问题转换成受限的键值对预测问题比自由文本稳定得多。第三步是候选初筛。用生成的约束序列去属性倒排索引里做精确查询拿到一批严格满足条件的候选商品 ID。由于约束条件可能过严系统还要做一次“放松校验”比如允许某条属性缺失只保留其他主要属性。第四步是候选校验与融合。把生成的候选、以及原本几路向量召回、关键词召回的候选做一个融合。这一步和传统融合不太一样的是生成式召回出来的候选通常带“约束来源”比如“因为命中了 mint_green 这个颜色坐标”所以在融合时可以有逻辑依据地分配权重而不是单纯看相似度分数。3.3 与现有向量召回、倒排召回怎么协同我在实践里的结论是生成式召回不是来替代向量检索的而是用来做“头部求解”的。什么叫头部求解就是专门处理最复杂的、意图最明确的、成交可能性最高的那部分长尾 query。举一个我在项目里经常用来和同事对齐的比喻向量召回像个大网能把鱼捞个大概倒排召回像个钩子能精准钓到明确的目标生成式召回像一个熟练的渔夫看一眼水面的波纹就知道该往哪里下钩甚至能把两三种鱼的特点组合起来去推测水下可能有的品种。所以上线时我一般会这样协同保留 2-3 路向量召回作为基础流量保障保留至少 1 路倒排召回处理品牌词和型号词新增 1 路生成式召回只处理经过意图路由判定为“复杂组合、黑话、场景化”的 query在融合层给生成式召回设置动态权重初始 0.1在线效果稳定后再逐步上调。这样做的好处是风险可控。生成式召回的增量效果可以被单独拆出来评估而不用一上来就承担全部召回流量。3.4 存储选型向量库不是唯一选项别被“知识库”三个字绕晕很多同学一听“知识库”第一反应是要不要去搭一套专门的向量库数据库。这个理解其实有点偏差。生成式召回的在线链路里存储需求可以分为三层第一层是“词表与属性字典库”用来支持受控解码的合法前缀校验。这层数据量不大用 Redis 或者内存哈希表就行不需要上数据库。第二层是“属性倒排索引库”用于执行约束条件下的候选初筛。这个可以用开源检索引擎或者现有的商品搜索索引不一定需要专门为生成式单独建一套。第三层才是“语义向量的近邻库”主要给向量召回占用的也就是大家理解的“向量数据库”。它可以继续沿用团队现有的基础设施比如 pgvector、Milvus、Elasticsearch 的向量能力都可以关键是和生成式召回的服务之间要有统一的商品 ID 对齐。所以为什么要问“向量库检索需要什么数据库”因为很多方案讨论到最后其实就是两套数据一套是给向量计算用的索引数据一套是给生成器做约束的键值数据。前者适合用成熟的向量数据库后者更适合用高性能 KV 和倒排索引。把这两个概念分开架构就能清晰很多。4. 评测与上线不能再用老指标“骗”自己生成式召回的评估是我认为最容易被低估的环节。很多团队喜欢用离线召回率一个指标拍脑袋上线结果线上效果一塌糊涂。这里我把评估体系拆成离线、在线、以及灰度回退三个层面。4.1 离线评估除了召回率还要看“意图生成准确率”传统的召回评估一般是看 RecallK。但生成式回调和传统召回不一样它比“集合覆盖率”更重要的是“生成质量”。我建议在离线阶段至少看三个指标意图生成准确率模型生成的约束条件里有多少是能正确解析的。例如 query 是“AJ4 白绿”生成结果里如果出现“color_waymint_green”就算正确如果出现“price_range1000”就是多余错误。约束冲突率生成的多个约束条件之间是否存在矛盾。比如“高帮”和“低帮”同时出现或者“价格区间 1000-1500”和“折扣现价 500”冲突。有效候选率生成的候选经过属性校验之后最终有多少能通过。如果通过率低于 60%说明模型在“编造”而非“召回”需要调整解码约束。你可能会发现这些指标比单纯算 RecallK 严格得多但恰恰是这些指标能暴露生成式模型的真实水平。我当时刚开始跑第一版时有效候选率不到 50%线上当然不敢放量。4.2 线上评估把召回效果映射到业务指标上离线实验再漂亮最后还是要看线上成交。但这里有个陷阱生成式召回只是链路前端的一路召回它不能直接决定排序所以单纯看整体 CVR 和 GMV 很容易把增量和噪音混在一起。更合理的做法是先看“增量召回曝光率”也就是生成式召回带来的、原本其他路召回都没发现的商品在最终曝光列表里占了多少比例。再看这部分曝光商品的点击率和成交转化率是不是显著高于大盘。如果增量曝光商品的转化率和大盘持平说明生成式召回的精准度OK如果转化率明显更低那可能召回是“乱广撒网”对排序层造成了负担。4.3 灰度过程与回退策略生成式召回上线我强烈建议走 1% 流量灰度并且灰度分组要和“意图路由”解耦。具体做法是先全量接入意图路由但只有 1% 的流量真正使用生成式召回其余流量仍然走原来的多路召回。同时记录生成结果日志和 99% 流量里的同 query 的召回结果做差集分析。这样一边灰度一边看差集能比较快地知道生成式召回强在哪类 query弱在哪类 query。回退策略也很简单如果增量曝光商品的成交转化率低于大盘超过一定比例或者生成服务延迟 P99 超过 120ms直接一键关掉生成式召回开关流量回归到原有多路召回。不要把回退做成“下线模型”做成“降级到旧链路”就行。毕竟模型训练成本摆在那里因为一次延迟抖动就下线重新训练代价太大。4.4 冷启动和探索策略生成式召回也有自己的冷启动问题。当一款新品上架知识库里还没有足够丰富的属性描述时生成模型很可能把它漏掉。所以我们当时还会保留一个“探索补充查询”在生成约束之外再加一批“相近类目候选”保证新品的曝光机会。这个做法有点像是在精确和探索之间做平衡不能全靠生成器一条路否则冷启动物料会越来越冷。5. 一路踩坑复盘最容易翻车的几个准备不充分的地方最后这部分我把自己真正踩过或者观察到的坑集中写下来。做生成式召回踩坑是常态关键是别在白骨堆上反复跌倒。5.1 “不受控生成”是最大的运营风险也是最大的公关风险前面我说过生产环境必须受控解码。这里我想再补一个容易被忽略的层面审核。生成式召回虽然不一定面向用户直接输出文案但模型内部如果生成出一些不适合的约束条件比如某些敏感词或错误物料经过后续链路放大依然可能出现在推荐理由、搜索提示等 To C 位置上。所以在生成器和前端之间必须加一道“输出内容安全过滤”用关键词名单加语义分类模型双重校验。这里没有技巧就是笨功夫但能挡住很多不必要的麻烦。千万不要觉得“只是内部召回不直接展示所以不用管审核”。5.2 知识库冲突比模型效果更致命生成式召回依赖的知识库如果本身存在冲突你会看到一些非常诡异的召回结果。比如知识库里有一个商品既被标成“男款”又被标成“女款”或者同一个商品 ID 的配色字段和标题描述对不上。生成器在解码时按知识坐标走一旦坐标错了候选就越跑越偏。这个问题的解法也只有从源头下手在商品知识抽取后加一轮一致性校验对每个商品生成“字段置信度”字段置信度低于阈值的商品不进入生成式召回的可选集合宁缺毋滥。5.3 延迟和成本生成式确实比检索贵一个量级生成式召回在进行 Beam Search 解码时每一轮生成都涉及多次模型前向计算耗电量、GPU 占用和延迟都远超向量检索。所以要想办法把生成服务做成“异步候选补齐”而不是同步主链路。比如主搜索链路先并行跑向量召回和倒排召回生成式召回作为一个并行分路超时或者未完成就降级不让 P99 被拖垮。我自己的经验做法是生成服务用一个小模型解码层数不用太高Beam Size 控制在 4 到 8同时配合缓存把高频 query 的生成结果缓存下来。实测下来模型推理压力能减少一大半。毕竟用户搜索词重复度在交易场景里其实很高缓存命中率往往比想象中好很多。5.4 团队心智向量检索要退场吗最后聊个偏“范式”的话题生成式召回到底是不是向量检索的终结者我现在的回答是至少三年内不是。生成式召回擅长的是把复杂意图拆解开再重组向量检索擅长的还是在海量候选中做相似覆盖。两者能力有重叠但更多是互补。对一个搜索团队来说真正重要的不是押注某一类召回技术而是想清楚自己的商品数据和用户 query 形态更适合哪一种范式。如果像得物这样商品库属性丰富、用户圈层黑话多、长尾组合 query 占比高那生成式召回的投入产出比会很高。如果是一个纯 UGC 内容平台query 和文本都非常开放那向量检索继续深耕的性价比可能更优。说实话我第一次看到“别再只卷向量检索了”这个标题时第一反应是偏见。真正动手做完一版生成式召回验证后我才意识到它最迷人的地方不在于“生成”而在于把召回从“匹配”提升到了“推理”。这个过程有点像把搜索引擎从记忆型选手变成思考型选手。如果在实际场景里你想从 0 开始验证这套思路我给的建议是三条第一先别动线上架构离线跑一个“受约束生成 属性校验”的模拟器第二先把商品知识库的一致性和覆盖率补到位第三评估指标里一定要加“有效候选率”和“意图生成准确率”别只盯着召回率。跑通了这三步再谈范式跃迁会少踩很多坑。