多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

生成式召回在交易搜索中的落地实践:从向量检索瓶颈到结构化意图生成

生成式召回在交易搜索中的落地实践:从向量检索瓶颈到结构化意图生成 1. 从卷不动的向量检索说起交易搜索到底卡在哪做电商搜索的人这两年应该都有同感向量检索这条赛道已经卷到不能再卷了。双塔模型、ANN索引、量化压缩、多路召回融合能优化的点几乎被翻了个遍但线上效果的天花板却越来越明显。尤其是在交易搜索这种场景里用户输入的不是我想看看连衣裙这种泛需求而是300以内能穿去面试的黑色西装外套和图片里这款差不多的沙发但预算砍一半——这类query背后是明确的交易意图、复杂的约束条件、甚至跨模态的参照物。传统向量检索的范式是编码-匹配把query和doc分别压成一个稠密向量在向量空间里算相似度。这套逻辑在语义泛化上确实强但它有个绕不开的硬伤——信息在编码阶段就被压扁了。一个query里的价格约束、品类限定、风格偏好、场景描述全被塞进一个几百维的向量里检索时模型根本不知道用户到底在意哪一条。更麻烦的是交易搜索的doc侧是动态的库存、价格、促销标签每小时都在变而向量索引的更新是有延迟的这就导致召回的东西语义相关但根本买不了。我在实际项目里见过太多这样的case用户搜适合小个子的长款羽绒服向量召回返回了一堆长款羽绒服但尺码全是L起步用户搜送男朋友的机械键盘500左右召回结果里混进了一堆300以下的入门款和800以上的旗舰款。这不是模型不够好而是召回范式本身就不支持这种细粒度的条件推理。生成式召回要解决的恰恰是这个范式层面的问题。它不再把query压成一个点去近邻搜索而是让模型直接理解query里的约束然后生成满足条件的doc标识或结构化检索意图。换句话说从找相似的变成按条件构造。这个转变听起来简单但落地时涉及模型选型、索引结构、推理性能、和现有链路的兼容等一大堆工程问题。下面我按自己踩过的坑和跑通的方案把这条路径拆开讲。2. 生成式召回到底生成的是什么三种落地形态的取舍很多人第一次听到生成式召回会误以为是让大模型直接生成商品列表这显然不现实——商品库动辄千万级生成模型不可能记住所有doc。所以关键在于搞清楚生成式召回里模型输出的到底是什么。根据我这边的实践和公开资料目前主流有三种形态各有各的适用边界。2.1 生成doc标识把召回变成受约束的解码第一种是让模型自回归地生成doc的ID序列。做法是把每个商品映射成一个短ID比如用层次化聚类得到的三段式ID然后训练一个seq2seq模型输入query输出相关doc的ID。检索时用beam search解码出top-k个ID再映射回商品。这种方案的好处是完全绕开了向量索引doc的更新只需要更新ID映射表不存在索引延迟问题。但坑也很明显ID空间是离散的模型一旦生成一个不存在的ID就是无效召回而且beam search的多样性控制很难容易反复生成同一批热门商品。我试过在千万级库上跑beam size开到50有效召回率也只有六成左右剩下的全是无效ID或重复项。所以这种形态更适合doc量级在百万以内、且ID体系稳定的场景。2.2 生成结构化检索意图让召回回到可解释的轨道第二种是我目前最看好的形态模型不直接生成doc而是生成结构化的检索条件比如品类、价格区间、属性标签、排序偏好然后把这些条件翻译成倒排或过滤查询去召回。举个例子query是500以内送男友的机械键盘模型输出可能是{ category: 机械键盘, price_max: 500, scene: 送礼, attributes: [RGB, 有线/无线双模], sort: 销量优先 }然后系统拿这个结构去查倒排索引召回结果天然满足约束。这种方案的优势在于可解释、可干预、可兜底——模型输出错了运营可以加规则修正某个条件召回为空可以自动放宽价格区间。而且它和现有搜索链路是兼容的不需要重建索引。难点在于训练数据的构造。你需要把历史query和用户实际点击/购买的商品反推成结构化条件这个标注过程很重。我的做法是用规则小模型先做一版弱标注再用大模型做蒸馏和纠错迭代三轮左右能达到可用的精度。2.3 生成伪doc向量在向量空间里造出目标第三种比较取巧让生成模型根据query生成一个理想doc的文本描述再把这个描述编码成向量去检索。比如query是适合油皮的夏季清爽防晒模型生成轻薄质地、控油配方、SPF50、不搓泥的防晒霜然后用这个生成文本的向量去近邻搜索。这种方案本质上是用生成能力做query扩展把隐式需求显式化。它的好处是复用现有向量索引改造成本低坏处是生成文本的质量直接决定召回效果而且多了一步编码延迟会增加。实测下来在美妆、服饰这类属性描述丰富的品类上效果提升明显但在3C这种参数化程度高的品类上反而不如直接生成结构化条件来得准。形态核心输出适用doc量级索引改造成本主要风险生成doc标识ID序列百万以内高需重建ID体系无效ID、多样性差生成结构化意图条件JSON不限低复用倒排标注成本高生成伪doc向量扩展文本不限低复用向量索引生成质量不稳定选哪种取决于你的doc规模、品类特性和团队工程能力。我的建议是如果倒排索引还在优先走结构化意图这条路稳且可控如果向量索引已经很成熟可以先用伪doc向量做增量验证收益后再考虑更重的方案。3. 大语言模型在召回链路里的真实位置别把它当万能钥匙生成式召回绕不开大语言模型但很多人一上来就想用最大的模型端到端做召回结果被延迟和成本教做人。我在项目里试过几种部署方式这里把真实体感说一下。3.1 在线生成 vs 离线生成延迟账要算清楚交易搜索的在线延迟预算通常卡在100ms以内而一个7B模型单次推理在GPU上也要几十毫秒加上beam search和多路并发很容易超预算。所以我的做法是把生成拆成离线和在线两段离线部分用大模型对高频query做结构化意图生成结果缓存进KV库线上直接查缓存。高频query通常只占总量的一小部分但覆盖了大部分流量这笔账很划算。在线部分只对未命中缓存的query走小模型实时生成模型可以蒸馏到1B以下配合量化单次推理能压到20ms以内。这样整体P99延迟能控制在80ms左右比纯在线生成稳得多。缓存命中率我这边做到过65%随着query日志积累还会涨。3.2 模型选型不是越大越好而是够用且可控选模型时我踩过一个坑一开始用了一个很大的开源模型效果确实好但推理成本高到没法全量上线只能做小流量实验。后来换成蒸馏后的小模型效果掉了不到3个点但成本降了一个数量级反而能全量推。具体选型时我会看三个指标意图识别准确率、结构化输出的格式合规率、以及单token延迟。格式合规率特别重要——生成式召回最怕模型输出一堆自由文本解析不了就直接废了。所以训练时一定要用大量结构化样本做SFT让模型养成输出JSON的习惯。我一般会在prompt里加few-shot示例再配合constrained decoding把合规率从70%拉到95%以上。3.3 多模态query的处理图片进来怎么办交易搜索里图片query占比不低用户拍个照就想找同款或相似款。这时候纯文本的生成模型就不够了需要多模态模型先把图片理解成结构化描述再走生成式召回。我的链路是这样的图片先过CLIP类的多模态模型抽取出品类、颜色、风格、材质等属性再把这些属性拼成文本query送进生成模型做意图结构化。这里有个细节图片理解的结果要保留置信度低置信度的属性不要硬塞进检索条件否则会引入噪声。比如模型识别出可能是羊毛材质但置信度只有0.4那就把它作为软条件在召回时降权而不是硬过滤。多模态这块目前最大的瓶颈是细粒度属性识别比如服装的版型、面料的纹理通用多模态模型往往识别不准。我的做法是在垂直品类上做小样本微调用业务侧的标注数据喂几百条效果就能明显改善。4. 把生成式召回接进现有链路工程上的五个关键决策模型跑通了只是第一步真正难的是怎么把它塞进现有的搜索链路里还不把稳定性搞崩。这部分我按决策点来说每个都附上我的取舍理由。4.1 召回通道的编排生成式是主路还是辅路我的建议是先做辅路再逐步提权。具体做法是保留原有向量召回和倒排召回作为主路生成式召回作为一路补充在融合层用加权的方式合并。这样即使生成式召回出问题整体效果也不会崩。融合权重怎么定我一般用线上A/B实验来调初始给生成式召回0.3的权重观察点击率和转化率的变化。如果正向逐步提到0.5、0.7。这里要注意不同品类的权重应该不一样——属性描述丰富的品类可以给高权重参数化品类给低权重。我这边服饰类给到0.63C类只给0.3效果比一刀切好很多。4.2 兜底策略生成失败时不能开天窗生成式召回最怕的就是模型输出异常——格式错了、条件太严召不回、或者生成了不存在的品类。所以兜底必须做三层第一层格式校验。输出不是合法JSON或字段缺失直接丢弃走原链路。第二层召回量校验。结构化条件召回结果少于阈值比如10条自动放宽条件重试比如价格区间扩大20%。第三层效果校验。如果生成式召回的点击率显著低于基线自动降权或熔断。这三层我在线上都触发过尤其是第二层在长尾query上救回来不少流量。4.3 索引与缓存的更新节奏生成式召回依赖的缓存和索引更新频率要和业务节奏对齐。价格、库存这类高频变动的字段不要写进生成模型的条件里做硬过滤而是放在召回后的排序阶段处理。否则缓存刚生成价格就变了召回结果全是失效的。我的做法是生成模型只负责品类、属性、场景这类低频变动的条件价格、库存、促销这些高频变动的条件在召回后实时过滤。这样缓存的TTL可以设到小时级不用频繁刷新。4.4 效果评估别只看召回率生成式召回的效果评估不能只看召回率因为召回的东西多了不代表有用。我一般看四个指标指标含义目标有效召回率召回结果中可购买商品占比95%约束满足率召回结果满足query硬约束的比例90%点击率提升相比基线的CTR变化正向转化率提升相比基线的CVR变化正向其中约束满足率是生成式召回特有的指标用来衡量模型对query条件的理解精度。这个指标上不去说明结构化意图生成得不准得回去调模型。4.5 和排序模型的配合生成式召回输出的结构化条件其实可以透传给排序模型作为特征。比如模型识别出query里有送礼场景这个信号在排序时很有价值——送礼场景下用户对包装、品牌的权重更高。我这边会把生成的结构化意图作为特征拼进排序模型实测对转化率有正向帮助。5. 踩过的坑与实测数据哪些做法真的有效说几个我在项目里实际踩过的坑都是文档里不会写的。坑一生成模型把预算理解成价格越低越好。早期模型对500左右这种模糊价格的处理很差要么召回全是100以下的要么全是499的。后来我在训练数据里专门加了模糊价格的样本并且把价格输出改成区间而不是单值问题才解决。现在模型对500左右会输出[400, 600]的区间召回结果分布合理多了。坑二多模态属性硬过滤导致召回为空。有次图片query识别出红色连衣裙模型硬过滤红色结果该品类红色库存很少召回直接空了。后来改成软条件红色作为加权项而不是过滤项召回量恢复正常且前排结果依然是红色为主。坑三缓存穿透导致长尾query延迟飙升。高频query走缓存没问题但长尾query没命中缓存时走实时生成QPS一高就把GPU打满了。后来加了一层降级实时生成队列超过阈值时直接走原链路保证整体不崩。实测数据方面我这边在服饰品类做过一轮A/B生成式召回作为辅路权重0.5实验组相比基线的点击率提升约8%转化率提升约5%约束满足率从基线的72%提升到91%。3C品类提升幅度小一些点击率约3%转化率约2%。这个差异也印证了前面的判断——生成式召回在属性描述丰富的品类上收益更大。6. 这条路还能怎么走几个值得试的方向生成式召回目前还在快速演进我自己接下来想试的几个方向一是把生成和排序做联合优化。现在生成和排序是两段式的生成的结构化意图只作为排序特征没有反向指导生成。如果能让排序的反馈信号回流去微调生成模型理论上能形成闭环效果应该还能再提一截。二是多模态生成式召回的深化。现在图片query还是先转文本再生成信息有损。如果能直接做多模态的意图生成让模型同时看图和文本输出结构化条件对图片query的效果会有明显改善。三是生成式召回的可解释性运营化。现在模型输出的结构化条件只有算法能看懂如果能把它们可视化给运营让运营能直接干预和修正长尾query的效果会好很多。这个方向工程量大但价值也大。整体来说生成式召回不是要取代向量检索而是在向量检索够不着的地方补位。两者配合才是交易搜索当前阶段比较务实的解法。
返回列表