
说实话这两年做搜索的人很难不焦虑。向量检索刚把召回从“关键词匹配翻篇”带到“语义向量匹配”的下一章大家还在研究 HNSW 的参数怎么调、向量库到底用 faiss 还是选分布式引擎结果又一种更新的玩法开始出现生成式召回。它不是在索引里找商品而是真正“生成”商品标识或商品的属性组合把用户需求直接翻译成一组商品描述符。最近看到得物交易搜索在这块做的东西挺有代表性的也很适合拿出来讲透为什么说这已经不是工程优化而是召回范式的一次跃迁先说我的结论生成式召回不是来“替代”向量检索的两套方法的底层逻辑都不一样。向量检索做的是连续空间的近邻逼近生成式召回做的是离散空间的组合生成。前者是“搜一个近似答案”后者是“生成一个答案结构”。对交易搜索这种强效果导向、库存动态变化快的场景后者能补上很多前者天生就有的洞。这篇文章我会从一个搜索从业者的视角把这套玩法从头拆开。适合正在做推荐、搜索和广告召回的同学也适合想搞明白“生成式检索到底怎么落地”的工程师。我会把原理、商品表征方式、训练细节、线上部署、评估方法和踩坑经验都铺开讲尽量做到能直接对着复现。我当年带团队做向量召回时遇到最头疼的就是两件事长尾需求覆盖不住新品的冷启动非常尴尬。这两件事恰好是纯向量召回在交易场景的结构性问题。1. 为什么“向量检索”在交易场景里不再够用1.1 从“关键词匹配”到“向量检索”到底改了什么传统搜索召回阶段核心是倒排索引加词法匹配。用户搜“男生潮流套装”检索系统先分词再取“男生”“潮流”“套装”三个词的倒排链做交集或并集。这个逻辑直白但也有硬伤用户表达稍带口语或者语境偏移比如搜“去见女朋友穿什么”关键词召回基本直接懵了。向量检索解决的问题正是这里。把 query 编码成一个向量把商品也编码成一个向量然后通过向量距离近似找语义相近的候选。它能泛化到“没提关键词但意思相近”的场景这是它的革命性。但与此同时向量检索引入了一个隐含假设语义相似约等于用户想要。这假设在资讯搜索、社区搜索里成立度很高但在交易搜索里恰恰不是这样。用户在交易搜索搜“男生潮流套装”他大概率不是想要“语义上相似的任何套装”而是想要“合适的尺码、合理的价格段、最近上新的款式、符合他审美偏好的品牌”。这里面有大量结构化约束向量空间表达不了那么细。1.2 交易搜索的三个特殊性长尾、新鲜度、结构化约束交易搜索和通用搜索有三个非常大的不同第一行为意图高度结构化。用户搜“运动鞋”他不是对一串文本感兴趣而是对“品类运动鞋”“价格某个带”“品牌偏好xxx”这些属性组合感兴趣。向量 embedding 把这些属性混合压进一个稠密向量里表达能力是有损耗的。我举个实际例子同一个 query 向量经过训练后可能把价格敏感用户和品牌敏感用户的表达混在一起线上召回出来的候选两边用户都不满意。第二新鲜供给必须快速进入可召回状态。商品库每天都在上新如果一个新品的向量没有得到充分训练那它在向量检索里的位置就很随机。按我见到的实际情况新品在 faiss 里有时候会落到一个和需求完全无关的邻居簇里。商品向量需要行为信号的滋养可是新品恰恰没有行为数据。第三长尾需求不是长尾文字而是长尾组合。每个词都不冷门但组合在一起就冷门。比如“宽松落肩美式复古重磅T恤”五个词分开都很常见合在一起其实是一个高度具体的结构化需求。向量检索对这种组合的捕捉能力取决于训练语料里有没有类似的 pair通常非常缺。这就直接引出了向量检索在交易场景里的“天花板”。它不是某一家的问题是这一范式在特定场景下的天然边界。那怎么办答案不是继续卷向量网络结构而是换一条路从“检索范式”切换成“生成范式”。2. 生成式召回换一种思路重构“召回”本身2.1 什么是生成式召回从“挑商品”到“写商品”传统召回的所有路径本质都是在做同一件事给定一个 user query在既有商品库中挑选 top k。无论是倒排、向量、图召回底层都是“选”。生成式召回把这件事彻底换了个角度它不直接选商品而是先生成关于商品目标的描述——可能是商品 ID可能是类目加属性组合再通过这个生成结果去圈定候选集。用一句话概括从“找一个最像答案的槽”变成“写出一段答案的描述”。这在范式上有本质差别。检索的选上限受索引质量和向量空间表达能力限制。生成的写从原理上可以组合出库中不存在于训练样本里的新组合比如混合两个类目的商品属性再映射到真实商品上。这相当于把召回从“记忆行为”升级成了“推理行为”。我做过的实验有个案例很典型。用户搜索“毕业典礼送的礼物”库里其实存在“领带”“钢笔”“香水”这些商品但没有任何训练样本把这个 query 和这三个类目同时连接起来。向量检索很可能只召回其中一个模糊匹配类目而生成式把一个商品序列生成出来例如“领带 钢笔 摆件”每一路都是这个 query 下的合理结果。这就是组合化能力。2.2 为什么它能实现“范式跃迁”而不只是又一个召回通道我理解“范式跃迁”这四个字不是新模型换个精度而是整个系统对问题的建模方式变了。原来我们的建模方式是query 和 doc 各做一个表征建立“匹配函数”。整个体系的优化全花在表征和匹配上。生成式召回换成了query 为主体商品候选作为“语言序列”输出。商品库结构不是先验索引而是在模型参数里形成目标分布。这个转换带来的直接收益是约束从“向量空间里找点”变成了“生成空间中规划序列”。前者是自由形式的几何问题后者是带语法的编译问题。交易搜索刚好有明确的商品 schema比如类目、品牌、价格档位、尺码这些结构正好就是生成约束的来源所以交易场景落地生成式召回会特别顺手。2.3 与知识库、向量库检索的边界不是替代是互补这一节我想特别说明一下生成式召回和“知识库 向量库 RAG 检索”并不是一回事。很多同学看到生成式和搜索第一反应是 RAG。但 RAG 里生成模型做的是“阅读并组织答案”向量库提供的是“检索事实”。生成式召回里生成模型本身就是检索器它直接产出候选商品标识不走向量库这一步。两个系统的组合关系是生成式召回负责“生成可能性”向量检索负责“扩大语义覆盖”知识库负责提供结构化商品属性。实际线上系统就是把生成式召回的候选、向量召回的候选和传统关键词召回的候选全部拿来做融合排序各干各的活。3. 商品表征生成式召回最关键的工程决策3.1 生成目标选什么是商品ID还是属性序列做生成式召回第一个绕不过去的决策是到底让模型生成什么。我见过三类做法第一类是直接生成商品 ID。把商品集合每个定义成一个唯一 token模型训练成从 query 映射到商品 token 的序列。严格来看这一类接近业界说的“生成式检索”模型输出的就是一个离散的商品标识符。优点是简洁不需要考虑商品内部结构缺点是商品库更新就要改词表模型几乎无法对库外商品泛化对品牌和类目也没有可解释性。第二类是生成商品属性的序列。模型输出依次为“类目关键词”“品牌”“价格带”“关键属性”。比如用户说“千元以内的经典款女表”模型生成的序列是“手表 女表 价格带500-1000 大牌同款”。用这个序列去转换商品库里所有符合表达的商品。可解释性很强新品也能被覆盖但对解码准确率要求很高一步错了后续就全乱。第三类是混合目标。前若干个 token 生成类目和属性最后一到两个 token 生成具体 item id。工程上更容易实现是 I know works better 的折中。就我实际经验看交易搜索更推荐用第二类和第三类的混合体。直接生成 item id 会陷入和倒排索引一样的“记忆库”反复召回头部爆品长尾需求仍然解决不了。属性序列方式则能给新品留出发挥空间库中只要有符合属性的商品不管有没有行为数据都能被捞出来。3.2 商品属性空间怎么压缩分档、量化与码表设计生成属性维度的前提是要把膨胀的属性空间压缩成模型能学的离散词汇。以购物搜索场景为例单是“品牌”就有上千颜色有几十价格更是连续值。如果直接用原文生成模型会被稀疏性打垮。做的时候我建议先把商品 Schema 里每个字段做量化编码。价格切成若干档位按商品客单价分布找分位点比如“0-99”“100-299”“300-999”等品牌先归并成头部品牌加“其他品牌”的兜底项颜色映射成标准色板风格、领型这类文本属性用标签化处理。经过这一步一个商品可以表达成 M 个属性槽的 token 序列。模型输出的长度就是属性槽的个数加一个终止符。这个设计有一个额外好处可以将解码过程约束到只从每个属性槽的词表选 token配合约束解码误生成概率会大幅下降。我自己做的时候在解码约束前后比较过约束后整句合法率从 72% 提到了接近 97%。3.3 从商品到序列训练样本怎么构造有了表征方案下面就是造训练样本。核心是建立(query, 商品属性序列)的平行语料。来源有三个第一搜索行为日志。用户搜索 query之后点击购买的 item把 item 转成属性序列直接成为一对训练样本。需要做去噪短曝光、误点、停留过短这些行为要滤掉。第二商品详情页的推荐流量。用户在一个商品停留很久后跳转到另一商品这种“共现”行为也能用来构造松散的 query-商品关系。但这条路的样本噪声更高建议只做辅助数据。第三基于商品属性的自动构造。把商品库里的每个 item 生成描述文本再把属性序列的前半段做 masked 语言模型预训练让模型学商品描述的通用语法。除了这些我还会加一层数据增强对已有 query 做同义词改写、属性值替换、类目升降级。因为在线真实 query 分布极端分散不增强模型会学得非常偏向头部 query。4. 模型选型与训练要点别盲抄NLP的作业4.1 网络结构选择为何不必非上大模型很多人一听到“生成式”就第一反应是上大模型上各种LLM。但交易搜索召回侧要考虑两个硬指标服务延迟和成本。召回链路每多 1ms 都影响整体体验生成式模型如果解到几百毫秒根本没法上线。我建议优先用一个轻量级的序列到序列模型做主体规模在 200M 到 500M 参数之间。结构可以是 Transformer encoder-decoder也可以直接用一层浅层 decoder 加 prefix encoder。核心不是模型多大而是有没有把商品表征和生成约束做对。工业界的主线工作证明了轻量 seq2seq 能在召回任务里跑出不错指标性价比远高于直接套大模型。4.2 训练数据平衡头部样本与长尾样本的冲突如果直接拿行为日志样本分布来训模型会收敛到一个“只会记住爆款”的状态。短尾 query 因为频次高训练更充分生成结果几乎都是高频商品长尾 query 则因为样本太少生成结果质量很差。解决方法是加一个重采样策略。对 query 出现频次做对数降权让低频率 query 的样本权重相对抬高同时对商品侧做“去曝光偏好”比如一个商品被反复点击导致样本量暴增就按商品曝光的概率做下采样。做完重采样后长尾样本占比会明显提升离线指标里“尾query召回率”涨得很明显。4.3 解码策略贪心、束搜索与约束解码的区别训练完之后线上推理时的解码策略直接影响候选生成的质量和多样性。贪心解码速度最快但容易生成保守重复的序列候选之间缺差异性。束搜索稍好可以取 Top N 条 beam 输出得到一个候选集合但束搜索出来的候选择会非常集中在头部语义簇多样性还是不够。我建议用多样束搜索它在保留 beam 的同时加入相似度惩罚让输出的若干条序列落在不同语义区域。解码同时配合属性槽约束每个位置只从当前属性的合法值集合里选 token这就避免了生成出“类目两件套”“把服装品牌放到数码类目”的低级错误。有一点很关键生成式召回的候选不需要生成很多3 到 5 条高质量序列就够了。每条序列经过属性倒排后落到商品库就能映射出成千上万的 item。真正要调的不是 Beam size 这样加码而是序列的“结构合理性”。5. 线上系统怎么做融合、伸缩与可回滚5.1 整体链路生成式召回在哪个位置起作用上线后我的首选架构是这样用户 query 先进 query 分析模块做改写、纠错和类目预测然后同时进入四个召回路关键词召回、向量召回、图召回和生成式召回生成式召回内部模型先解码输出 3 到 5 个属性序列用序列构造候选商品池再走一遍类目约束和基础过滤输出 Top 200最后四路候选合在一处交给粗排精排。这里面的关键思想是生成式召回不要做单路决策而是作为一种高效“新供给发现器”。它的候选和向量召回的候选重叠度通常不高融合后整体覆盖度会显著提升。我用过一个评估指标叫“单路独有召回占比”生成式召回独有商品的占比能到 15% 左右意味着每 100 个最终成交商品里约 15 个是原来任何路都找不到的。5.2 GPU服务与延迟控制轻量解码的工程细节在线服务我建议单独部署一组浅层生成模型用 GPU 做批量 decode。实际生产里这些优化是必不可少的用动态 batch把同时到达的 query 拼成一个小 batch 一起解码能压到几十毫秒query 侧 prefix 做缓存因为同一 query 的编码结果可以缓存复用属性序列的长度很短只有 5 到 8 个 token解码轮次低延迟天然可控服务上做两个副本主副本和延迟容忍副本高峰期直接把召回集降级为贪心解码和属性缓存结果保证整体 P99 不超标。5.3 如何跟踪“召回质量”而不是只看点击率上线后监控指标要分两层。第一层是传统业务指标点击率、转化率、成交额。第二层是召回专属指标包括生成序列的合法率、生成候选池的覆盖率、生成候选和用户点击 item 的对齐率。这里我最看重的指标是“行为对齐率”把用户在某次搜索后的实际点击商品映射回属性序列再看生成式召回的候选序列和这个实际序列做的匹配程度。这个指标能看出模型生成的序列到底有没有理解用户想要什么而不是只靠粗排补偿错误。行为对齐率如果长期低于 40%说明生成式模型基本没学到东西只是给粗排提供了噪声这时候就该回去调数据或表征。6. 得物交易搜索的实践复盘我看到的三个关键跃迁6.1 从“改 query 词”到“生成 query 意图序列”回到标题里的得物案例它不是我把这套方法塞进去而是它本身有值得拆解的实践细节。得物交易搜索明显走了一条“不是单纯用向量检索解决所有问题”的路径而是利用生成模型直接产出商品属性序列。用户的搜索意图并不总是和商品文本描述一致尤其潮流单品大量依赖风格化表达得物用生成式把 query 转译成“类目 属性序列”正好解决了“潮流描述词库不完整”的问题。6.2 从固定属性到面向交易目标的动态生成第二个跃迁和交易指标直接相关。生成式召回的目标不是“和用户 query 长得像”而是“生成能促成交易的商品组合”。体现在细节上训练样本的 label 不只是点击而是加上成交行为。这样模型学到了一个隐性的交易约束比如同一个商品在送礼物场景下可能被选中的是礼盒装和品牌溢价款在自用场景下可能是基础款。这个在纯向量检索里很难做到因为向量空间的监督信号太单一。6.3 从“库内召回”到“库间关联”第三个跃迁是生成式召回天然产生的“跨类目关联能力”。用户在得物搜索一个球鞋但优秀的生成式模型在球鞋属性序列之后可能继续生成与球鞋搭配的服装属性序列。这是原来独立商品召回完全做不到的。候选集因此不再局限在同一叶子类目而是能跨越类目边界找到新的交易可能性。7. 常见问题与排障实录7.1 生成了脏序列怎么办最常遇到的是生成了不存在的类目组合比如“数码-男装-球鞋”这种乱配序列。这类问题主要来自解码位置没做好槽约束。我遇到后的处理办法是在解码器每个位置加一个允许的 token 掩码当前槽位只允许当前类目和该槽位下的合法属性值mask 后基本绝迹。7.2 新品永远生成不出来模型倾向输出训练时高频的商品序列新品属性组合没在样本里出现过很难被解码出来。我给的建议是在线解码完成后对序列里的属性条件再到商品库做一次全量扫描匹配。只要新品的属性落进同一组约束里就能被匹配到不必让模型直接生成新品 ID。这其实就是上一步说的混合目标的用意。7.3 与粗排脱节召回集丰富但成交差会出现生成召回很好、离线覆盖也高但线上转化反而不涨的情况。我排查时发现是生成式召回的候选分布和粗排模型的排序偏好不匹配。粗排是在向量召回样本上训练的生成式召回的候选特征分布在另一片区域导致粗排给的分数普遍偏低。解决办法是把生成式召回的候选加进粗排训练样本做一小段 fine-tune让排序模型对生成路径的候选也有判别力。8. 我认为这套范式未来的两个延伸方向一个延伸方向是往“生成式精排”走。现在的生成式只做了召回如果继续往链路下游推进让生成模型直接产出 Next-Item 推荐、跨商品搭配、购物车套餐这类“行动序列”这套思路会从召回一直贯穿到决策。另一个方向是和多模态融合商品主图、细节图里的视觉属性也能建模进生成序列比方说“图案是卡通印花”“整体颜色是大地色”这些属性用文本来表达有时不够全加视觉 token 后生成式召回能捕捉到更细腻的用户审美。这两个方向我都还没完整落地但从目前试验效果看潜力很大。最后分享一个我自己的体会做搜索做久了很容易陷进“匹配”思维觉得召回就是找相似、找近邻、找最近向量。但交易搜索里用户的真实需求更像一份结构清晰的“购物清单”而不是一团稠密向量。生成式召回的意义不是提供多一个模型多一路候选而是把召回从“相似匹配”提升到了“意图构建”这一层。建议下一阶段有条件的团队可以小范围试一下先把商品表征和约束解码这层地基打好范式跃迁就是从这一步开始的。