news 2026/10/2 14:01:16

生成式召回:突破交易搜索意图约束的新范式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
生成式召回:突破交易搜索意图约束的新范式

1. 交易搜索的特殊性:为什么向量检索在这里不是银弹

搜索圈这两年确实被向量检索带起了节奏,尤其是RAG概念火了之后,仿佛任何搜索场景都可以用embedding一梭子解决。但我得先泼一盆冷水:在电商交易搜索里,向量检索并没有想象中那么万能。得物交易搜索的实践让我越来越确认一个反直觉的判断——与其继续把向量模型做深做宽,不如换个思路,把召回这件事从“检索”变成“生成”。

先解释一下交易搜索和通用语义搜索的差别。你在百度或知乎上搜索,核心诉求是“找到一篇相关的文章”,语义相近基本等于结果可用。但用户在电商App里搜“羊毛大衣女冬”,他的真实意图不是找“和这句话语义相似的内容”,而是要找到一件“羊毛材质、女款、适合冬天穿的大衣”,同时这衣服得有库存、价格合适、能发货。这种场景下有大量硬约束,比如类目约束、属性约束、库存约束、价格区间约束,而向量检索擅长的是“语义匹配”,不是“约束满足”。

我举几个我曾经踩过的真实场景。用户搜“小个子显瘦毛呢外套”,如果按常规的文本向量化,query会被embedding成一个稠密向量,模型会把“小个子”“显瘦”两个修饰词压进整体语义里,结果召回来的往往是“毛呢外套”这个主体相关的商品,而“小个子”“显瘦”两个关键约束在向量空间里被稀释了。再比如用户搜“不要加绒的卫衣”,这里有个否定词“不要”,语义向量完全没法准确表达排除关系,最后召回结果里全是加绒卫衣,用户转头就流失了。

还有一类更隐蔽的问题,就是长尾表达和商品标题之间的语义鸿沟。用户说“梨形身材神裤”,但商品标题只会老老实实写“高腰阔腿裤女显瘦”,这两句话在字面上几乎不重合,向量检索靠语义近似有可能搭上关系,但往往召回来的还掺杂了一堆不合身型的普通牛仔裤。用户意图里的“梨形身材”是一个很具体的体型特征,需要被翻译成商品侧可匹配的属性组合,比如“高腰、阔腿、显胯宽修饰”,这不是向量检索的直接能力。

所以我的结论是,向量检索在交易搜索里依然有价值,但它解决的是“模糊语义召回”问题,解决不了“结构化意图约束”问题。而要突破这一层,就需要把召回逻辑做一个范式上的改变,也就是标题里提到的“生成式”召回。

2. 生成式召回的整体设计与核心思路

2.1 什么是生成式召回:先猜意图,再造候选

所谓生成式召回,核心思路不是让模型直接生成商品,也不是让模型帮你写商品描述,而是让模型根据用户的query,先生成一套“结构化的搜索意图表达”,再基于这套表达去构造候选集。说得更直白一点:传统召回是“拿query去索引里找商品”,生成式召回是“拿query去推演用户想找什么,然后把这个‘想找什么’翻译成检索条件,再执行检索”。

你可以把它理解成以前买东西找销售顾问。用户说“我想要一件显瘦的冬天外套”,普通搜索就像销售顾问直接带你去货架上找带“显瘦”二字的商品;生成式召回则像是这个顾问先思考了一下,判断出用户可能是一个小个子女性用户,她说的“显瘦”大概率对应高腰线、短款、修身剪裁,然后顾问自己组织了一套检索条件,去库房里精准挑出符合这些要求的一批货再拿给你看。

在这个框架下,召回的对象其实从“商品”变成了“意图”。这一步转变非常关键,因为query是很短的,信息量不足,直接拿它去匹配商品,天然就会碰到前面说的信息稀疏问题。而生成模型的优势在于,它可以结合内部知识、用户画像、上下文信息,把一句稀疏的话扩展成一组丰富的、结构化的条件。

2.2 整体架构:Query理解、候选生成、融合排序三段式

我们在工程上把生成式召回拆成了三段:Query理解、候选生成、融合排序。这里我不画流程图,用文字给你理清楚。

Query理解这一层,负责把用户的原始输入解析成结构化的信息,包括类目意图、属性槽位、价格区间、用户偏好等。比如“小个子显瘦毛呢外套”会被解析为:类目=女装-毛呢外套,属性={版型:显瘦, 长度:短款},人群偏好={小个子}。这个解析结果不是简单的NER(命名实体识别),它需要结合商品知识库里的属性词典来做对齐。

候选生成这一层,基于Query理解的输出,模型会生成一组“原子查询条件”,也就是若干条可以在倒排索引上直接执行的检索表达式。比如生成“毛呢外套+短款+高腰线”“毛呢外套+小个子+通勤”这样的条件组合。这组条件会分别去倒排索引里拉取候选商品,生成式模型在这里的角色不是匹配器,而是候选条件的生产器。

