拓冰建站拓冰建站
首页 / 资讯中心 / 正文

生成式召回实战:从向量检索瓶颈到多路召回融合的工程落地

1. 从“卷向量”到“生成式召回”的范式转移1.1 为什么传统向量检索在交易搜索场景里越来越吃力做电商搜索的人这两年都有一个共同感受向量检索的边际收益在快速衰减。两三年前把商品标题和属性拼成文本过一遍双塔模型产出embedding往Faiss或者Milvus里一塞再配个HNSW索引召回效果就能比倒排提升一大截。那时候大家比的是谁的模型更大、谁的负采样更讲究、谁的索引参数调得更细。但到了今天你会发现一个尴尬的现实——在交易类搜索里纯向量召回的天花板已经肉眼可见。问题出在几个层面。第一交易搜索的query和商品之间不是简单的语义相似关系。用户搜“夏天穿的透气跑鞋”他要的不只是语义上“透气”和“跑鞋”都匹配的商品而是要在“透气性”“夏季适用”“跑步场景”“价格带”“库存状态”“履约时效”这些维度上同时满足。向量检索把所有这些信息压缩成一个稠密向量本质上是在做一种有损压缩维度再高也扛不住这种多约束叠加。第二交易场景对“精确匹配”有硬需求。型号、规格、品牌名、适配关系这些东西向量检索经常翻车。你搜“iPhone 15 Pro Max 256G 原色钛金属”向量模型很可能给你召回一堆“iPhone 15 Pro”甚至“iPhone 14 Pro Max”的壳和膜因为它在语义空间里觉得这些都很“像”。但用户要的是那个精确的SKU差一个字都不行。第三长尾query和冷门商品是向量检索的噩梦。双塔模型在训练数据覆盖不到的query上表现断崖式下跌而交易搜索里长尾query占比极高。你不可能为每一个“XX品牌XX型号XX规格”的组合都准备足够的训练样本。1.2 生成式召回到底“生成”了什么“生成式召回”这个词听起来很玄但拆开看其实很朴素。它的核心思路是不再把召回当成一个“从库里找相似向量”的检索问题而是把它当成一个“根据query生成目标商品标识”的生成问题。具体来说有两种主流做法。一种是生成式检索用大语言模型或者序列到序列模型直接根据query自回归地生成商品ID序列。比如输入“夏天透气跑鞋男”模型直接输出“商品A、商品B、商品C”的ID。另一种是生成式增强召回用大语言模型对query进行理解、改写、扩展生成多个子查询或者结构化约束条件再去驱动多路召回。得物交易搜索团队走的路线从公开信息推断更偏向第二种的进阶版用生成式模型做query理解与改写同时结合多模态信息做商品侧的统一表征最终实现“生成式驱动多路召回”的范式。这背后的逻辑是交易搜索的query往往很短、很模糊、甚至带有错别字和口语化表达直接拿去检索效果很差。但如果先用生成式模型把query“翻译”成检索系统能更好理解的形式召回质量就能上一个台阶。1.3 这个范式跃迁适合谁来参考如果你在做以下任何一件事这套思路都值得你花时间研究电商平台的搜索召回、内容社区的商品推荐、本地生活服务的POI检索、任何需要处理短文本模糊查询且对精确性有要求的场景。特别是那些已经上了向量检索但发现效果卡在瓶颈的团队生成式召回提供了一条新的破局路径。但也要说清楚这不是一个“把向量检索扔掉”的方案。生成式召回和向量检索是互补关系前者解决query理解和多约束表达的问题后者解决大规模候选集快速筛选的问题。得物的实践也是多路召回并存生成式只是其中一路但它是带来增量最大的那一路。2. 生成式召回的核心技术拆解2.1 Query理解与生成式改写让模型“读懂”用户交易搜索的query有几个典型特征短平均3到8个词、模糊“那个白色的鞋”、带噪声错别字、拼音、缩写、多意图“送男友生日礼物 篮球鞋 500以内”。传统做法是用NER加规则模板做query解析但规则覆盖不全长尾query一多就崩。生成式改写的做法是用一个大语言模型可以是本地部署的开源模型也可以是API调用的商用模型对query做几件事意图补全把“夏天穿的”补全为“夏季透气轻薄”把“送男友”补全为“男性礼物 运动鞋”。约束结构化把“500以内”提取为价格区间[0, 500]把“篮球鞋”提取为品类约束。多查询生成对同一个query生成3到5个语义等价但表述不同的子查询分别去召回最后合并去重。纠错与归一把“阿迪达斯”和“adidas”归一把“蓝球鞋”纠正为“篮球鞋”。这里的关键是生成式模型不是简单地做同义词替换而是真正理解query背后的购买意图。比如“跑步膝盖疼买什么鞋”传统检索可能召回“膝盖疼”相关的商品但生成式模型能理解到用户需要的是“缓震支撑型跑鞋”从而生成更精准的检索词。注意生成式改写会引入延迟。得物的做法是离线预生成加在线轻量模型兜底热门query的改写结果直接缓存长尾query走在线小模型快速推理。这个工程取舍很关键纯在线大模型推理在搜索场景下延迟扛不住。2.2 多模态统一表征商品侧的“生成式理解”交易搜索的另一个难点在商品侧。一个商品有标题、属性、图片、视频、用户评价、问答等多模态信息传统做法是各模态分别建索引检索时分别召回再融合。但这种“分而治之”的做法有个问题不同模态之间的语义鸿沟很难弥合。图片里展示的“透气网面”和标题里写的“透气”在向量空间里可能离得很远。生成式多模态统一处理的做法是用一个多模态大模型比如CLIP系列的进阶版或者专门训练的商品多模态模型把商品的各个模态信息统一编码到一个共享的语义空间里。更进一步可以用生成式模型直接生成商品的“结构化语义描述”比如“这是一双适合夏季跑步的男款跑鞋网面透气缓震中底适合5到10公里日常训练价格区间300到500”。这个生成的描述有两个用途一是作为商品侧的检索文档参与倒排和向量召回二是作为生成式召回的“目标生成内容”让模型学习从query到商品语义描述的映射关系。得物在商品多模态支持上的投入从热词“商品多模态支持”“多模态统一处理”能看出一些端倪。他们的商品库里有大量潮鞋、潮服、潮玩图片信息极其重要很多商品的卖点光看标题根本看不出来必须结合图片才能理解。比如一双鞋的“配色故事”“联名细节”“材质纹理”这些信息在标题里往往只有一两个词但在图片里是核心卖点。2.3 多路召回与生成式路由让每一路都发挥所长生成式召回不是单一路径而是一个“生成式路由加多路召回”的架构。具体来说生成式路由用生成式模型判断query应该走哪几路召回。比如精确型号query走倒排加属性过滤模糊语义query走向量加生成式改写图片相似query走多模态召回。多路召回并行倒排召回、向量召回、生成式召回、多模态召回、图召回等多路并行执行每路召回各自的TopK。生成式融合排序用生成式模型对多路召回结果做融合和重排输出最终的商品列表。这个架构的核心优势是“各司其职”。倒排负责精确匹配向量负责语义泛化生成式负责意图理解和约束满足多模态负责视觉相似。每一路都在自己擅长的领域工作最后通过生成式融合把结果拼起来。实操心得多路召回的融合权重不要拍脑袋定。得物的做法是用一个轻量级的Learning to Rank模型以多路召回的特征各路得分、排名、是否命中作为输入学习最优融合权重。这个模型可以离线训练在线推理延迟极低。2.4 算力约束下的工程取舍热词里有个“算力约束下提升大语言模型能力的资源配置建模”这其实是生成式召回落地时最现实的问题。大语言模型推理成本高搜索场景QPS又大不可能每个query都过一遍大模型。得物的工程方案从公开信息推断大概率是分层处理热门query层离线用大模型批量生成改写结果和召回结果直接缓存在线只做KV查询。温query层在线用小模型蒸馏版或者量化版做快速推理延迟控制在10毫秒以内。冷门query层走传统召回兜底同时异步用大模型生成结果下次命中时直接使用。这个分层策略的核心是“用空间换时间用离线换在线”。大模型的能力通过离线预计算和在线小模型蒸馏在算力约束下最大化利用。3. 实操落地从零搭建生成式召回链路3.1 环境准备与工具选型如果你要复现一套类似的生成式召回系统以下是我建议的工具栈组件推荐方案选型理由大语言模型本地部署开源模型如Qwen系列、Llama系列数据安全可控推理成本可预期多模态模型CLIP系列或专门训练的商品多模态模型图文统一表征成熟社区资源丰富向量索引Faiss或Milvus成熟稳定支持大规模向量检索倒排索引Elasticsearch或自研精确匹配和属性过滤必备编排框架LangChain4j或自研Pipeline多路召回编排和结果融合模型推理vLLM或TensorRT-LLM高吞吐低延迟推理LangChain4j在多路召回编排上比较顺手它提供了Retriever接口和EmbeddingStore抽象可以比较方便地把不同召回路径串起来。但如果你追求极致性能自研Pipeline会更可控。3.2 Query改写模块的实现先定义一个QueryRewriter接口public interface QueryRewriter { RewriteResult rewrite(String query); } public class RewriteResult { private ListString subQueries; private MapString, String constraints; private String normalizedQuery; // getters and setters }然后用大语言模型实现public class LLMQueryRewriter implements QueryRewriter { private final ChatLanguageModel model; public RewriteResult rewrite(String query) { String prompt buildPrompt(query); String response model.generate(prompt); return parseResponse(response); } private String buildPrompt(String query) { return 你是一个电商搜索query理解助手。请对以下query进行改写和约束提取。 原始query: %s 请输出JSON格式 { subQueries: [改写后的查询1, 改写后的查询2], constraints: {price_max: 500, category: 篮球鞋}, normalizedQuery: 归一化后的query } .formatted(query); } }这个模块的关键在于prompt设计。得物的实践里prompt里会包含品类知识、品牌别名表、常见错别字映射等业务信息让模型输出更贴合交易场景。3.3 多模态商品表征的生成商品侧的处理流程多模态信息抽取从商品详情页抽取标题、属性、图片、视频关键帧、用户评价摘要。统一编码用多模态模型把图片和文本编码到同一空间。生成式描述生成用大语言模型根据多模态信息生成结构化商品描述。索引构建把生成的描述分别写入倒排索引和向量索引。def generate_product_description(product): prompt f 根据以下商品信息生成一段适合搜索召回的结构化描述 标题{product.title} 属性{product.attributes} 图片描述{product.image_caption} 用户评价摘要{product.review_summary} 请输出包含以下维度的描述 - 品类 - 适用场景 - 核心卖点 - 适用人群 - 价格区间 return llm.generate(prompt)这个生成的描述会作为商品侧的“语义文档”既参与倒排召回分词后建索引也参与向量召回编码后建向量索引。3.4 多路召回编排与融合用LangChain4j的Retriever接口把多路召回串起来public class MultiRouteRetriever { private final Retriever invertedRetriever; private final Retriever vectorRetriever; private final Retriever generativeRetriever; private final Retriever multimodalRetriever; private final FusionRanker fusionRanker; public ListProduct retrieve(String query, int topK) { RewriteResult rewrite queryRewriter.rewrite(query); ListCompletableFutureListProduct futures List.of( CompletableFuture.supplyAsync(() - invertedRetriever.retrieve(rewrite)), CompletableFuture.supplyAsync(() - vectorRetriever.retrieve(rewrite)), CompletableFuture.supplyAsync(() - generativeRetriever.retrieve(rewrite)), CompletableFuture.supplyAsync(() - multimodalRetriever.retrieve(rewrite)) ); ListListProduct allResults futures.stream() .map(CompletableFuture::join) .collect(Collectors.toList()); return fusionRanker.fuse(allResults, topK); } }融合排序用Learning to Rank模型def fuse_results(multi_route_results, top_k): features [] for route_results in multi_route_results: for rank, product in enumerate(route_results): features.append({ product_id: product.id, route: route_results.route_name, rank: rank, score: product.score, ctr: product.ctr, cvr: product.cvr }) df pd.DataFrame(features) df[final_score] ltr_model.predict(df) return df.sort_values(final_score, ascendingFalse).head(top_k)3.5 离线评估与在线A/B离线评估用RecallK、NDCGK、MRR等指标重点看生成式召回带来的增量。得物的实践里生成式召回在长尾query上的Recall100提升非常明显但在头部query上提升有限因为头部query的传统召回已经做得足够好。在线A/B要关注几个核心指标点击率、转化率、搜索无结果率、首屏点击位置分布。生成式召回如果做得好首屏点击位置会前移无结果率会下降。注意生成式召回的A/B实验周期要比传统召回长。因为生成式模型有“冷启动”问题新query的改写效果需要积累一定数据才能稳定。建议至少跑两周再下结论。4. 常见问题与排查技巧实录4.1 生成式改写“过度发挥”怎么办这是最常见的问题。大语言模型有时候会“脑补”太多把用户没说的意图也加进去。比如用户搜“苹果”模型可能生成“苹果手机、苹果电脑、苹果水果”三个子查询但用户其实只想买手机。排查思路看改写后的子查询和原始query的语义漂移程度。可以用一个轻量级的语义相似度模型做过滤漂移超过阈值的子查询直接丢弃。另外在prompt里加约束“只生成与原始query语义一致且不引入新意图的子查询”。4.2 多路召回结果“打架”怎么融合不同召回路径的结果可能互相矛盾。比如倒排召回了“iPhone 15”向量召回了“iPhone 14”生成式召回了“iPhone 15 Pro”。这时候融合排序模型要能判断哪个更符合用户意图。技巧在融合特征里加入“query-商品”的细粒度匹配特征比如品类匹配度、品牌匹配度、价格区间匹配度。这些特征比单纯的召回得分更有区分度。4.3 生成式召回的延迟怎么压延迟是生成式召回最大的工程挑战。几个实用的优化手段模型量化把大模型量化到INT8甚至INT4推理速度提升2到4倍效果损失可控。KV缓存复用相同或相似query的KV缓存复用减少重复计算。异步预生成对可预测的query比如热门搜索词、季节性问题离线预生成。降级策略在线推理超时直接走传统召回兜底保证可用性。4.4 多模态信息“噪声太大”怎么处理商品图片质量参差不齐有些图片包含大量文字、水印、拼接图直接送进多模态模型会引入噪声。处理技巧先做图片质量过滤低质量图片不参与多模态召回。另外图片描述生成时加约束“只描述与商品本身相关的视觉信息忽略水印、文字、背景”。4.5 常见问题速查表问题现象可能原因排查方向解决思路改写后召回结果偏离意图模型过度生成检查子查询语义漂移加语义相似度过滤多路召回结果重复率高各路召回重叠统计各路结果交集去重后融合调整各路TopK长尾query召回效果差训练数据覆盖不足分析长尾query分布生成式改写加传统兜底在线延迟飙升大模型推理耗时监控各阶段耗时量化、缓存、降级多模态召回噪声大图片质量差抽样检查图片质量图片预处理加质量过滤融合排序效果不稳定特征分布漂移监控特征PSI定期重新训练LTR模型4.6 几个踩过的坑第一个坑是prompt里的品类知识更新不及时。交易场景的品类体系经常调整新品类、新品牌、新规格层出不穷。如果prompt里的品类知识没跟上模型改写就会出错。建议把品类知识做成可配置的定期从商品库同步。第二个坑是多路召回的TopK设置不合理。每路召回如果都取Top100四路就是400个候选融合排序的压力很大。得物的做法是每路取Top50融合后取Top200进入粗排再取Top50进入精排。这个漏斗比例要根据实际效果调。第三个坑是离线评估和在线效果不一致。离线Recall提升明显但在线CTR没涨。原因可能是离线评估用的标注数据有偏或者在线融合排序没做好。建议离线评估和在线A/B同步看不要只看离线指标。5. 生成式召回的未来演进方向5.1 从“生成式改写”到“端到端生成式检索”现在的生成式召回还是“改写加多路召回”的架构未来会走向更彻底的端到端生成式检索。也就是用一个大模型直接完成“query理解、召回、排序”的全流程中间不再需要多路召回和融合排序。这个方向在学术界已经有了一些探索比如用序列到序列模型直接生成商品ID序列但工业级落地还有距离主要是规模和延迟的问题。5.2 多模态与生成式的深度融合现在的多模态召回和生成式召回还是相对独立的两个模块。未来会走向深度融合用多模态大模型同时理解query的文本和图片比如用户上传一张鞋的照片来搜同款然后生成式地输出目标商品的语义描述和ID。这个方向在潮鞋、潮服这类视觉驱动的品类上价值极大。5.3 个性化生成式召回现在的生成式召回对所有用户一视同仁但交易搜索的个性化需求很强。同一个query不同用户想要的商品可能完全不同。未来会把用户画像、历史行为、实时上下文融入生成式模型实现“千人千面”的生成式召回。5.4 算力约束下的模型蒸馏与协同大模型的能力要落地到搜索场景蒸馏是必经之路。把大模型的query理解能力蒸馏到小模型上在线用小模型推理离线用大模型持续优化。这个“大模型教小模型”的协同模式会是未来几年生成式召回工程化的主流路径。我个人在实际操作中的体会是生成式召回不是“银弹”它解决的是传统召回在query理解和多约束表达上的短板但它的工程复杂度、延迟压力、维护成本都比传统召回高一个量级。如果你的搜索场景query比较规范、品类比较集中、长尾问题不突出传统召回加向量召回可能就够了。但如果你的场景像得物这样query口语化严重、品类极其丰富、用户对精确性要求又高那生成式召回带来的增量是值得投入的。最后分享一个小技巧生成式召回的prompt不要写得太“满”留一些空间让模型自己发挥。我试过把prompt写得极其详细结果模型变得很“死板”只会按模板输出。后来把prompt精简到只给核心约束和输出格式模型反而能生成更有创意的改写结果。这个度需要反复调没有标准答案。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门