ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI重构站内搜索:混合检索与语义理解实战

AI重构站内搜索:混合检索与语义理解实战 1. 站内搜索为什么需要AI来重做一遍做过电商、内容社区或者企业知识库的朋友应该都有体会站内搜索这东西看着不起眼但它是用户找到目标内容的最短路径。搜索做不好用户要么在搜索框里反复换词要么直接跳出走人。传统的站内搜索方案说白了就是关键词匹配那一套——倒排索引、TF-IDF、BM25再叠加一些同义词配置和人工规则。这套东西在内容量不大、用户表达规范的场景下还能凑合但一旦内容规模上去、用户查询变得口语化问题就全暴露出来了。通智云智能搜索这个项目核心要解决的就是这个痛点用AI能力把站内搜索从“关键词匹配”升级到“语义理解”。它要做的不是把Elasticsearch换掉而是在检索链路里嵌入语义向量、查询理解、结果重排这几层AI能力让搜索能听懂“我想找上次那个讲怎么退换货的帖子”这种自然语言查询而不是只能匹配“退换货”这三个字。这篇文章适合谁看如果你是负责站内搜索的研发工程师、搜索产品经理或者正在做企业知识库、电商平台、内容社区的技术负责人那这篇内容应该能给你一些可以直接参考的思路和落地细节。我会从整体架构设计讲到具体的向量检索参数怎么调、查询理解怎么做、重排模型怎么选再把我自己踩过的坑和排查经验一并分享出来。全文基于常见的工程实践来展开具体参数和选型你可以根据自己的业务场景做调整。2. 整体架构设计与技术选型思路2.1 为什么不能只靠向量检索很多人一提到AI搜索第一反应就是“上向量数据库做语义检索”。这个思路方向没错但如果直接把传统关键词检索整个替换成向量检索实际效果往往不升反降。原因很简单向量检索擅长的是语义相似但它在精确匹配上是有短板的。比如用户搜一个具体的订单号、一个型号代码、一个专有名词向量模型很可能把它编码成一个语义相近但完全不对的结果。我实测过一个场景用户搜“X200 Pro”向量检索返回了一堆“X200”“X100 Pro”甚至“Pro 200”的结果因为模型觉得这些在语义空间里离得很近但用户要的就是那个精确型号。所以通智云智能搜索的架构核心思路是混合检索关键词检索负责召回精确匹配的结果向量检索负责召回语义相关的结果两路结果合并后再做重排。这个思路在业界已经比较成熟了但具体怎么融合、权重怎么分配是有讲究的。2.2 四层架构拆解整个搜索链路我把它拆成四层每一层各司其职第一层查询理解层。用户输入的那句话不能直接拿去检索。这一层要做的是分词、意图识别、实体抽取、查询改写、同义词扩展。比如用户输入“怎么退换货”这一层要能识别出意图是“售后咨询”实体是“退换货”然后改写成“退货 换货 售后 流程”这样的检索表达式。第二层召回层。这一层是双路并行一路走关键词倒排索引用BM25打分召回Top N另一路走向量索引用ANN近似最近邻召回Top M。两路各自返回候选集。第三层融合与重排层。把两路召回的结果合并去重然后用一个交叉编码器Cross-Encoder或者精排模型对候选集重新打分排序。这一步是提升搜索质量的关键因为它能同时看到查询和文档的完整语义做出更精准的相关性判断。第四层业务规则层。重排之后还要叠加业务规则比如置顶、去重、多样性打散、时效性加权、个性化偏好等。这一层是纯工程逻辑但直接影响用户体验。2.3 技术选型的关键考量选型这块我列一个对比表把几个核心组件的选择逻辑说清楚组件可选方案选择理由关键词检索引擎Elasticsearch / OpenSearch成熟稳定倒排索引性能好生态完善向量检索引擎Milvus / Qdrant / FAISS需要支持HNSW索引召回率和性能平衡好嵌入模型BGE / M3E / text-embedding中文语义理解能力强维度适中重排模型BGE-Reranker / Cohere Rerank交叉编码器精度高推理延迟可接受查询理解规则小模型混合纯大模型延迟高纯规则覆盖不够这里重点说一下嵌入模型的选择。维度不是越高越好1024维和768维在实际检索效果上差距可能只有1-2个百分点但存储成本和检索延迟差距是实打实的。我建议先用768维跑一轮评测如果召回率不达标再考虑升维。另外嵌入模型一定要用你的业务数据做一轮微调通用模型在垂直领域的语义理解往往不够精准。注意向量索引的构建不是一劳永逸的。内容更新后需要增量更新向量如果增量太大HNSW索引的召回率会下降需要定期做全量重建。建议设置一个阈值比如增量超过20%就触发重建。3. 查询理解层的核心细节与实操要点3.1 分词与实体抽取的配合中文分词看起来是个老问题但在搜索场景下分词的粒度直接决定了召回效果。我试过几种方案jieba分词、HanLP、还有基于BERT的序列标注。实测下来纯分词工具在通用场景够用但在垂直领域比如医疗、法律、电商会频繁出现切分错误。比如“退换货政策”这个词jieba可能切成“退换/货/政策”但正确的切分应该是“退换货/政策”。我的做法是用分词工具做基础切分然后叠加一个领域词典做修正。领域词典从哪来从用户的搜索日志里挖。把高频查询词、点击率高的词整理出来人工审核后加入词典。这个工作看起来笨但效果立竿见影。我做过一个对比测试加入领域词典后关键词召回的准确率提升了大概15个百分点。实体抽取这块主要是识别查询中的关键实体品牌名、产品型号、人名、地名、时间等。这些实体在后续的检索中会作为强约束条件。比如识别出“2024年”这个时间实体就可以在检索时对时间字段做过滤。3.2 查询改写的边界控制查询改写是提升召回率的重要手段但也是最容易出问题的地方。改写过头了会把用户的精确意图改没了改写不够又召回不到足够的结果。我的经验是改写要保守扩展要克制。具体怎么做我一般分三步同义词扩展只扩展确定安全的同义词。比如“退换货”扩展成“退货 换货”这是安全的。但“苹果”扩展成“iPhone”就要谨慎因为用户可能真的在搜水果。意图补全根据意图识别结果补充必要的检索词。比如识别出“售后”意图可以补充“售后 客服 维修 退换”等词但要用OR逻辑不能强制匹配。拼写纠错这个必须有但纠错要给出置信度。置信度高的直接纠置信度低的保留原词同时加入纠错词。实操心得查询改写一定要做A/B测试。我见过太多团队拍脑袋定了改写规则上线后核心指标反而跌了。建议每次改动都跑一周的A/B看点击率、转化率、无结果率这几个核心指标的变化。3.3 意图识别的轻量化方案意图识别如果用大模型来做延迟是个大问题。用户搜索的响应时间要求通常在200ms以内大模型推理根本来不及。我的方案是规则小模型。规则层处理高频、明确的意图比如包含“怎么”“如何”的查询归为“操作指南”意图包含“多少钱”“价格”的归为“价格咨询”意图。规则覆盖不到的走一个小型的文本分类模型比如TextCNN或者蒸馏后的BERT推理延迟控制在20ms以内。这个方案的准确率能做到85%左右对于搜索场景够用了。剩下的15%靠后续的重排和业务规则来兜底。4. 混合检索与重排的落地实现4.1 双路召回的参数调优关键词召回这块Elasticsearch的BM25参数调优有几个关键点k1和b参数k1控制词频饱和度b控制文档长度归一化。默认值k11.2b0.75。对于短文本为主的场景比如商品标题建议把b调低到0.5左右因为短文本的长度差异不大过度归一化反而不好。字段权重标题、摘要、正文的权重应该不同。我一般设标题权重3.0摘要2.0正文1.0。具体数值要根据业务数据做网格搜索。召回数量关键词召回建议Top 200向量召回建议Top 100。这个数量要平衡召回率和后续重排的计算成本。向量召回这块HNSW索引的参数M每个节点的最大连接数默认16。增大M可以提高召回率但内存消耗和构建时间也会增加。我一般设32。efConstruction构建时的候选集大小默认200。增大可以提高索引质量但构建变慢。建议设400。efSearch搜索时的候选集大小默认100。这个参数可以在查询时动态调整efSearch越大召回率越高但延迟越大。我一般设128。4.2 融合策略的选择两路召回的结果怎么融合常见的有三种策略策略一加权求和。把关键词得分和向量得分归一化后加权相加。优点是简单缺点是权重难调而且两路得分的分布差异很大归一化本身就会引入误差。策略二RRFReciprocal Rank Fusion。不看具体得分只看排名。公式是score Σ 1/(k rank)k一般取60。这个方法的优点是鲁棒性好不需要调权重缺点是完全忽略了得分的置信度信息。策略三学习排序。把两路得分作为特征训练一个LTR模型来融合。效果最好但需要标注数据冷启动阶段比较难。我的建议是冷启动阶段用RRF快速上线有了一定量的点击数据后切换到LTR。通智云智能搜索的默认配置用的是RRF因为它在大多数场景下表现稳定不需要太多调参。4.3 重排模型的部署与优化重排是提升搜索质量最明显的一步。我实测过加入重排后Top 10结果的点击率能提升20%以上。但重排的代价是延迟交叉编码器要对每个候选文档做一次推理100个候选就是100次推理延迟很容易超过500ms。优化方案有几个候选集截断不要对全部召回结果做重排只对Top 50做重排后面的直接按召回得分排序。模型量化把重排模型做INT8量化推理速度能提升2-3倍精度损失在1%以内。批处理把多个候选文档拼成一个batch一起推理充分利用GPU并行能力。缓存对于高频查询把重排结果缓存起来下次直接返回。我一般用方案13的组合把重排延迟控制在150ms以内。注意重排模型的输入长度有限制一般是512个token。如果文档很长需要做截断。截断策略很重要我建议保留文档开头和包含查询词的片段中间部分可以丢弃。5. 常见问题排查与避坑经验实录5.1 搜索结果不相关的排查思路这是最常见的问题。用户搜A返回了B。排查步骤我一般按这个顺序来第一步看查询理解的结果。把查询理解层的输出打出来看分词对不对、意图识别对不对、改写后的查询是什么。很多时候问题出在这一层比如分词切错了导致后续检索全偏了。第二步看召回结果。分别看关键词召回和向量召回的结果判断是哪一路出了问题。如果关键词召回的结果就不相关那是分词或同义词的问题如果关键词召回相关但向量召回不相关那是嵌入模型的问题。第三步看重排结果。如果召回结果里有相关的但重排后排名掉了那是重排模型的问题。可能是重排模型的训练数据和业务场景不匹配需要做领域微调。5.2 无结果率的控制无结果率是搜索质量的重要指标。用户搜了没结果体验极差。控制无结果率有几个手段查询改写兜底当原始查询无结果时自动触发查询改写用改写后的查询再搜一次。向量召回兜底关键词召回无结果时强制走向量召回至少返回语义相近的结果。降级策略如果两路都无结果返回热门内容或者相关推荐不要让用户看到空白页。我一般把无结果率控制在3%以内超过这个值就要排查是内容覆盖不够还是检索策略有问题。5.3 性能问题的排查搜索的性能问题通常表现为延迟高或者吞吐量低。排查方向问题现象可能原因排查方法延迟突然升高向量索引退化检查索引大小和召回率吞吐量下降重排模型成为瓶颈看GPU利用率和队列长度偶发超时缓存击穿检查缓存命中率和过期策略内存占用高向量索引加载过多检查索引分片和加载策略我踩过的一个坑是向量索引没有做分片全量加载到内存导致单节点内存爆了。后来改成按时间分片只加载最近3个月的索引内存占用降了60%召回率只损失了2个百分点。5.4 效果评测的指标体系搜索效果不能只看点击率要建立一套完整的指标体系召回率相关结果中被召回的比例。这个需要人工标注评测集。准确率召回结果中相关结果的比例。NDCG考虑排序位置的增益指标比单纯的准确率更能反映排序质量。无结果率搜索无结果的比例。首条点击率第一条结果被点击的比例。平均点击位置用户点击结果的平均排名位置越低越好。我建议每周跑一次离线评测每天看线上指标。离线评测用固定的评测集保证可比性线上指标看趋势及时发现异常。6. 从零搭建的完整实操流程6.1 数据准备与索引构建第一步是数据清洗。把业务数据里的标题、正文、标签、分类等字段整理出来去掉HTML标签、特殊字符、重复内容。然后做字段映射确定哪些字段参与检索、哪些字段用于过滤、哪些字段用于展示。第二步是向量化。用嵌入模型把每个文档编码成向量。这个过程可以离线批量做也可以实时做。离线批量做的好处是可以充分利用GPU速度快实时做的好处是内容更新后立即可检索。我一般用离线批量增量实时的混合方案。第三步是索引构建。Elasticsearch建倒排索引Milvus建向量索引。两边用同一个文档ID做关联。# 向量化示例伪代码 from sentence_transformers import SentenceTransformer model SentenceTransformer(BAAI/bge-base-zh-v1.5) def encode_documents(docs): texts [doc[title] doc[content][:500] for doc in docs] embeddings model.encode(texts, batch_size64, normalize_embeddingsTrue) return embeddings6.2 检索服务的搭建检索服务我建议用微服务架构把查询理解、召回、重排拆成独立的服务通过RPC调用。这样做的好处是每个服务可以独立扩缩容比如重排服务GPU吃紧就多加几个实例召回服务CPU吃紧就多加几个实例。服务间的通信协议用gRPC比HTTP性能好。超时时间要设合理查询理解50ms召回100ms重排150ms总超时控制在300ms以内。6.3 上线后的持续优化上线不是终点而是起点。持续优化主要做几件事Bad Case收集每天从日志里捞无结果查询、低点击率查询、高跳出率查询人工分析原因。模型迭代用积累的点击数据训练重排模型用业务数据微调嵌入模型。规则调优根据Bad Case分析结果调整同义词词典、改写规则、业务权重。A/B测试每次改动都跑A/B用数据说话。我自己的节奏是每周一次Bad Case Review每月一次模型迭代每季度一次大版本升级。实操心得不要追求一步到位。我见过很多团队想一次性把搜索做到完美结果拖了半年没上线。正确的做法是先上线一个MVP版本哪怕只用了关键词检索简单重排先跑起来收集数据然后快速迭代。搜索效果是迭代出来的不是设计出来的。7. 一些关于AI搜索的个人体会做搜索这些年我最大的体会是AI不是银弹。向量检索、重排模型这些技术确实能提升搜索质量但它们解决的是“语义理解”的问题解决不了“内容质量”的问题。如果站内内容本身质量差、重复多、信息密度低再好的搜索技术也救不了。所以做搜索优化之前先看看内容质量是不是达标了。另一个体会是搜索效果的提升是非线性的。从60分到80分可能只需要加一个重排模型但从80分到90分需要做大量的精细调优投入产出比会明显下降。所以要根据业务阶段来定目标不要盲目追求极致。最后说一个具体的技巧查询理解层一定要做日志。把每个查询的分词结果、意图识别结果、改写结果都记下来这些日志是后续优化的金矿。我通过分析查询日志发现了很多分词错误和改写过度的问题这些都是靠拍脑袋想不出来的。
返回列表