融合排序这一层,把多路召回来的候选集做合并、去重,然后交个粗排和精排。这里要注意的是,生成式召回并不是替代掉原有的向量检索,而是作为新的一路召回加入整个召回体系,后面我会专门讲多路之间怎么配合。

2.3 生成式召回与多路召回、swing协同的定位

现在很多团队都在讲“多路召回”,向量一路、倒排一路、协同过滤一路,热门的时候还能加上swing召回。得物这边也一样,但我们花了很多精力去思考一个问题:如何让生成式召回不是简单叠加,而是真正补齐其他路的盲区。

我的定位是:向量检索擅长语义泛化,负责在“不知道用户具体要什么词”时找回可能相关的商品;倒排索引擅长精确匹配,负责“用户给出明确属性词”的时候锁定候选;swing这类协同召回擅长挖掘行为相似性,在用户历史行为丰富时补充个性化候选。而生成式召回在这三者之间扮演的是一个“调度者+翻译者”的角色,它先把用户那句口语化的query翻译成更贴近商品侧表达习惯的检索条件,然后决定哪些条件交给倒排、哪些条件增强向量检索的输入。

举个例子,用户搜“送男朋友的生日礼物”。这个query拿到传统倒排里只能切出“男朋友、生日、礼物”三个词,召回质量很差;向量检索稍微好一点,能泛化出“男士皮带、钱包、手表”等语义相近的商品,但精度不够。生成式召回会先把意图翻译成“男士-礼品类目-中高价格带-生日场景”,然后生成一批候选条件:皮带、钱包、剃须刀、耳机、机械手表等,每一条再带着“礼盒装”“刻字服务”这类属性约束去召回。这样的召回结果既覆盖了语义泛化的广度,又保留了交易场景的精度。

3. 核心环节的实现:从模型选型到线上部署

3.1 Query结构化理解:属性抽取与意图分类的实现细节

先说一下Query理解这层怎么落地。我们的方案是基于一个中小规模的生成模型,配合商品知识库里的属性词典做约束解码。为什么不用大模型?因为Query理解需要极低的延迟,线上请求p99要求控制在50毫秒以内,满血大模型根本跑不起。而且属性抽取这件事,并不需要多强的推理能力,它更依赖对商品类目体系的深刻理解。

具体实现上,我们定义了一套Query理解输出的JSON Schema,包含类目候选、属性槽位、意图标签、价格约束等字段。模型输出的json结构如下:

{ "category": ["女装-毛呢外套", "女装-大衣"], "attributes": { "版型": ["显瘦", "直筒"], "长度": ["短款", "中长款"], "材质": ["毛呢", "羊毛"], "风格": ["通勤", "韩版"] }, "intent": "buy", "user_profile_bias": ["小个子", "学生党"], "price_range": [100, 500] }

属性抽取最大的难点在于“泛化属性”的对齐。用户说“显瘦”,商品侧标题里可能根本不会出现这个字,但它会写“高腰”“立体剪裁”“A字版型”,这需要模型能把这些表达映射到同一个属性槽位下。我们的做法是给模型输入一个属性同义词表,把“显瘦”关联到“高腰线、收腰、A字、立体剪裁、垂坠感”等词,让模型在生成属性条件时不只是输出用户原词,而是输出商品侧真正可匹配的表达词。这一步让我强烈感受到:生成式召回要做的不是“理解用户说了什么”,而是“理解商品库能匹配什么”,中间这层桥梁得靠知识库持续维护。

3.2 候选生成:模板化生成与生成模型的取舍

Query理解做完之后,进入候选生成阶段。这个阶段我们用了两条腿走路:基于模板的生成和基于生成模型的自由生成。

模板化生成适用于意图清晰、规则明确的场景,比如“价格区间+类目+属性”这种组合。系统会根据Query理解输出的结构化槽位,自动枚举组合出一批原子查询条件。比如前面那个例子,会生成这么几条:

  • 毛呢外套 短款 高腰线
  • 毛呢外套 小个子 通勤
  • 毛呢外套 短款 显瘦
  • 大衣 韩版 短款

每一条原子查询条件都会去倒排索引里执行一次检索,拉回top N商品,最后合并成候选集。模板生成的好处是可控、可解释、永远有结果,缺点是它只能在已有槽位的组合空间里打转,遇到复杂的长尾需求就无能为力了。

