新闻详情

新闻详情

首页 / 资讯中心 / 详情

从 Elasticsearch 到 AI 搜索:电商搜索系统的进化路径与实践

发布时间:2026/9/16 2:06:47来源:尧图网络
从 Elasticsearch 到 AI 搜索:电商搜索系统的进化路径与实践
搜索模块是电商系统里最容易被低估的一个环节。我刚接手搜索系统的时候它在整个研发团队里的定位属于“能用就行”——一个输入框一个列表页后端挂一台 Elasticsearch商品数据每天凌晨全量同步一次用户敲什么关键词系统就按词匹配什么结果。当时谁都没觉得这会成为问题。可等到商品池从几万涨到几十万搜索从“锦上添花”变成整个站点转化率最高的入口之一问题就接踵而来分词不准、同义词没人维护、长尾词搜不到、排序规则频繁被运营投诉。于是我们开启了一个从单体搜索逐步进化到 AI 搜索的改造过程过程很痛苦但回头看这套进化路径几乎可以回答电商搜索系统建设中大部分“下一步怎么办”的疑问。1. “先用起来”阶段单体搜索的架构形态与隐性成本1.1 单体搜索的典型技术形态按现在互联网团队的标准看早期电商搜索基本不算一个系统顶多算业务系统里的一个功能。常见做法是业务代码里直接封装搜索客户端商品、库存、价格的数据都保存在业务数据库然后通过定时任务或者接口调用的方式喂给搜索引擎。具体到技术选型小型团队往往从 MySQL 的 LIKE 查询起步等到商品量上来再迁到 Elasticsearch。也有不少人直接选择开源商城项目起步比如 mall4j 这类 Java 商城开源社区提供了完整的 Docker 部署包一个 docker-compose 文件就能把 Tomcat、MySQL、Redis、ES 全部拉起来。这种单体部署的好处非常明显上手快、环境一致、给客户演示方便。商品索引在一个 ES 索引里搜索和详情共用同一个 Spring 服务开发的时候一个 Application 起来就能联调。这种形态在商品只有几千、日搜索量只有几百的时候完全够用。倒排索引本身就足够支撑简单的关键词匹配BM25 的排序模型在大多数情况下也“像个样子”。团队的时间可以花在品类管理、订单流程、支付体验这些核心主链路上。可以说单体搜索是绝大多数电商项目最合理的起点如果谁告诉我一个新项目上来就搞微服务加向量数据库我反而会怀疑他是不是只想凑技术亮点。1.2 最先暴露问题的不是性能而是数据口径真正让我对单体搜索产生警惕的不是搜索慢而是数据错乱。在早期系统里商品下架、库存变更、价格调整这些动作都发生在业务数据库而 ES 里的索引需要靠定时任务同步。同步频率设成 5 分钟一次大促期间经常出现用户在前台看到商品有库存提交订单时提示缺货运营把商品价格改了搜索结果页却保持老价格。用户投诉到客服客服找开发开发一查索引更新时间是昨天凌晨两点只能安抚用户说“缓存更新有延迟”——但实际情况是同步链路本身靠不住不是缓存的事。还有一个坑排序规则散落在业务代码里。运营希望“销量高的排前面”开发就在查询条件里加了一个 sort 字段后来需求改成“新上架加权重”又有人在前端参数里拼了一个字符串。日积月累一个看似简单的搜索接口里堆积了十几套排序规则有些规则之间甚至互相冲突最后谁也不敢动因为动一个字段就可能影响线上转化。从这时候开始我意识到搜索不是一个纯检索问题它首先是数据一致性问题然后是相关性优化问题最后才是性能问题。这个认知直接影响了后面的拆分方案。2. 拆分开工把搜索能力从业务单体里剥离出来2.1 同步链路如何把商品、库存、价格数据搬到搜索集群拆的第一刀不是把 ES 集群单独拎出来而是重构“业务数据 → 搜索索引”的数据通道。这一步是后续所有优化的地基。我们最终采用的方案是业务库开启 binlog通过 Canal 监听商品、SKU、库存、价格相关表的变更事件写入 RocketMQ搜索服务消费消息后将变更同步到自己的文档模型里再更新 Elasticsearch。全量数据通过离线任务定期重建增量数据靠消息队列保证最终一致。Canal 的原理其实不复杂它把自己伪装成 MySQL 的从库读 binlog 然后解析成结构化事件我们只需要在消费端定义好“主键变了怎么办、库存变了怎么办、价格变了怎么办”这些规则。这套链路加上对账任务之后搜索结果的脏数据率明显降了下来。工程上有一个容易被忽略的细节消息里不能只传主键 ID然后让消费端回查业务库因为大促期间回查会把业务库打爆而且业务库和搜索库的状态之间存在时间窗口。我们的做法是把变更后的必要字段直接序列化进消息体消费端拿到什么就更新什么最多再补查一次 Redis 缓存。这里也解释了我对“为什么搜索服务必须拆分”的看法。拆分不是技术洁癖而是因为搜索的写入模型和业务的事务模型完全不同。业务系统关注的是状态一致性搜索系统关注的是文档新鲜度业务库要防止并发写冲突搜索库要接受批量覆盖。这两种诉求放在同一个进程里迟早会互相拖累。2.2 商品文档模型从三范式到搜索宽表拆出独立服务后第一个要重新设计的就是文档模型。业务数据库为了减少冗余会把商品、SKU、属性、品牌、类目拆成一堆表查询时再 JOIN。但搜索引擎最适合的是扁平化、冗余存储的宽表结构最好把所有能用于检索和排序的字段都堆到一个 JSON document 里。我通常会这样设计商品索引文档顶层包含商品 ID、标题、副标题、品牌、类目路径、上下架状态结构化字段单独列出来比如价格、销量、库存状态、上架时间属性字段用嵌套对象或者 flatten 后的键值对比如“颜色: 白色”“尺码: L”“填充物: 90绒”。标题、卖点、详情里提取出来的关键词作为文本字段参与 BM25 相关度计算这些文本字段同时也会做向量化用于后面的语义召回。{ product_id: 100234, title: 中长款白色羽绒服 90绒加厚, category_path: [女装, 羽绒服], brand: 示例品牌, price: 899.00, stock_status: 1, status: 1, attrs: { color: 白色, fill_power: 90绒, length: 中长款 }, title_embedding: [0.035, -0.102, 0.289] }很多从单体转型的开发会问一个非常实际的问题SKU 和商品到底应该各建一个文档还是合成一个文档我的经验是检索维度以商品为主价格、库存、规格等和购买决策强相关的字段取主 SKU 或者最低价格 SKU 的值展开到商品文档里。真要做 SKU 级筛选时再根据商品文档里的子 SKU 列表二次过滤。这样能避免同一个商品的不同 SKU 在搜索结果里互相抢占位置。还要注意不是说把字段全塞进文档里就完事。ES 里的 mapping 设计要区分“用于全文检索的 text 字段”和“用于过滤聚合的 keyword/数值字段”。很多团队图省事把所有字段都配成 text结果搜索“白色羽绒服”时商品标题里的“白色”和属性里的“颜色: 白色”都被命中相关度计算反而被稀释了。我们后来把颜色、尺码、品牌、类目都改成了 keyword 类型并启用子字段需要分词的才走 text相关度评价指标才稳定下来。拆分子服务之后ES 的写入和查询压力也更容易隔离了。以往大促数据同步高峰会把搜索写入线程占满拖累查询拆分后可以把写入队列、查询线程池、熔断阈值分开配置。再往后即便是要升级集群版本、调整 mapping也可以在独立环境里做验证而不需要拉着整个商城发版。3. 关键词搜索的天花板为什么这个时代的搜索需要 AI3.1 关键词搜索到底“死”在了哪几个真实场景上说实话关键词搜索并没有“死”它在短时间内依然是电商搜索的主入口。但它的瓶颈特别清晰只能做字面匹配理解不了用户真正的需求。我随便举几个后台日志里真实出现过的搜索词大家应该都能感同身受。第一个类型是口语化长句。用户会搜“给爸爸的生日礼物 预算五百以内”这句话里没有几个词的顺序是标准的商品标题传统分词器把它切成“给 爸爸 的 生日 礼物 预算 五百 以内”里面“预算五百以内”根本匹配不到任何价格字段最后只能靠运气返回一些爸爸衫或者礼品盒。第二个类型是同义表达。用户在北方说“保暖内衣”在南方可能叫“秋衣秋裤”搜索“显瘦穿搭”和“收腰连衣裙”对应的其实是同一种审美诉求字面完全不一样。第三个类型是属性组合查询。“白色 羽绒服 中长款 90绒”这种查询其实包含三个属性传统搜索只能靠分词硬拆很难精确映射到相应的属性字段上于是经常出现白色羽绒服第一屏里有 80 绒、短款这些本来不该出现的商品。这些问题在小商品池里可以靠人工堆同义词、维护运营规则掩盖过去可一旦商品池上了十万百万人工规则就维护不动了漏匹配率会明显上升。我们当时统计过一个数字日均搜索词里包含两个以上实体属性的查询占了 37%而传统搜索方案对这类查询的相关性评分和用户真实点击行为之间的相关系数已经降到了比较低的水平。换句话说系统返回的“相关”跟用户认为的“相关”已经严重脱节了。3.2 AI 搜索在电商搜索里的能力边界与设计目标为什么会想到用 AI 搜索来补这个缺口一方面语义向量模型确实能把“文字意思”变成向量距离让“保暖内衣”和“秋衣秋裤”在向量空间里靠得很近解决同义匹配和口语化表达的问题。另一方面现在不少用户已经被通用 AI 搜索工具以及那些同时聚合多个 AI 搜索结果一起展示的站点影响了使用习惯大家越来越习惯用自然语言提问而不是刻意地挑几个关键词。这种习惯一旦形成就会顺理成章地期望电商搜索也能“懂人话”。但电商搜索里的 AI 不能做成“大模型胡答”。它有两条明确的能力边界。第一搜索结果必须服从业务约束商品必须在架、有库存、价格区间必须匹配、配送范围要能覆盖这些硬条件任何情况下都不能被语义相似度带偏。第二它对准确性要求很高不是生成一段看起来合理的文本就算完而是必须真的把商品找出来、排对序。所以我们在设计目标里把 AI 搜索拆成三个阶段阶段一是“理解查询”把用户输入转换成意图、实体、属性、约束条件阶段二是“召回与过滤”综合字面匹配和语义匹配找到候选集再用业务条件过滤阶段三是“排序与解释”用更精细的相关性模型重排并在前端给用户展示“推荐理由”。具体落地到工程系统时这几个阶段是环环相扣的。3.3 通用 AI 搜索和电商 AI 搜索的差异很多产品经理容易把通用 AI 搜索的使用体验直接搬到电商里结果翻车。通用 AI 搜索的核心任务是信息综合用户要一篇“XX 品牌的口碑对比”AI 可以把多篇内容揉成一段摘要电商搜索的核心任务是商品决策用户要的是“可以下单的那个商品”不是一段关于商品有多好的描述。这意味着电商 AI 搜索要把“内容生成”和“商品检索”当成两条并行管线检索管线决定哪些商品能出现在结果里生成管线负责解释为什么推荐这些商品。生成内容不能反过来篡改商品列表。我在项目里反复对团队强调先保证商品列表的相关性再让人去美化解释文案。列表不对文案越动听用户越觉得不靠谱。4. 混合召回与重排序电商 AI 搜索的系统核心4.1 多路召回让传统引擎和语义向量各司其职AI 搜索落地时最容易犯的错误是“把传统搜索整个扔掉全用向量检索”。我在初期也做过类似的方案结果发现小词命中率和精确过滤能力严重下降。比如用户搜“iPhone 15 128G”关键词召回靠“iPhone 15”能非常精准地把品牌、型号锁定向量检索反而可能召回一批“类似手机壳”“手机支架”之类的边缘商品因为它们的标题向量和查询向量足够近。靠谱的方案是多路召回对一个查询同时发起文本召回和语义召回最后把多路结果融合。文本召回继续承担精确匹配的职责处理型号、品牌、SKU 编码这类硬词语义召回承担同义扩展和口语化理解的职责处理“保暖内衣”找到“秋衣秋裤”这类软匹配。两路结果合并之后再用业务过滤条件把下架、无库存、超预算的商品剔除。可以用一个简单的表来理解不同召回路径的分工召回路径输入形式擅长解决的问题典型弱点文本召回分词后的关键词型号、品牌、SKU编码精确匹配对同义词、口语表达无能为力语义召回查询向量近义词、意图扩展、长句理解可能召回“看起来像但实际不对”的边缘商品类目导航类目路径或预测类目限定结果范围适合大促会场用户意图不明确时不适用伪代码大概是这种感觉def multi_recall(query, filters): # 文本召回 bm25_results es_search(indexproduct, querybuild_bm25_query(query)) # 语义召回 query_vector embedding_model.encode(query) vector_results vector_search(indexproduct_embedding, vectorquery_vector, top_k200) # 结果融合RRF 或者去重后按分数加权 candidates rrf_fusion(bm25_results, vector_results) # 业务过滤 return apply_business_filters(candidates, filters)融合算法可以直接用 RRFReciprocal Rank Fusion简单稳定不需要训练权重。它的思路是只关注每条结果在各路中的排名位置把排名倒数加和。我更倾向于先做粗融合把候选集扩大到 500 以内再用后面更精细的重排序模型慢慢排而不是在两路召回阶段就把结果卡死。4.2 重排序与业务规则的博弈召回阶段的目标是把可能相关的商品尽量多地捞回来所以召回集往往是“大而全”真正的排序反而更重要。这个阶段我推荐引入一个轻量级的 cross-encoder 重排序模型把用户查询和候选商品做深度交互打分替代早期那种“向量检索完就按相似度排序”的做法相关性的区分度会明显上升。但电商排序不能只讲语义相关它还要平衡很多业务指标转化率、毛利率、广告坑位、库存深度、运营主推等等。我们的排序公式把重排序模型的相关性分和业务加权分合并相关分占大头业务分只负责在相关分数接近时进行微调。这样能避免一个常见灾难某件商品语义上高度相关但库存只有两件却因为向量相似度最高被推到了第一位用户点进去已经没货了。可以把排序特征拆成两类特征类型举例作用相关性特征重排序模型得分、语义相似度、BM25分确保商品与查询意图匹配业务特征库存状态、价格带、近7天转化率、毛利确保结果可购买、可下单、可持续转化4.3 向量数据库与搜索引擎的配合聊到架构很多人会问一个问题是不是要单独引入一套向量数据库我的答案是视体量而定。商品池在百万以内ES 自带的向量检索能力或者 Redis 向量模块就够用了商品池到了千万级别查询并发又高再考虑接 Milvus 这类专用向量库。先别急着迎接新技术。如果现有 ES 集群能扛住文本检索把它改造成“文本向量”双索引是成本最低的方案。我们当时的实践是文本字段和向量字段放在同一个索引里查询时用 bool 查询同时发起ES 内部做粗筛再到应用层做融合。只有当你发现向量检索的 QPS 和延迟开始挤压文本检索的核心资源池时再让向量服务独立部署也不迟。关于向量化任务商品侧要离线批量完成一个商品生成一个 768 维向量来源是标题、卖点、类目和属性拼接后的文本。查询侧必须在在线服务里实时生成向量所以 embedding 模型要部署成独立服务并做好 batch 推理优化。我们当时把 embedding 服务单独部署了一组 GPU/CPU 混合实例再在前面加一层本地缓存长尾词才会真正走到模型推理那一步。5. 落地过程中最容易被忽略的三件套数据、评测、灰度5.1 搜索日志与标注集AI 搜索的“训练土壤”很多团队做 AI 搜索的第一反应是“先找个模型接进来”这其实顺序反了。没有数据AI 搜索就是一个黑盒子你根本不知道它哪里变好了、哪里变坏了。我们需要把搜索日志当成最重要的资产来建设。行为日志至少包括这几个字段query 原文、query_embedding、结果集 ID 列表、展示顺序、用户点击了哪些结果、点击后有没有加购或下单、结果是否缺货、用户是否在短时间内换了别的词重搜。有了这些数据我们才能算出准确率、召回率、点击率、转化率这些基础指标也才能给人工标注团队提供“用户搜这个词点击了那个商品”的弱标注样本。在离线评测上我们维护了一个从线上日志里抽出来的标注集每条 query 标注出 0、1、2 三档相关度0 表示不相关1 表示边缘相关2 表示明显相关。每次搜索算法或模型升级先在标注集上跑一遍看 NDCG、MRR 这些指标有没有回退再决定要不要线上实验。如果线上跑出来的表现和离线评测偏差很大大概率是行为日志埋点的问题比如没有记全结果集、排序位置和曝光信息。5.2 分阶段灰度与回退别让 AI 把转化率带崩即使离线评测通过我仍然不建议直接把 AI 搜索全量开放。AI 搜索天然存在一定的随机性特别是像 embedding 模型升级或重排序模型参数调整很容易在某个品类上出现意外回退。灰度就是把这部分风险控制在一个可控范围里。我们的灰度策略一般分三步先在一个品类或者一个流量小站点灰度观察相关性指标再把流量比例放到 5%对比全网大盘的搜索成交转化率如果 A/B 实验置信区间没有显著变差才逐步提高到 20%、50%、100%。整个过程的回退方案在第一步就要准备如果 AI 搜索的召回数量低于某个阈值或者在线 p99 延迟超过 800ms就直接切回关键词搜索的主链路。我印象很深的一次事故是整体平均指标都正常但把 A/B 结果按类目拆开一看品牌词的精准召回反而下降原因是升级后的向量模型把品牌名错误地当成了一串普通词汇导致好几个官方旗舰店商品被排到了后面。如果不是提前按类目拆分监控这次事故很可能被平均数据掩盖等到全量上线后再被动回滚影响面就完全不同了。这类排查过程比模型选型更考验工程功底。5.3 成本控制不是所有查询都值得走语义模型成本控制也需要提前算。向量检索的存储成本和计算成本都比纯文本检索高如果每天搜索量在百万级一个 768 维的向量字段至少要占用一份不小的内存资源。常用手段包括为高频 query 做结果缓存、按商品离线生成向量并用低维模型压缩、只在长尾词和口语化查询上开语义召回其他词直接走文本结果。我们在生产环境的做法是维护一份“语义路由表”记录哪些 query 触发了语义召回且明显提升了转化哪些 query 走语义召回反而召回了一堆边缘内容再把这个路由表回流到路由策略里做精细调度。比如“iPhone 15”这种高频精准词直接走文本被召回就够了没必要浪费一次向量检索而“适合拍照的轻薄外套”这种组合意图词才需要向量召回来解决。用这种混合路由语义召回只承担 20% 左右的查询流量但贡献了相当一部分长尾转化整体成本可控。6. 从“搜索框”到“购物助手”下一步演进与阶段取舍6.1 从“搜索框”到“购物助手”搜索进化的终点不是“用一个更聪明的模型替代现有模型”而是改变用户和商品之间的交互方式。现在很多搜索系统已经不再满足于“输入关键词→给结果列表”而是开始做连续对话、动态筛选、多轮澄清。用户说“给爸爸的生日礼物预算五百以内”系统可以马上问“爸爸平时喜欢什么运动喝茶还是钓鱼”然后不断缩小候选范围。这种体验本质上把搜索从单次行为变成了一个会话任务。工程上要支撑这种交互搜索系统的形态会从“索引 查询接口”变成“一个能理解任务、拆分任务、逐步执行的智能体”。查询理解模块会进一步拆分出意图识别、槽位填充还会记住多轮对话里的上下文。比如用户上一轮说了“预算五百以内”下一轮直接说“白色那款”系统需要自己把颜色条件和预算条件合并在一起去更新检索条件和排序条件。这就对会话状态的建模和搜索中间态的存储提出了新的要求。6.2 演进到什么程度取决于你的体量聊完演进方向我还是想说点泼冷水的话不是所有电商系统都需要立刻冲到 AI 搜索这一步。如果商品池只有几千件、日均搜索两百次老老实实用单体加关键词搜索把精力花在供应链和运营活动上投入产出比要高得多。技术演进是受业务规模驱动的不是为了一个名词去推倒重来。对已经走到中大型规模、搜索成为核心转化入口的系统我的建议是把单体搜索当成起点没有问题但要有意识地在早期就把数据口径、日志埋点和可回退架构这三件事做好。这三件事就像是地基不管以后是接语义向量还是上大模型都用得上。如果地基没打好后面每加一个模型都是给原本松散的架构继续添乱最后只能陷入无休止的“方案争论”。6.3 回过头看的几点体会最后说几句我个人的体会。第一无论架构怎么演进搜索系统的第一原则永远是“先能度量再谈提升”。没有搜索日志、没有行为埋点、没有离线评测集任何 AI 算法都是空中楼阁。第二别为了淘汰单体而淘汰单体。单体搜索变成了过去的形态不代表它没有价值它让我们在最需要跑通业务的阶段用最低成本完成了搜索能力的建设。第三AI 搜索的每一步改造都要有回退开关把它当成一个可以随时摘掉的工具而不是一个不可逆的信仰。我在这个项目里最大的收获是理解了一个系统从简单到复杂、再从复杂到智能的完整过程。单体搜索让我们活了下来独立搜索服务让我们跑得更顺AI 搜索让我们开始理解用户。每一步都不是为了追概念而是被实打实的业务问题推着往前走。电商搜索的进化本质上就是数据和算法逐渐向“人”靠拢的过程。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

