
🎯 学电商搜索与推荐的系统工程:不是调 Elasticsearch 或训练一个模型,而是从索引构建、查询理解、排序策略、个性化推荐、AB 测试到反馈闭环的完整系统工程。 ⏱️ 预计时间:45 分钟
[!tip] 💡 白话小课堂 搜索和推荐是一对双胞胎,但性格截然不同:搜索是用户主动找(我知道要买"碎花连衣裙"),推荐是平台主动推(我猜你喜欢这个)。搜索的核心挑战是"理解用户到底想搜什么"——输入"显瘦连衣裙",用户要的是版型显瘦,不是"显瘦"这两个字;推荐的核心挑战是"冷启动"——新用户没有行为数据时推荐什么?新品没有销量时怎么曝光?
[!warning] ⚠️ 避坑指南 三个常见的大坑:1)只用Elasticsearch做文本匹配没有查询理解——中文分词用空格分=完全不可用,必须接入jieba分词+电商词典;2)空结果不记录——用户搜不到东西是最差体验,比搜到不相关的结果还糟,必须记录所有query分析Top-N空结果词;3)推荐只看销量排序——新品永远没机会曝光,形成"强者恒强"的恶性循环。
[!info] 🔑 核心秘诀 搜索架构的四层漏斗:查询理解(分词+纠错+意图识别)→ 多路召回(文本+向量+协同过滤,至少3条路径)→ 排序(粗排→精排→重排)→ 反馈闭环(点击+转化的数据反向优化模型)。每一层都在过滤噪音,300万候选商品经过四层漏斗只剩200个——而用户只看到前20个。
[!quote]- 📖 课程来源 本课为系统设计大师课,内容综合自真实电商工程实践经验,而非单一 Skill 文件。涵盖架构设计、分布式系统、团队管理等高级工程主题。
1. 搜索 vs 推荐——不同的工程问题
搜索(用户主动找)
→ 用户意图明确:输入"夏季连衣裙 碎花" → 核心指标:召回率、精确率、搜索转化率 → 关键挑战:拼写纠错、同义词、类目预测、空结果处理
推荐(平台主动推)
→ 用户意图模糊:平台猜你喜欢什么 → 核心指标:点击率、加购率、GMV 贡献 → 关键挑战:冷启动、多样性、实时性、探索 vs 利用
搜索 + 推荐的交汇
→ 搜索无结果时 → 推荐替代商品 → 搜索结果排序 → 融合个性化信号 → 首页个性化 → 基于搜索历史的推荐
2. 搜索系统的分层架构
四层搜索架构
Layer 1: 查询理解(Query Understanding)
→ 分词:中文分词(jieba / HanLP)→ "夏季连衣裙碎花" → [夏季, 连衣裙, 碎花] → 纠错:Did You Mean "连衣裙"(不是"连衣群") → 类目预测:Query → 类目树(女装 > 连衣裙 > 碎花连衣裙) → 意图识别:搜索意图 vs 导航意图(搜品牌名 = 导航) → 实体识别:品牌名、颜色、尺码、材质、风格
Layer 2: 召回(Recall)
→ 文本召回:Elasticsearch BM25(标题 + 描述 + 属性) → 向量召回:商品 Embedding(CLIP / text2vec)→ 语义相似 → 类目召回:只在类目预测的类目下搜索 → 个性化召回:基于用户历史的协同过滤 → 多路召回合并:至少 3 条路径,每条取 Top-N → 去重 → 合并
Layer 3: 排序(Ranking)
→ 粗排(L1):简单特征(销量、评分、价格)→ Top 500 → 精排(L2):Learning to Rank(LambdaMART / DNN)→ Top 100 → 重排(L3):多样性、打散、业务规则 → 最终结果 → 特征工程:商品特征 + 用户特征 + 上下文特征 + 交叉特征
Layer 4: 反馈闭环
→ 点击率反馈 → 更新排序模型 → 转化率反馈 → 更新商品权重 → 无结果反馈 → 更新索引 / 同义词 → AB 测试 → 比较两个排序策略的效果
3. 推荐系统的工程挑战
推荐系统的冷启动问题
用户冷启动
→ 新用户无行为数据 → 用热门推荐 + 类目推荐 → 渐进式:第一次点击后 → 相关推荐 → 3 次点击后 → 协同过滤 → 利用注册信息(年龄、性别、偏好标签)
商品冷启动
→ 新品无行为数据 → 用内容特征(标题、描述、图片 Embedding) → 新品 boost:给予 24 小时曝光加权 → 快速收集行为数据 → 衰退策略:曝光 > 1000 次但 CTR < 0.5% → 停止推荐
实时性挑战
特征实时化
→ 用户刚看过某商品 → 推荐"相似商品" → 需要 < 1 分钟延迟 → 架构:Flink / Kafka Streams → 实时特征计算 → Redis 存储
模型更新周期
→ 排序模型:天级更新(夜间训练) → 召回 Embedding:周级更新 → 行为特征:分钟级更新(Flink 实时聚合)
4. 电商案例:搜索推荐双引擎——"搜得到"+"推得准"
🛒 实战案例:某综合电商平台日均搜索量50万次,但搜索转化率仅3.2%(行业基准5-8%),空结果率高达12%,首页推荐CTR仅1.1%。更糟的是,搜索和推荐两个团队各自为战——搜索团队用Elasticsearch BM25纯文本匹配,推荐团队用离线协同过滤T+1更新——两个引擎的数据、模型、评估体系完全割裂,GMV增长陷入瓶颈。
用 gstack 架构体系设计双引擎协同:
- /plan-eng-review 诊断现状 → 发现三大断层:搜索无查询理解(分词用空格分割→"显瘦连衣裙"搜不到"修身连衣裙")、推荐无冷启动机制(新品0销量=0曝光→强者恒强恶性循环)、搜索与推荐数据不互通(用户搜索"露营帐篷"后首页仍推"办公椅")
- /review 审查搜索服务代码 → 发现6个CRITICAL:中文分词使用空格分割(完全不可用)、ES查询无minimum_should_match(匹配1个词就返回→相关性极差)、空结果query未记录(无法分析用户搜了但没找到什么)、排序仅按销量(新品永远0曝光)、无拼写纠错("连衣群"=0结果)、推荐仅依赖商品协同过滤(冷启动商品完全不可见)
- /autoplan 生成4阶段改进方案:Week 1-2查询理解(jieba分词+电商词典+类目预测)→ Week 3-4召回增强(文本召回+向量召回+协同过滤三路合并)→ Week 5-6排序优化(XGBoost LambdaMART + 实时特征:最近5次点击+价格偏好+类目偏好)→ Week 7-8双引擎协同(搜索历史实时注入推荐特征、搜索结果页底部融合个性化推荐)
- /benchmark 验证搜索延迟:优化前P99=420ms → P99=295ms(ES+FAISS并行查询),推荐P99延迟从180ms降至45ms(特征缓存到Redis)
效果:
搜索转化率从3.2%提升至7.8%(14天AB测试,P<0.001,日均GMV增量约¥42万)
空结果率从12%降至3.1%(每万次搜索从1200次空结果降至310次)
推荐CTR从1.1%提升至3.2%(首页"猜你喜欢"模块),推荐贡献GMV占比从4%→18%
新品冷启动曝光:新上架商品24小时内100%获得至少500次曝光(内容Embedding召回+新品boost池)
搜索推荐协同效应:搜索过"露营帐篷"的用户→首页推荐帐篷配件→协同转化率4.7%(vs 无协同1.1%)
🔑 启示:搜索和推荐不是两个独立的系统,而是一个"理解用户意图"引擎的两个输出通道。搜索告诉推荐"用户现在想要什么",推荐告诉搜索"用户可能还喜欢什么"——两者的数据不互通是电商平台最大的隐性GMV损失。召回架构的核心不是"选ES还是FAISS",而是"多路召回合并"——文本召回解决字面匹配(30%贡献)、向量召回解决语义理解(40%贡献)、协同过滤解决个性化(30%贡献)——三者去重合并后,漏召回率降低70%。
5. 动手实践
- 为你的电商产品设计多路召回策略:列出至少 4 条召回路径(如关键词匹配、语义向量、协同过滤、热门商品),说明每条路径解决什么搜索意图。
- 设计排序特征工程:列出你用于排序的 10 个特征(如点击率、转化率、价格、评分、销量、季节性等),标注每个特征的数据来源和更新频率。
- 做一个搜索体验审计:在你的店铺搜索 5 个常见关键词,记录搜索结果的质量。识别至少 2 个可以立即优化的召回或排序问题。
[!tip] 提示:搜索优化的第一步不是改算法,而是理解"用户搜了什么但没找到"。先建立搜索日志(search log),分析"零结果查询"和"低点击率查询",这比任何算法调参都重要。
6. 掌握检验
Q1:搜索系统的四层漏斗中,"多路召回"为什么比单一的 Elasticsearch BM25 文本匹配更可靠?
- A) ES BM25 已经足够好,多路召回只是锦上添花
- B) 单一文本匹配无法解决"显瘦连衣裙"这样的语义理解——BM25 只能匹配关键词"显瘦"和"连衣裙",但无法理解"显瘦"=版型修身。多路召回(文本+向量+协同过滤)覆盖关键词匹配、语义相似、用户偏好三个维度,降低"用户想搜但搜不到"的概率
- C) 多路召回主要是为了技术展示,实际效果差异不大
- D) 多路召回解决了分词问题
Q2:排序的三阶段(粗排 L1 / 精排 L2 / 重排 L3)各自解决什么不同层次的排序问题?如果只用精排不用粗排,300 万候选商品直接过 DNN 模型会有什么工程后果?
Q3:推荐系统中,用户冷启动和商品冷启动的解决方法有何本质不同?如果一个新用户首次访问你的电商平台,首页"猜你喜欢"应该展示什么?为什么?
- A) 展示平台热销商品——新用户无行为数据无法个性化,热门推荐是最大公约数的最佳选择
- B) 展示随机商品让用户自己探索
- C) 展示最新上架的商品
- D) 不展示任何推荐,等用户搜索
Q4:gstack 在搜索优化案例中将空结果率从 12% 降到 3.1%——请列出实现这一改进的至少 3 个具体措施,并解释为什么"记录所有空结果 query"比"改进搜索算法"更优先。
Q5:在 gstack /review 审查搜索代码时发现了 6 个 CRITICAL 问题。请选择其中 2 个你认为对搜索体验影响最大的问题,分析:如果不修复,用户会看到什么?修复后,用户感受有何变化?
Q6:搜索和推荐虽然都是"帮用户找到商品",但核心工程挑战完全不同。请从"用户意图""核心指标""主要技术挑战""评估方式"四个维度对比搜索和推荐的差异。
7. 答案
点击查看答案
Q1:B — BM25 是纯文本匹配的检索模型,基于词频和逆文档频率。它无法理解"显瘦连衣裙"中的"显瘦"指的是版型修身而不是字面有"显瘦"两个字。文本召回解决字面匹配,向量召回(CLIP/text2vec Embedding)解决语义相似度——"显瘦连衣裙"与"修身连衣裙"在向量空间中距离很近;协同过滤召回解决个性化——"和你有相似购买行为的用户还买了什么"。三条路径并行召回,去重合并,大大降低漏召回率。
Q2:粗排(L1):从 300 万→Top 500,使用简单快速的特征(销量、评分、价格),模型极轻量(几十毫秒),解决"300 万不可能都进精排"的效率问题。精排(L2):从 Top 500→Top 100,使用 Learning to Rank(LambdaMART/DNN),综合商品特征+用户特征+上下文特征+交叉特征,解决"哪个最符合当前用户的偏好"的精准度问题。重排(L3):从 Top 100→最终展示结果,做多样性打散(避免全是同一品牌)、业务规则(新品加权、合规过滤),解决"精排只看单点分数导致的用户体验问题"。如果不用粗排直接 300 万过 DNN:单次搜索延迟可能从 300ms 变成数秒甚至数十秒,模型服务成本暴增百倍,且 300 万商品的 DNN 打分是无必要的资源浪费——用户只看前 20 个。
Q3:A — 用户冷启动时无任何行为数据,协同过滤和个性化模型都不可用。此时最合理的策略是展示平台全局热销商品——这是"最大公约数"偏好,虽不个性化但至少是大多数人喜欢的。同时采用渐进式策略:第一次点击后→基于点击商品的相关推荐;3 次点击后→协同过滤开始可用。商品冷启动的解法不同:用内容特征(标题 Embedding、类目、属性)在没有销量数据时也能被向量召回检索到,并给予 24 小时新品曝光加权快速收集行为数据。
Q4:三个具体措施:(1) 接入 jieba 分词 + 自定义电商词典,解决"空格分割导致中文搜索不可用";(2) ES 查询增加 minimum_should_match: "70%",避免"搜夏季碎花连衣裙中长款但匹配夏季就返回";(3) 多路召回(文本+向量+协同过滤),解决纯文本匹配的语义理解缺陷。空结果日志优先于算法优化:因为空结果意味着用户明确表达了意图但系统完全无法响应——这是最差的用户体验。记录所有空结果 query → ETL 分析 Top-N 空结果词 → 发现"用户搜了但系统没有"的模式——比如"大码女装"搜不到但系统里有只是标签不同——这比盲目改进算法更精准有效。
Q5:选择(1) 分词使用空格分割和(2) 空结果未记录。不修复分词问题:用户搜索"碎花连衣裙"→空格分割成无效单字→搜索结果返回所有包含"碎""花""连""衣""裙"中任意一个字的所有商品→完全无相关性→用户困惑"这个平台连连衣裙都搜不到"。修复后:jieba+电商词典→正确分词为["碎花","连衣裙"]→精准返回碎花连衣裙。不修复空结果:用户搜"大码女装"但系统没匹配→空白页面→用户以为平台不卖大码→流失到竞品。修复后:记录空结果→ETL 分析发现"大码"是商家用的标签而非标题→补充同义词映射→下次搜索命中→用户找到商品。
Q6:对比维度:(1) 用户意图——搜索:明确、主动("我想买碎花连衣裙");推荐:模糊、被动("猜猜我喜欢什么")。(2) 核心指标——搜索:召回率、精确率、搜索转化率、空结果率;推荐:点击率(CTR)、加购率、GMV 贡献、多样性。(3) 主要技术挑战——搜索:查询理解(分词/纠错/意图识别)、空结果处理、稀疏查询(长尾关键词);推荐:冷启动(用户和商品)、实时性、探索 vs 利用(Exploration vs Exploitation)、多样性。(4) 评估方式——搜索:offline 指标(NDCG/MRR)+ online AB 测试;推荐:offline 离线回放 + online AB 测试(点击率和 GMV)。
(5/6 通过)
延伸阅读
- [[L7-04-支付链路可靠性|上一课:支付链路可靠性 —— 每笔订单都像银行转账一样分毫不差]]
- [[L7-06-微服务拆分|下一课:微服务拆分 —— 把大泥球一步步拆成乐高积木的正确姿势]]
- [[L6-37-浏览器自动化|相关:浏览器自动化——搜索体验测试]]

评论区
共 0 条评论