基于生成模型的自由生成则负责处理模板覆盖不到的复杂意图。还是那个“送男朋友的生日礼物”的例子,模板生成没法把这个query拆成明确槽位,这时候生成模型会结合自己的常识知识,产出“男士钱包 礼盒装”“男士皮带 生日礼物”“男士剃须刀 实用”“机械手表 学生党 生日”等候选条件池。这一步我们用的是中等参数量的序列生成模型,在内部语料上做了指令微调,确保输出格式永远是一组结构化的”查询条件”。

需要提醒的是,生成模型的输出一定要做合规校验和后处理。我们最初上线的时候,模型偶尔会生成一些超出商品库表达范围的生僻词,比如“男友风oversize羊羔毛外套女”这种长尾词,虽然语法正确,但倒排索引里可能一个商品的标题都覆盖不到,纯粹浪费算力。后来加了“必须在词典内”的约束解码,保证生成条件里每个核心词都能在商品知识库中找到对应,大大提升了召回的产出率。

3.3 融合排序与回流机制:生成式召回如何真正影响排序结果

候选生成完并不是直接给用户看,还要和向量检索、swing等路召回来的候选合并进入排序流程。但这里有个容易踩坑的细节:不同路的召回来源不一样,数据的“信任度”也不一样。倒排召回的商品和用户query有字面匹配,向量召回的商品是语义匹配,生成式召回的商品可能是“意图匹配”。如果把三路结果等同看待直接丢给排序模型,排序模型会感到很困惑,因为它很难学到“哪一路的特征更重要”。

我们的做法是给生成的候选打上标签,记录每条商品是通过哪条原子查询条件召回的、一共命中了几条条件、条件类型是什么。这些信息会作为特征直接进排序模型。比如一件毛呢外套被三条生成条件同时命中,和只被一条条件命中的商品,在排序模型看来权重完全不同。这个设计我们内部叫“命中强度特征”,实测下来对排序效果有明显帮助。

另外还有回流机制。生成式召回的优势在于它产出的原子查询条件本身可解释、可复用。我们会把线上表现好的条件组合沉淀到“优质查询库”里,定时离线挖掘和扩充,再更新到模板生成器的候选池中。这个飞轮转起来以后,生成式召回的覆盖率会持续提升,而不是永远只靠模型在线生成。

4. 实验评估、效果对比与常见问题

4.1 离线评估:召回率怎么算才算合理

说到评估,先讲离线。搜索召回阶段最核心的指标是召回率,但交易搜索里“召回”的定义需要仔细斟酌。你不能说用户点击了某商品,就算它应该被召回,因为用户点击可能受价格、图片、排序位置影响。我们在实践中用的方式是基于成交和深度行为定义“相关商品集合”:用户下单、加购、收藏、或者浏览时长超过一定阈值的商品,都算作“应召回商品”。然后分别统计生成式召回、向量检索、倒排检索各自能覆盖这个集合中的多少比例。

我这里给一组我们内部测试时的参考数据。在测试集上,纯向量检索的召回率大概是61%,纯倒排召回是55%,而生成式召回单独一路能达到52%。看绝对值似乎生成式并不占优,但我们要看的是“新增覆盖”,也就是其他两路都没召回、而生成式一路能额外捞回来的商品占比。这个数字大约是7.3%。听起来不算大,但在交易搜索场景,7个百分点的增量覆盖,往往对应着大量长尾成交转化。

还要看一个指标叫“精确率”,就是召回来的商品里到底有多少和用户意图相关。生成式这里的优势就体现出来了,它的精确率明显高于向量检索,因为生成的每个原子查询条件都带有明确属性约束,拉回来的商品在类目命中率上比纯语义泛化高出不少。精排环节的输入质量更高了,后续模型的压力也能减轻。

4.2 在线效果:成交转化率和用户体感的变化

离线指标只是第一步,最终还是要看线上AB实验。我们当时做了一个月的AB,核心观察两个指标:成交转化率和人均浏览深度。生成式召回上线后,成交转化率相对提升了约2.1%,人均浏览商品数提升了约3.4%。

我印象最深的是一个搜索词“冬天穿什么显瘦”。这类query之前在线上的搜索量不算低,但转化率很惨,因为常规召回就是把它当成普通文本切词,召回一些“冬天”“显瘦”相关的商品,并没有理解用户深层需求。生成式召回上线后,这个query被翻译成了一批“冬季+显瘦+外套/裤装/连衣裙”的结构化条件,额外召回了一批原本无法触达的商品,这批商品带来的成交增量非常可观。这说明,生成式召回提升的不是头部热门词的效果,而是把那些“模糊表达型”query的成交潜力释放了出来。

4.3 常见问题与排查技巧实录

最后分享一下实战中遇到的几个典型问题和排查思路,这些坑常规文档里不会写。