OpenCV双目立体匹配SGBM原理与参数调优实战指南 2026/9/16 3:45:54

OpenCV双目立体匹配SGBM原理与参数调优实战指南

1. 双目立体匹配到底在解决什么问题1.1 三角测量与视差先说一个最基本的公式,后面所有内容都围绕它转:Z f * B / d其中 Z 是目标点到相机的深度,f 是焦距(像素单位),B 是左右相机光心之间的距离&#xff0…

阅读更多 →
千元无人机怎么选?十大性价比机型实测与避坑指南 2026/9/16 3:45:54

千元无人机怎么选?十大性价比机型实测与避坑指南

千元无人机这个价位段,说实话是市场上最“鱼龙混杂”的地方。往上有大疆Mini系列压着,性能和体验确实没得挑;往下有三四百块的“玩具级”飞行器,飞起来跟放风筝似的,图传卡成幻灯片,电机飞两三次就报废。真…

阅读更多 →
可编程数字栅极驱动:从分段波形整形到AI可靠性估计的实战指南 2026/9/16 3:45:54

可编程数字栅极驱动:从分段波形整形到AI可靠性估计的实战指南

做功率电子的朋友肯定都经历过这种场面:新板子打样回来,示波器探头一搭Vds,振铃大得以为探头坏了,开通过冲差点把SiC MOSFET的耐压干穿;把栅极电阻从10Ω一路试到100Ω,损耗上去了,EMI却还在限值…

阅读更多 →
基于H∞与RLQR的铰接式重型车辆鲁棒路径跟踪控制 2026/9/16 3:45:54

基于H∞与RLQR的铰接式重型车辆鲁棒路径跟踪控制

在铰接式重型车辆的控制圈子里,路径跟踪一直是个不太好啃的骨头。车子本身就长,还拖着挂车,高速跑起来之后车头和挂车之间的铰接角一旦控制不好,轻则甩尾摆振,重则直接折叠失控。这些年我一直在做商用车主动安全控制&a…

阅读更多 →
U-Net语义分割实战:皮肤癌图像分类模型全流程解析 2026/9/16 3:45:54

U-Net语义分割实战:皮肤癌图像分类模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
LLM工程师面试真相:从原理到端侧推理的七道生死关 2026/9/16 3:42:54

LLM工程师面试真相:从原理到端侧推理的七道生死关

1. 这不是“面经”,是LLM工程师真实战场的作战地图“LLM面经(一)”这五个字,最近在技术社区里刷屏得有点狠。但说实话,我翻过不下两百份标着“LLM面经”的文档,八成以上是把Transformer公式抄一遍、把Atten…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