想象你走进一家大型超市,金牌导购王姐迎了上来。你还没来得及开口,她已经根据你上次买的咖啡和零食,推测你可能想要什么,顺手从货架上抽出几样放到你面前——这叫“召回”。接着,她没有把商品随手一扔,而是把你最可能买的、最划算的、最匹配口味的那件放在最上面——这叫“排序”。最后,她还根据你的犹豫表情,补了一句“如果不喜欢,这边还有新品可以试试”——这叫“冷启动”和“重排”。整个过程行云流水,你还没反应过来,购物车已经满了。 电商搜索背后的技术,干的就是王姐这档子事。用户输入一个关键词,系统要在几亿商品里快速圈出几百个“可能想要的”(召回),再按用户偏好把这几百个排出先后(排序),最终展示在前台。谁能把这件事做得又快又准,谁就能把用户留在自己的平台里,把“逛一逛”变成“买一买”。
对 AI 从业者而言,搜索排序与召回是推荐系统中最具商业价值的技术高地——理解它能让你掌握用户意图匹配、模型排序和系统架构的核心能力,直接对话 GMV、转化率这类的业务指标,是成为电商领域 AI 专家的必修课。
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
Top-10 精排结果 电商搜索排序可视化:展示Query理解、多路召回、粗排、精排、重排的完整链路
搜索全流程
王姐做导购的第一步,从来不是直接冲进货架,而是先打量你、听你说完“我要什么”。你含糊地说“想买个耳机”,她心里已经在拆解你的话:是有线的还是无线的?是听歌还是打游戏?这个“拆解需求”的动作,在搜索系统里叫查询理解——把用户输入的几个字翻译成系统能执行的条件。
拆解完需求,王姐开始行动了。她不会把整个超市翻一遍,而是凭经验快速圈出几个区域:数码区、配件区、促销堆头——这个“圈货架”的动作就是召回,目标是在亿级商品中快速捞出一批候选。捞出来之后,她还会顺手做一次粗略筛选,比如单价太高的先放一边,这叫粗排,起到“漏斗收口”的作用。
真正见功力的是最后的精排与重排。精排像王姐根据你的预算、品牌偏好、历史购买,把候选商品打上“最可能买”的分数,按分数从高到低排好;重排则是她最后的人工调整——“这两款是同品牌的,放一个就行,别让顾客看花眼”,于是加入多样性打散、插入活动商品。整个流程构成一个漏斗:亿级 → 千级 → 百级 → 十级,每一层都在丢弃不合适的商品,留下来的是最有可能成交的。
召回策略
王姐要同时伺候好几个顾客,每个顾客想要的东西千奇百怪。她不可能每次都亲自跑遍全部货架,于是发展出一套“多路找人”的本事——这对应搜索系统的召回策略。
第一路叫词法召回。就像王姐听到“耳机”就直奔数码区的耳机货架,系统用 BM25 这类算法,在商品标题、类目、品牌字段里做关键词匹配。它简单直接,但有个致命弱点:用户搜“煲汤锅”,商品标题写“陶瓷炖盅”,词对不上就召回不了,这叫做词义鸿沟。
第二路向量召回就是为了跨越这道鸿沟。它把用户查询和商品都映射到一个向量空间里,语义相近的文本向量距离也近。搜“煲汤锅”时,“陶瓷炖盅”的向量离它不远,于是能被捞出来。这就像王姐听到“想喝汤”,不只拿汤锅,还会顺带想到砂锅、炖盅——因为她理解了“汤”背后的场景。
第三路协同召回,走的是“和你相似的人买了什么”的路子。王姐记得上次有个和你年龄相仿的顾客,买了耳机又加购了耳机收纳盒,于是她也给你拿了一个。系统通过用户行为矩阵做协同过滤,挖掘群体智慧。
各路召回的结果参差不齐,有的重相关、有的重个性,于是需要多路融合:把多路的候选集合起来去重,设定权重分配名额,保证最终候选池既有相关性又有惊喜。王姐的做法是:货架主力款拿 5 件,潮流新品拿 2 件,和你类似的顾客爱买的拿 3 件——每路都有出场机会,最后汇成一个小推车。
排序模型
候选商品圈到几十个了,接下来王姐要排出个“先给我看哪个”的次序。排序的核心,是给每个商品打一个“用户会买”的分数,分数从何而来?来自排序模型。
最早期的模型是逻辑回归(LR)。它的思路很朴素:把所有可能影响购买的因素——价格、销量、用户历史点击、品牌——都作为特征,每个特征学习一个权重,最后加权求和,输出一个 0 到 1 之间的概率。就像王姐心里有一本账:“你之前买过这牌子 +10 分,价格超过预算 -5 分,销量高 +3 分……”算个总账。LR 简单、可解释性强,但它只能捕捉特征的线性关系,学不到“价格低且品牌好”这类非线性组合。
于是树模型登场,GBDT 是其中的代表。它把特征空间切分成很多小块,在每个小块里学一个预测值,本质上是自动发现了特征的交叉组合。这相当于王姐总结出经验:“年轻顾客 + 外观时尚 + 价格适中 = 高概率购买”,她不需要别人告诉她这些规则,而是从一次次成交中总结出来的。GBDT 对表格类特征非常友好,一度是排序的主力。
但 GBDT 对高维稀疏特征(比如几百万个商品 ID)力不从心,于是深度排序模型走上前台。DNN 先把用户和商品的离散 ID 映射成稠密向量,再通过多层网络自动学习特征交互。就像王姐的大脑里,每个顾客不是一个标签,而是一个立体的“画像向量”;每个商品也是一个“商品向量”;二者做内积、拼接、交叉,最终输出购买概率。深度学习让模型从“人肉总结规则”升级到“自动发现模式”。
不过,排序的目标不只是一个概率。用户真正希望的是:排在最前面的永远是最想要的——这对应学习排序(LTR) 的思想。它不满足于“预测点击率”,而是直接优化“排在最前的那几个是否对”。它的损失函数像王姐的考核标准:不看你单次推荐对不对,而看你推荐的 TOP 10 里顾客买了几个。
排序模型沿着 LR → GBDT → DNN 的路径进化,正如王姐从“手写顾客档案”到“心算成交概率”再到“直觉般预判需求”的成长——模型越深,越能捕捉用户说不出口的偏好。
- 特征加权求和将所有特征值乘以对应权重并相加,得到一张“总评分”。
- Sigmoid 压缩把任意实数 z 映射到 0~1 区间,变成概率。
- 输出概率模型输出用户点击该商品的概率,排序时按概率从高到低排列。
特征工程
决定王姐推荐水平的,除了她的经验模型,还有她眼里能看到什么信息。一个新手导购只看到顾客的年龄和性别,王姐却能看到更多——这就是特征工程的威力:特征决定上限,模型逼近上限。
用户特征刻画的是“你是谁”。基础属性如年龄、性别、地域,历史行为如过去 7 天点击过哪些类目、加购过什么价位段的商品,还有实时行为如当前是否在比价。王姐的服务秘诀正是“记得住老顾客”——系统用特征把用户的行为记忆数字化。
商品特征描述的是“货是什么”。类目、品牌、价格、销量、好评率、近 30 天加购转化率……这些统计特征像商品包装上的标签,让模型快速判断“这件货本身够不够硬”。
真正拉开差距的是交叉特征。用户特征和商品特征单独看,信息有限;一旦交叉,价值倍增。比如“用户性别=女 × 商品类目=连衣裙”就比单独两个特征有力得多。GBDT 天然擅长这种交叉,而深度模型则通过 embedding 在隐空间自动学习。王姐的直觉“这个年纪的男士在礼品区停留,多半是给女友挑礼物”,就是一种交叉特征。
有了特征,还得有 样本构造。模型要学“什么情况该推荐什么”,得有标注好的数据。正样本是曝光后点击或购买的商品,负样本是曝光未点击的商品。这里最讲究的是采样比例:负样本太多,模型会变得过于保守;太少,又学不到区分度。王姐培训新人的时候,总是强调“不只要记住成单的例子,也要记住顾客摇头走开的例子”——负样本才是让模型知道“什么不该推”的关键。
冷启动
新来的顾客第一次进店,王姐没有任何关于他的记录。他不开口,你连他是南方人还是北方人都不知道——这是用户冷启动。新上架的网红商品,一件都没卖出去,没有任何销量数据——这是商品冷启动。
用户冷启动靠什么破局?王姐的策略是“轻轻试探”:先拿几类大众款出来,观察顾客在哪儿停留、对什么问价。系统也一样,给新用户推荐热门商品,同时收集点击反馈,快速建立用户画像。这叫探索与利用的权衡——拿不确定的推荐去换取用户信息,再逐步收敛到个性化。
商品冷启动则相反。新品没有点击数据,排序模型给不出高分,会陷入“没曝光 → 没数据 → 没曝光”的恶性循环。王姐遇到新品,会把它放在显眼位置,用“新品”标签吸引注意。系统则通过属性迁移来破局:新品虽然没销量,但它和已售罄的爆款同属一个品牌、同一种风格、同一价位段,那就借用“同款旧品”的特征来预测它的潜力。
最后的兜底手段是策略干预。无论算法多智能,总有覆盖不到的场景。平台可以人工配置规则:新用户前 3 次搜索强制展示若干低门槛商品,新品上架 7 天内给固定曝光位。就像超市规定新品必须上堆头试销两周——规则兜底,模型调优,二者并行不悖。
指标评估
王姐的导购水平怎么衡量?最粗暴的标准是看“她一天促成多少成交额”。对应到搜索系统,这个“成交额”就是 GMV——搜索给平台赚了多少钱,是最终极的业务指标。
但只看 GMV 太滞后了,你需要拆解它:GMV = UV × 点击率 × 转化率 × 客单价。于是有了技术指标来诊断每一层漏斗。CTR(点击率) 衡量“用户看到结果之后愿不愿意点”,反映相关性;CVR(转化率) 衡量“点了之后买不买”,反映商品吸引力与价格匹配度。AUC 则用来评估排序模型的全链路能力——它回答的问题是“随机挑一个正样本和一个负样本,模型能正确把正样本排前面的概率是多少”,是技术团队的日常体检指标。
离线评估是发布前的考试:用历史数据切出训练集和测试集,在测试集上算 AUC、NDCG,判断模型有没有进步。但离线效果好不代表线上一定好——因为离线数据的分布都是历史行为,而线上的流量随时在变。
这就有了在线实验:把用户随机分成实验组和对照组,实验组用新模型、对照组用旧模型,跑一段时间后对比两组的关键指标是否有显著提升。这叫 A/B 测试。王姐带徒弟就是这么干的:同一批顾客,徒弟用新方法服务一半,她亲自服务另一半,月底一对账,高下立判。在线实验是搜索系统进化的唯一裁判,任何离线指标都替代不了。
工程架构
王姐的本事再大,也只能同时服务几位顾客。电商平台要同时应对几亿用户的搜索请求,必须有一套精密的工程架构把王姐的本事规模化。
离线链路是“厚积薄发”的部分。每天凌晨,系统用前一天的全量日志训练排序模型、更新召回索引、计算商品统计特征。就像王姐每天下班后会翻看当天的服务记录,记下哪个老顾客买了新品类、哪批新品反馈好,为第二天的工作做准备。离线计算是大规模、非实时的,但它决定了模型的上限。
实时链路负责“临场应变”。用户刚点击了一个商品,这个行为要在秒级内反馈到推荐结果中。王姐看到你拿起又放下一件商品,马上换一件推荐——这个反应的时效性是离线链路给不了的。实时链路由消息队列和流式计算构成,把用户行为实时拼装成特征,喂给在线模型。
模型服务是系统中的“王姐本人”。它接收用户当前的请求特征,调用排序模型打分,在几十毫秒内返回结果。为了让打分足够快,模型往往要做量化压缩、特征缓存等优化。这就像王姐在脑中有一套“快问快答”的反射机制——不用每次重新思考,大多数判断靠直觉秒回。
最后的性能优化则贯穿各层。一个搜索请求的预算通常在 200 毫秒以内,召回、粗排、精排、重排都要在这 200 毫秒里跑完。工程师们用索引加速召回、用级联模型逐层减负、用缓存降低重复计算,一切只为了一个目标:让用户感觉“系统是秒回的”。王姐的快,靠的是十年功力的内化;系统的快,靠的是架构设计的精妙。
AI 应用场景
电商大促的搜索流量调控
阶段:排序模型 + 重排策略
解决的问题:大促期间用户搜索“手机”,既要保证头部爆款有曝光,又要让中小商家有活路,还要兼顾平台整体 GMV 目标。传统做法是人工调配展位,耗时且不精准。
具体案例:某平台在双 11 大促期间,对搜索排序模型增加了“价格力”和“新品权重”两个特征,并在重排阶段加入品类打散策略。结果 CTR 提升 3.2%,新品曝光量提升 18%,平台 GMV 整体增长 5.6%。
新用户冷启动的搜索引导
阶段:召回策略 + 冷启动
解决的问题:新注册用户没有历史行为,搜索“男装”时如果用纯个性化召回,结果与热门榜单无异,用户觉得“不够懂我”。AI 通过试探性推荐 + 实时反馈收集,逐步构建用户画像。
具体案例:某电商 App 对新用户采用“热门 + 类目偏好猜测”的混合召回,前 3 次搜索引入探索权重,点击后立即更新用户向量。数据显示,冷启动用户 7 日留存率提升 11%。
Python 演示
import mathimport numpy as npfrom collections import Counter # ========== 商品库 ==========products = [ {"id": 1, "title": "无线蓝牙耳机", "brand": "声阔", "price": 299, "sales": 5000}, {"id": 2, "title": "头戴式降噪耳机", "brand": "索尼", "price": 1999, "sales": 1200}, {"id": 3, "title": "陶瓷炖盅砂锅", "brand": "苏泊尔", "price": 159, "sales": 3200}, {"id": 4, "title": "便携蓝牙音箱", "brand": "JBL", "price": 399, "sales": 2100}, {"id": 5, "title": "电竞游戏耳机", "brand": "罗技", "price": 349, "sales": 980}, {"id": 6, "title": "真丝连衣裙", "brand": "优衣库", "price": 459, "sales": 860},] def tokenize(text): return [c for c in text if c.isalnum()] doc_terms = [tokenize(p["title"]) for p in products] # ========== BM25 召回 ==========def bm25(query, k1=1.5, b=0.75): N = len(products) avgdl = sum(len(d) for d in doc_terms) / N scores = [] for i, doc in enumerate(doc_terms): doc_len = len(doc) tf_map = Counter(doc) score = 0.0 for q in tokenize(query): if q in tf_map: tf = tf_map[q] df = sum(1 for d in doc_terms if q in d) idf = math.log((N - df + 0.5) / (df + 0.5) + 1) score += idf * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * doc_len / avgdl)) scores.append((score, products[i])) scores.sort(key=lambda x: x[0], reverse=True) return scores # ========== 简单向量召回 ==========embeds = { "耳机": np.array([1, 0, 0]), "音箱": np.array([0.8, 0.6, 0]), "炖": np.array([0, 1, 0]), "连衣裙": np.array([0, 0, 1]),} def vector_recall(query, topk=3): q_vec = np.zeros(3) for ch in query: if ch in embeds: q_vec += embeds[ch] scored = [] for i, p in enumerate(products): title_vec = np.zeros(3) for ch in p["title"]: if ch in embeds: title_vec += embeds[ch] sim = np.dot(q_vec, title_vec) / (np.linalg.norm(q_vec) + 1e-8) scored.append((sim, p)) scored.sort(key=lambda x: x[0], reverse=True) return scored[:topk] # ========== 逻辑回归排序 ==========class LogisticRanker: def __init__(self): self.w = None def fit(self, X, y): X = np.c_[np.ones(len(X)), X] self.w = np.zeros(X.shape[1]) for _ in range(100): z = X @ self.w p = 1 / (1 + np.exp(-z)) grad = X.T @ (p - y) / len(y) self.w -= 0.5 * grad def predict_proba(self, X): X = np.c_[np.ones(len(X)), X] z = X @ self.w return 1 / (1 + np.exp(-z)) def feat(p): return np.array([p["price"] / 2000, p["sales"] / 5000, 1.0 if p["brand"] == "索尼" else 0.0]) # ========== 主流程 ==========def search(query): rec = bm25(query) rec = [p for s, p in rec if s > 0][:3] if len(rec) < 3: seen = set(id(p) for p in rec) for _, p in vector_recall(query, topk=5): if id(p) not in seen: rec.append(p) if len(rec) >= 3: break X = np.array([feat(p) for p in rec]) ranker = LogisticRanker() y = np.array([1, 0, 1])[:len(rec)] ranker.fit(X, y) scored = sorted(zip(ranker.predict_proba(X), rec), key=lambda x: -x[0]) return [p["title"] for _, p in scored] if __name__ == "__main__": result = search("耳机") for r in result: print(r)
doc_terms = [tokenize(p["title"]) for p in products]将商品标题分词,构建文档词表,是 BM25 计算的基础。score += idf * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * doc_len / avgdl))BM25 的核心公式:词频越高、文档越长、词越稀有,得分越高。q_vec += embeds[ch]把查询词中每个字的向量相加,得到查询的整体语义向量。sim = np.dot(q_vec, title_vec) / (np.linalg.norm(q_vec) + 1e-8)用余弦相似度衡量查询与商品的语义距离。X = np.c_[np.ones(len(X)), X]在特征矩阵前加一列全 1,对应逻辑回归的偏置项。grad = X.T @ (p - y) / len(y)梯度下降更新权重:预测与真实值的差异越大,权重调整幅度越大。
常见误区
误区召回阶段应该尽量多捞商品,把所有可能的候选都放到排序阶段,这样排序模型才有足够的选择空间。
正解召回数量越多,排序阶段的计算压力和延迟越大。电商搜索对响应时间极其敏感,200 毫秒内必须返回结果。多路召回的正确做法是各路设置名额上限,在覆盖率和响应延迟之间找平衡。像王姐不会把整个超市搬到你面前,而是精选 20 件让你挑。
为何常见:初学者容易线性思维地认为“信息越多决策越优”,忽略了系统延迟的硬约束。
误区向量召回能理解语义,效果比 BM25 这类词法召回好,未来只需要向量召回就够了。
正解向量召回在语义泛化上确实更强,但它在精确匹配上反而不如词法召回。用户搜“iPhone 15 手机壳”时,词法召回能精确定位品牌和型号,向量召回反而可能召回一堆“手机配件”的泛泛结果。工业界几乎都是词法召回和向量召回并存,各自负责不同的召回通道。
为何常见:看到向量召回的 SOTA 效果后容易高估其能力,忽略了它对精确属性的匹配弱点。
误区深度模型效果全面碾压浅层模型,所以排序模型应该无脑上 DNN,网络越深越好。
正解电商搜索的特征以高维稀疏 ID 为主,GBDT 对这类特征非常有效,深度模型虽强但需要大量数据和调参成本。实际工业界常采用 GBDT + DNN 的并行结构,各自处理不同类型的特征。模型选型要结合数据规模、特征类型和推理延迟,不能只看论文上的 SOTA。
为何常见:深度学习在图像、语音上的巨大成功,让人们误以为它在所有场景都无条件占优。
面试题
Q1. 在电商搜索系统中,召回和排序的核心目标分别是?
- A.召回追求精确,排序追求覆盖
- B.召回追求覆盖,排序追求精确← 正确答案
- C.两者都追求精确
- D.两者都追求覆盖
答案:B。召回的目标是“宁可错捞、不可错过”,优先保证覆盖率;排序的目标是把最合适的排在最前,追求精度。二者构成漏斗的两端,分工不同,选择 B 正确。
Q2. BM25 属于哪一类召回策略?
- A.向量召回
- B.协同召回
- C.词法召回← 正确答案
- D.图召回
答案:C。BM25 是经典的词法匹配算法,基于关键词在文档中出现的词频和稀缺性打分,属于词法召回。向量召回用的是 embedding 语义向量,协同召回用的是用户行为矩阵。
Q3. 关于多路召回融合,下列说法正确的有?
- A.各路召回结果需要去重← 正确答案
- B.各路召回名额应均衡分配
- C.需要设置权重控制各路占比← 正确答案
- D.融合后无需再做粗排
答案:AC。多路召回融合时,首先要做候选去重,避免同一商品被多路重复召回;其次要按策略分配各路权重和名额,保证多样性和相关性。融合后通常仍需要粗排/精排漏斗过滤,B 和 D 错误。
Q4. 逻辑回归输出值经过什么函数映射成 0~1 的概率?
- A.ReLU
- B.Sigmoid← 正确答案
- C.Softmax
- D.Tanh
答案:B。逻辑回归用 Sigmoid 函数 σ(z)=1/(1+e⁻ᶻ) 把线性加权和 z 映射到 0~1。ReLU 常用于深层网络的激活层,Softmax 用于多分类,Tanh 映射到 -1~1。
Q5. 新商品上架十几天都没有曝光,最可能的原因是?
- A.商品标题写得太短
- B.没有行为数据导致排序模型打分低← 正确答案
- C.商品类目设置错误
- D.商家店铺评分低
答案:B。新品没有点击和成交数据,排序模型给出的预测分接近先验值,排在后面导致没曝光,形成恶性循环。解决方案是属性迁移或策略干预,而非单纯优化标题或类目。
Q6. 搜索排序中常用的技术指标包括?
- A.CTR← 正确答案
- B.AUC← 正确答案
- C.GMV
- D.客单价
答案:AB。CTR 衡量点击率,AUC 评估排序模型区分正负样本的能力,都是技术团队的常用指标。GMV 和客单价是业务指标,受价格、供给等非模型因素影响,故不选。
Q7. 特征工程的核心意义是?
- A.减少训练数据量
- B.特征决定模型性能上限← 正确答案
- C.替代排序模型
- D.缩短离线训练时间
答案:B。特征工程决定模型能感知的信息边界,特征越丰富,模型上限越高。训练数据量、训练时间属于工程优化范畴,特征不能替代模型本身。
Q8. 关于用户冷启动,最有效的初始策略是?
- A.不做推荐,等用户主动浏览
- B.完全随机推荐商品
- C.用热门商品试探并收集反馈← 正确答案
- D.只推荐高客单价商品
答案:C。冷启动的核心是快速收集用户偏好信号。推荐热门商品能保证基础体验,点击行为则为画像构建提供数据。纯随机推荐体验差,只推高价容易流失用户。
Q9. 关于 GBDT 与深度排序模型,下列说法正确的有?
- A.GBDT 擅长高维稀疏特征
- B.深度模型擅长自动特征交互← 正确答案
- C.GBDT 对表格型稠密特征效果好← 正确答案
- D.深度模型无法处理 ID 类特征
答案:BC。深度模型通过 embedding 把高维稀疏 ID 映射成稠密向量,并自动学习特征交互;GBDT 对稠密的统计型特征效果好。GBDT 不擅长高维稀疏特征,深度模型恰恰擅长 ID 特征,A 和 D 表述相反,故不选。
Q10. 搜索请求的整体延迟预算通常控制在什么量级?
- A.10 秒级别
- B.200 毫秒级别← 正确答案
- C.20 毫秒级别
- D.5 秒级别
答案:B。电商搜索的延迟预算一般在 200 毫秒以内,超过这个阈值用户会明显感到卡顿。工程上通过索引加速、级联漏斗、缓存等手段压缩各环节耗时。