ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AI重构站内搜索:混合检索架构与排序调优实战

AI重构站内搜索:混合检索架构与排序调优实战 1. 站内搜索为什么需要AI重构做过电商、内容社区或者SaaS后台的朋友应该都有体会站内搜索这个模块平时没人夸它一旦出问题就是铺天盖地的投诉。用户搜红色连衣裙结果出来一堆红色T恤和连衣裙不相关的搭配搜苹果手机壳给你返回苹果和手机壳两个独立类目的商品搜一个错别字连衣群直接零结果。这些场景我猜你多少都遇到过。传统站内搜索的技术栈基本是倒排索引加BM25打分那一套核心逻辑是关键词匹配。这套东西在文档检索时代是够用的但放到今天的业务场景里问题就暴露得很明显了。用户的表达越来越口语化、越来越长尾而商品标题、文章标题、FAQ内容往往是运营或者商家自己填的两边天然存在语义鸿沟。你搜适合送女朋友的生日礼物倒排索引会把它拆成适合送女朋友生日礼物几个词然后去找包含这些词的文档但真正符合意图的商品标题可能写的是浪漫礼盒 女生 情人节 纪念日一个词都没对上。通智云智能搜索这个项目要解决的就是这个问题。它的定位很明确给中大型站点提供一套AI驱动的站内搜索解决方案把传统的关键词匹配升级成语义理解加多路召回加智能排序的架构。说人话就是让搜索框真正听懂用户在说什么而不是只做字面匹配。这篇文章适合谁看如果你是后端开发、搜索算法工程师、技术负责人正在考虑给自家产品做搜索升级或者你已经在用Elasticsearch但效果一直不理想那这篇内容应该能给你不少参考。我会从架构设计、核心模块拆解、实操部署、参数调优到问题排查把整个方案讲透。里面涉及的一些参数和配置是我在实际项目中反复验证过的你可以直接拿去用。2. 整体架构设计与技术选型思路2.1 为什么不用纯向量检索而是混合架构这两年向量数据库很火很多人第一反应是把文档全部embedding然后做向量检索不就完了。我一开始也这么想过但在实际项目里踩了坑。纯向量检索有几个绕不过去的问题第一对于精确匹配的场景表现很差比如用户搜一个具体的订单号、型号iPhone 15 Pro Max 256G向量检索可能给你返回一堆手机但就是没有那个精确型号第二向量检索的可解释性差运营问你为什么这个商品排在前面你很难给出一个让人信服的理由第三全量向量化的成本不低尤其是文档量上千万的时候embedding的计算和存储开销都很可观。所以通智云智能搜索采用的是混合检索架构我把它拆成四层来看层级模块核心职责技术选型接入层查询理解分词、纠错、意图识别、查询改写自研NLP管线 大模型召回层多路召回关键词召回、向量召回、个性化召回Elasticsearch 向量索引排序层精排模型多特征融合打分、业务规则干预LambdaMART / 深度排序模型应用层结果呈现聚合、去重、多样性控制、埋点业务服务这个架构的核心思路是召回要全排序要准。召回层用多路并行保证不漏排序层用模型加规则保证结果符合业务预期。下面我逐层拆解。2.2 查询理解层让搜索框听懂人话查询理解是整个搜索链路的第一环也是最容易被低估的一环。很多团队把精力全放在排序模型上结果查询理解没做好后面再优化也是白搭。通智云在这一层做了几件事。分词和纠错是基础中文分词用的是自研的领域词典加通用词典的混合方案领域词典从业务数据里自动挖掘比如商品类目词、品牌词、型号词。纠错这块用的是编辑距离加拼音相似度的组合策略像连衣群到连衣裙这种同音错字拼音相似度能直接命中。意图识别是重点。系统会把查询分成几类导航类用户想直接去某个页面比如搜我的订单、信息类用户想找答案比如搜怎么退货、交易类用户想买东西比如搜蓝牙耳机 降噪。不同意图走不同的召回和排序策略导航类直接给入口交易类重点排商品。查询改写是提升召回的关键。系统会对原始查询做扩展比如同义词扩展手机扩展出移动电话智能机、上下位词扩展连衣裙扩展出裙子女装、以及基于大模型的查询重写。这里用大模型做query rewriting效果很好比如用户搜有没有那种能测心率的表大模型能改写成心率监测 智能手表召回率直接上一个台阶。注意查询改写一定要做相关性校验扩展出来的词如果和原查询语义偏离太大会引入大量噪声。我们的做法是给每个扩展词算一个语义相似度分数低于阈值的直接丢弃。2.3 多路召回层三条腿走路才稳召回层的设计原则是宁滥勿缺先把可能相关的都捞出来把筛选的压力交给排序层。通智云用了三路召回并行第一路是关键词召回基于Elasticsearch的倒排索引用BM25打分。这一路保证精确匹配的能力对于型号、品牌、专有名词这类查询是主力。ES的配置上我们用了ik分词器加自定义词典同时开了edge_ngram做前缀匹配解决用户输入到一半就想看结果的需求。第二路是向量召回把文档和查询都通过embedding模型转成向量用近似最近邻ANN算法检索。这一路解决语义匹配问题对于长尾、口语化的查询效果显著。向量索引我们用的是HNSW算法召回率和速度的平衡比较好。embedding模型选的是中文语义理解能力较强的开源模型在业务数据上做了微调。第三路是个性化召回基于用户历史行为做协同过滤。这一路在电商场景特别重要同一个查询运动鞋男性用户和女性用户、跑步爱好者和篮球爱好者想要的结果完全不同。个性化召回能保证结果的千人千面。三路召回的结果会做融合融合策略用的是加权RRFReciprocal Rank Fusion每路的权重可以根据业务场景调整。比如导航类查询关键词召回权重高探索类查询向量召回权重高。2.4 排序层模型加规则的组合拳召回回来几百上千个候选排序层要做的是把它们排出一个合理的顺序。通智云用的是两阶段排序粗排加精排。粗排用轻量级模型快速过滤把候选从几百降到几十。精排用LambdaMART或者深度排序模型输入是丰富的特征包括查询文档相关性特征BM25分数、向量相似度、文档质量特征点击率、转化率、时效性、用户特征历史偏好、当前上下文、业务特征是否广告、是否促销。这里有个经验纯模型排序在业务场景里往往不够用必须留规则干预的口子。比如运营要做活动某些商品必须置顶比如合规要求某些内容必须降权。通智云在排序层之上加了一个规则引擎支持按条件动态调整排序结果规则可以热更新不用重启服务。3. 核心模块实操部署要点3.1 环境准备与依赖清单部署通智云智能搜索之前先把基础环境理清楚。这套系统对资源有一定要求我列一下我们生产环境的最小配置和推荐配置组件最小配置推荐配置说明Elasticsearch3节点 4C8G5节点 8C16G存储索引和向量向量索引服务2C4G4C8G可复用ES或独立部署模型推理服务GPU T4 16GGPU A10 24Gembedding和排序模型应用服务2C4G x24C8G x3查询理解、融合、排序Redis2C4G4C8G缓存和会话依赖的软件版本这块ES建议7.10以上因为要用到dense_vector字段类型。Python环境3.8以上主要依赖包括elasticsearch-py、sentence-transformers、fastapi、redis-py等。模型推理如果不想自己搭可以用Triton Inference Server吞吐和延迟都比较好。提示embedding模型和排序模型对显存有要求如果文档量大建议把embedding计算做成离线批处理在线只做查询侧的embedding这样能大幅降低GPU压力。3.2 索引结构设计与字段映射索引设计是搜索效果的地基字段映射建错了后面怎么调都别扭。通智云的核心索引结构包含这几个字段{ mappings: { properties: { doc_id: {type: keyword}, title: { type: text, analyzer: ik_max_word, fields: { keyword: {type: keyword}, ngram: {type: text, analyzer: edge_ngram_analyzer} } }, content: {type: text, analyzer: ik_max_word}, category: {type: keyword}, tags: {type: keyword}, embedding: { type: dense_vector, dims: 768, index: true, similarity: cosine }, quality_score: {type: float}, update_time: {type: date} } } }这里有几个设计要点值得说。title字段同时建了keyword、ngram和分词三个子字段分别用于精确匹配、前缀匹配和全文检索。embedding字段的维度要和embedding模型输出一致我们用的是768维。quality_score是文档质量分参与排序这个分数可以来自点击率、转化率等业务指标。3.3 查询理解管线的实现查询理解管线是串行执行的每一步的输出是下一步的输入。我用伪代码把核心流程写一下def query_understanding(raw_query, user_context): # 1. 归一化全半角、大小写、去特殊字符 query normalize(raw_query) # 2. 纠错编辑距离 拼音相似度 query spell_correct(query) # 3. 分词领域词典 通用词典 tokens tokenize(query) # 4. 意图识别分类模型 intent classify_intent(query, tokens) # 5. 查询改写同义词 大模型重写 rewritten query_rewrite(query, intent) # 6. 实体识别品牌、型号、类目 entities extract_entities(query) return { original: raw_query, normalized: query, tokens: tokens, intent: intent, rewritten: rewritten, entities: entities }这里面意图识别和查询改写是两个难点。意图识别我们用的是BERT微调的分类模型标注了大概两万条数据准确率能到92%左右。查询改写用大模型做few-shotprompt里给几个示例让模型输出改写后的查询效果比规则方法好很多。3.4 多路召回与融合的工程实现召回层是并行的三路召回同时发起然后做融合。工程上要注意超时控制任何一路召回超时都不能拖垮整个查询。我们给每路召回设了独立的超时时间比如关键词召回200ms向量召回300ms个性化召回150ms超时的直接丢弃用剩下的结果继续。融合用加权RRF公式是这样的score(d) Σ weight_i / (k rank_i(d))其中weight_i是第i路召回的权重rank_i(d)是文档d在第i路召回中的排名k是一个平滑常数一般取60。这个公式的好处是不依赖各路的原始分数只依赖排名避免了不同路分数不可比的问题。权重怎么定我们的经验是导航类查询关键词权重0.6、向量0.3、个性化0.1信息类查询关键词0.4、向量0.5、个性化0.1交易类查询关键词0.3、向量0.4、个性化0.3。这些权重可以在线调整根据AB实验的结果优化。4. 排序模型训练与调优实战4.1 训练数据的构造与标注排序模型的效果七分靠数据三分靠模型。训练数据的构造是重中之重。通智云用的是点击日志加人工标注的混合方案。点击日志这块要注意处理位置偏差。用户倾向于点击排在前面的结果这是位置偏差不是真的相关。我们用倾向性模型PBM或UBM对点击做去偏还原真实的相关性。具体做法是给每个位置的点击算一个倾向分数训练时用这个分数做样本加权。人工标注这块我们定义了一个五级相关性标准完全相关、高度相关、部分相关、不相关、完全无关。标注团队按这个标准对查询-文档对打分。标注数据量不用太大几千到一万条就能显著提升模型效果关键是标注质量要高标注规范要清晰。4.2 特征工程哪些特征真正有用排序模型的特征工程我踩过不少坑。一开始恨不得把所有能想到的特征都塞进去结果模型过拟合线上效果反而差。后来做了一轮特征筛选留下真正有用的。下面是我们验证过有效的特征清单特征类别具体特征重要性相关性BM25分数、向量相似度、词命中率高文档质量点击率、转化率、停留时长高时效性发布时间、更新时间中用户偏好历史点击类目、品牌偏好中业务规则是否广告、是否促销、库存状态高查询特征查询长度、意图类型低特征重要性这块相关性特征和文档质量特征贡献最大业务规则特征虽然简单但对最终效果影响很大。查询特征单独看重要性不高但和文档特征交叉后价值就出来了比如查询意图和文档类目的匹配度。4.3 模型选型与线上部署模型选型上我们对比过LambdaMART、DNN和Transformer三种方案。LambdaMART在特征工程到位的情况下效果就很不错训练快、推理快、可解释性好是我们的基线方案。DNN在特征交叉上有优势但需要更多数据。Transformer效果最好但推理延迟高我们只在精排的最后阶段用。线上部署用的是模型服务化的方案模型训练好后导出成ONNX格式用Triton做推理。这样做的原因是解耦算法团队负责训练和导出工程团队负责部署和扩缩容。模型更新走灰度发布先切5%流量观察指标没问题再逐步放大。注意排序模型的线上推理延迟要严格控制我们的目标是P99在50ms以内。如果模型太大跑不动可以考虑模型蒸馏用大模型教小模型效果损失不大但速度提升明显。5. 常见问题排查与避坑指南5.1 搜索结果不相关的排查思路搜索结果不相关是最常见的问题排查要按链路一步步来。我整理了一个排查清单现象可能原因排查方法解决方案零结果分词错误、词典缺失看分词结果补充领域词典结果不相关召回噪声大、排序模型问题看各路召回结果调整召回权重、重训模型结果重复去重逻辑缺失看文档ID加去重模块结果过时时效性特征权重低看特征权重提高时效性权重个性化失效用户画像缺失看用户特征补全画像数据排查的时候我习惯先看查询理解的结果对不对分词、纠错、改写有没有问题。这一步没问题再看召回把三路召回的结果分别打出来看哪一路噪声大就调哪一路。最后看排序把特征值打出来看是不是某个特征异常导致排序错乱。5.2 性能瓶颈的定位与优化性能问题在搜索系统里很常见尤其是大促期间流量暴涨的时候。常见的瓶颈点和优化手段ES查询慢一般是索引设计问题或者查询太复杂。优化手段包括合理设置分片数单分片30-50G比较合适、用filter代替queryfilter有缓存、避免深分页用search_after代替fromsize。向量召回慢主要是ANN索引参数没调好。HNSW的ef_search参数控制召回率和速度的平衡调大召回率高但慢调小则相反。我们的经验是ef_search设在100-200之间比较合适。模型推理慢要么是模型太大要么是batch没做好。优化手段包括模型量化FP16或INT8、请求批处理、模型蒸馏。我们做过测试FP16量化后推理速度提升约40%效果损失不到1%。5.3 几个我踩过的坑第一个坑是embedding模型更新导致索引不一致。我们换了一版embedding模型忘了重新生成全量文档的向量结果查询侧用新模型文档侧还是旧向量语义空间对不上效果直接崩了。教训是embedding模型更新必须配套全量重建索引而且要灰度切换。第二个坑是查询改写过度导致意图漂移。有段时间我们放开了查询改写的阈值结果用户搜苹果系统给改写成苹果 手机 电脑 平板召回了一堆电子产品但用户可能只是想找水果。后来加了意图约束改写词必须和原查询意图一致。第三个坑是缓存击穿。热门查询的缓存过期瞬间大量请求打到后端把ES压垮了。解决方案是缓存过期时间加随机抖动同时对热点查询做本地缓存加分布式锁。6. 效果评估与持续迭代6.1 离线评估指标怎么选搜索效果的评估离线指标和在线指标要结合看。离线指标常用的有NDCG、MAP、MRR这几个指标各有侧重。NDCG考虑位置因素适合评估排序质量MAP关注整体相关性MRR关注第一个相关结果的位置。我们的做法是离线用NDCG10作为主指标配合人工评估。人工评估虽然成本高但能发现模型发现不了的问题比如结果多样性、时效性、合规性。每轮模型迭代我们都会抽一批查询做人工评估确保没有明显的bad case。6.2 在线AB实验的设计在线实验是检验效果的最终标准。AB实验的设计有几个要点分流要随机且稳定同一个用户每次实验分到同一组指标要选对核心指标是点击率和转化率辅助指标包括零结果率、首条点击率、人均点击次数实验周期要足够长至少覆盖一个完整的用户行为周期一般7天起步。我们做过一次排序模型升级的AB实验实验组NDCG离线提升3个点但线上点击率只提升了0.5个点。后来分析发现离线评估用的标注数据和线上真实分布有偏差。这件事给我的教训是离线指标只能参考最终还是要看线上效果。6.3 持续迭代的机制搜索优化不是一锤子买卖需要持续迭代。我们建立了一个闭环机制线上日志回流挖掘bad case和长尾查询bad case进入标注队列补充训练数据模型定期重训一般两周一次新模型先离线评估再小流量AB最后全量。这个闭环里bad case挖掘是最有价值的环节。我们写了一个脚本自动从日志里捞出零结果查询、高跳出查询、点击位置靠后的查询人工review后分类处理。有些是词典缺失补词典就行有些是语义理解错误需要改模型有些是数据问题得推动业务方修数据。7. 这套方案还能怎么扩展通智云智能搜索目前的架构已经能覆盖大部分站内搜索场景但还有一些方向可以继续深挖。一个是多模态搜索支持以图搜图、以图搜文这在电商和内容社区很有价值。另一个是对话式搜索把搜索框变成对话入口用户可以用自然语言多轮交互逐步细化需求。还有一个是个性化推荐的融合搜索和推荐本质上都是解决信息匹配问题两者的用户画像和特征可以复用做成搜推一体的架构。我个人在实际项目中的体会是搜索系统的优化没有终点用户的需求在变数据分布在变模型和策略就得跟着变。关键是建立一套能快速迭代的机制让优化成为一个持续的过程而不是一次性的项目。另外不要迷信模型规则和模型结合才是工程上最稳的方案纯模型方案在业务场景里往往会遇到各种意想不到的问题。
返回列表