第一个是生成结果的“幻觉属性”问题。模型偶尔会输出商品域里根本存在的属性组合,比如“防水羽绒服”可能没问题,但“透气羽绒服”在知识库里匹配度很低。我们排查时的经验是,给每个生成的属性词打一个“知识库覆盖分”,低于阈值的直接丢弃。每周离线统计分析低覆盖词案例,反馈给模型调优。这个机制上线后,无效候选的比例下降了约30%。

第二个是延迟问题。生成模型推理是毫秒级延迟的主要来源,尤其在流量高峰可能拖垮整个搜索服务。我们做了两级缓存体系:同一query近段时间内的生成结果直接命中缓存,不同query共享的原子查询条件也做复用。另外模型推理和检索环节做成并行流水线,查询理解还没完全结束时,模板生成器已经把基础条件送入检索了,这样总链路延迟只增加了约15毫秒。

第三个是多路召回之间的“同质化”问题。之前我发现生成式召回的候选和向量检索的重合度变高了,新增覆盖越来越少。排查后发现是生成条件里的同义词扩展词又落入到向量检索能覆盖的语义范围里了。解决方式是在生成条件里抑制“高向量相似度”的词,把资源留给真正需要精确约束的长尾表达。调整之后,新增覆盖回升明显。

还有个容易被忽视的问题是日志埋点。生成式召回需要记录“来源条件ID”,否则线上出了问题根本没法查。我们在每个召回商品上都挂了条件ID、条件类型、命中数等字段,排查问题时可以直接定位到某条原子查询条件,分析它为什么召回了不该召回的商品。这一点强烈建议所有做多路召回的同学都重视起来。

按照我个人的实践经验,想做好生成式召回,不能把它当成一个纯模型问题,它更像是一个系统工程。Query理解、候选生成、多路融合、评估回流四个环节环环相扣,任何一个环节拖后腿,最后的效果都会大打折扣。而且不同品类的搜索query差异极大,比如奢侈品搜索和潮流服饰搜索的表达习惯完全不同,生成式召回的策略参数也需要按类目做差异化配置,这又是一个长期迭代优化的过程。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 14:01:05

Apache Ignite集成Spring Boot实战:分布式缓存与计算一体化的性能调优

1. 项目整体设计与技术选型思路1.1 为什么不是 Redis,而是 Apache Ignite聊到分布式缓存,很多人的第一反应是 Redis。确实,Redis 在缓存领域统治了很多年,简单、成熟、生态好,单机吞吐量极高。但我这次在项目里遇到的情…

作者头像 李华
网站建设 2026/10/2 14:00:48

知识图谱问答系统课设实战:从Neo4j建模到Flask部署

简介:面向Python课程设计场景,基于知识图谱的问答系统源码提供了从数据构建到在线问答的完整可运行方案,适合高校计算机专业学生作为课程设计、毕业设计参考,也适合希望入门知识图谱与问答系统的开发者。压缩包共486个文件&#x…

作者头像 李华
网站建设 2026/10/2 14:00:27

C++四种类型转换面试必考:static_cast、dynamic_cast、const_cast、reinterpret_cast全解析,90%的候选人说不清楚!

C++四种类型转换面试必考:static_cast、dynamic_cast、const_cast、reinterpret_cast全解析,90%的候选人说不清楚! 面试官:C++有哪几种类型转换?你:static_cast、dynamic_cast、const_cast、reinterpret_cast。面试官:它们各自的使用场景是什么?dynamic_cast的底层原理…

作者头像 李华
网站建设 2026/10/2 14:00:27

汽配、美容、健康管理行业找客户,云熵科技AI搜索营销品牌,灵活适配产品规格与业务场景,助力安庆企业精准获客

在安庆的街头巷尾,汽配城的灯光总是亮到很晚。老张经营着一家汽配门店,货架上摆满了各类配件,从滤清器到刹车片,一应俱全。可这两年,他越来越觉得不对劲——进店的客户少了,偶尔来的几个,也是比…

作者头像 李华
网站建设 2026/10/2 13:58:49

当小程序不只是“工具”:为什么畔游科技是企业“懂成长的伙伴”?

小程序, 早在从前你就已经习惯了它那被定义为仅仅只是拿来就用一下就走掉而已的那种简易形态的小应用软件, 而现在它已经不再是这样的状态了。最新的有关数据, 其来源是所谓的《2026移动互联网生态报告》, 这最新数据显示的实际情况是, 就时间而言, 截至到二零二六年三月这一个…

作者头像 李华
网站建设 2026/10/2 13:57:07

直播封装与低延迟 HLS:CMAF、Part 切片与 3 秒延迟实现

HLS 把直播流切成 5 秒以上的 TS 分片,端到端延迟常被实测推到 10~30 秒——电商秒杀、在线教育答题这类强互动场景,半分钟的画面滞后足以让整场活动失效。这正是直播系统封装模块要直面的痛点:既要保住 HLS 跨设备兼容的广覆盖,又…

作者头像 李华