本文是 搜推算法笔记 第 1 篇,共 7 篇。索引见 搜推算法 · 知识索引。
下一篇:Query 理解与多路召回
学习搜推算法时,常见误区是过早陷入 BM25 公式或某个模型细节,而忽略更根本的问题:整个系统到底在优化什么? 用户说「搜不到想要的」,工程师聊倒排索引和分词——中间缺了一层:从输入到最终列表,每一层在解决什么问题、失败时长什么样。
本文梳理搜索/推荐共通的工业界框架。读完应能画出标准漏斗、解释每层优化目标、判断该用哪类算法。
1. 搜索与推荐的本质区别
一句话定义
| 系统 | 定义 |
|---|---|
| 搜索 | 用户给出明确意图(Query),系统返回与意图匹配的结果,并按相关/价值排序 |
| 推荐 | 用户未必给出 Query,系统根据用户、物品、上下文,预测「接下来可能感兴趣的内容」 |
两者底层都在做一件事:在海量候选里,找出并排出用户此刻最可能需要的一小撮。 差别在于意图从哪来——搜索来自 Query,推荐来自画像/行为/场景。
对比表
| 维度 | 搜索 | 推荐 |
|---|---|---|
| 输入 | Query(可能还有筛选、排序偏好) | User / Context / Item(常无 Query) |
| 成功标准 | 「找得准」:相关、可解释 | 「猜得准」:兴趣匹配、惊喜、停留 |
| 冷启动 | 新 Query 可用文本匹配 | 新用户/新物品更难(缺行为) |
| 典型算法 | 倒排+BM25、Query 理解、向量检索、LTR | CF、双塔、序列模型、多目标学习 |
| 失败形态 | 空结果、不相关、排序差 | 同质化、马太效应、不感兴趣 |
两者如何融合
真实产品很少「纯搜索」或「纯推荐」:
1 | ① 搜索排序:有 Query → 召回 → LTR 精排 |
模式 ② 是常见组合——主链路搜索无结果时,用语义召回和热门补齐,目标从「零结果」变为「零结果率下降且替代结果可接受」。
学习路径建议: 先把「有 Query 的排序」学透(倒排、向量、LTR),再学「无 Query 的推荐」(CF、双塔)。
2. 工业界标准漏斗
为什么必须分层?
假设候选库 (N = 10^7)(千万级),精排模型对每个候选要算几十维特征 + 树模型/神经网络:
- 若对全库精排:延迟与算力不可接受
- 解决办法:先廉价地缩小集合,再昂贵地精细打分
这就是漏斗(Cascade)思想——工业界搜推系统的基本架构。
标准四层
1 | ┌─────────────────────────────────────────────┐ |
每层优化目标与失败表现
| 层 | 核心问题 | 优化什么 | 典型技术 | 失败时用户感知 |
|---|---|---|---|---|
| 召回 | 好东西进池了吗? | Recall@K、覆盖、延迟 | 倒排、向量、CF、热门、多路融合 | 空结果、永远看不到想要的 |
| 粗排 | 能便宜丢掉垃圾吗? | 速度、低误杀 | 逻辑回归、浅层双塔、简单 GBDT | 好商品被砍掉 / 或粗排太慢 |
| 精排 | 顺序对吗? | NDCG、CTR、CVR | LambdaMART、深度学习排序 | 有好货但排很后 |
| 机制 | 体验与约束满足吗? | 多样性、合规、公平 | 规则、MMR、打散窗口 | 同店刷屏、违禁、审美疲劳 |
核心原则
召回决定上限,精排决定排序质量,机制决定体验底线。
候选池里没有的东西,精排再强也排不出来。
排查「库里有却搜不到」时,应优先检查 Query 理解层和召回层,而非直接归因于搜索引擎或精排模型。
粗排 vs 精排:什么时候需要粗排?
| 维度 | 粗排(Pre-rank) | 精排(Rank) |
|---|---|---|
| 输入规模 | 千~万级 | 百~千级 |
| 模型复杂度 | 浅层双塔、LR、简单 GBDT | LambdaMART、深度排序 |
| 特征数 | 10~30 维,可缓存 | 50~200 维,实时计算 |
| 延迟预算 | 5~20ms | 20~80ms |
| 优化目标 | 快速砍掉明显不相关 | 相对顺序最优 |
| 典型失败 | 误杀好商品(Recall 损失) | 顺序不对(NDCG 损失) |
召回后候选 < 500 时,粗排常可省略;候选上万且精排特征很重时,粗排能显著保护 P99。
漏斗的 Recall 损失(Cascade 效应)
设每层保留率分别为 (p_1, p_2, p_3)(召回→粗排→精排),则最终进入曝光的相关物品比例约为:
[
P(\text{相关且曝光}) \approx p_1 \times p_2 \times p_3 \times P(\text{相关}\mid\text{进精排池})
]
每层误杀都会乘性放大。 若召回 Recall@1000 = 0.95,粗排误杀 10%,精排池只有 500 个位置——整体 Recall 上限 ≈ 0.95 × 0.9 = 0.855。
工程含义:
- 召回 Recall 从 0.90 → 0.95,收益往往大于精排 NDCG 从 0.85 → 0.90
- 粗排阈值不宜过严——宁可多送一些进精排,让 LTR 压噪
- 监控每层「相关物品流失率」,而不只看最终 CTR
机制层补充
机制层常被低估,但在产品化阶段至关重要:
| 机制 | 作用 | 典型算法 |
|---|---|---|
| 过滤 | 下架、无库存、违禁、黑名单 | 规则引擎 |
| 打散 | 同店/同品牌不连续出现 | 滑动窗口 |
| 多样性 | 避免结果同质化 | MMR、DPP |
| 强插 | 运营位、广告、新品曝光 | 固定位置插入 |
| 混排 | 自然结果 + 广告 | 拍卖/加权 |
3. 相关性与多目标
排序不是只优化「相关」
用户点不点、买不买,受多个因素影响:
| 维度 | 含义 | 正例 | 负例 |
|---|---|---|---|
| 相关性 | 与意图匹配 | 搜「牛奶」出纯牛奶 | 出大量牛奶糖、奶粉(可能偏) |
| 质量 | 物品本身靠谱 | 好评、完整信息 | 假货、缺图、差评 |
| 时效 | 是否过时 | 当季、活动中 | 过季、下架边缘 |
| 个性化 | 是否符合偏好 | 常买母婴 → 偏母婴品牌 | 完全忽略历史 |
| 效率 | 商业目标 | CTR/CVR/GMV | 只相关但不转化 |
| 生态 | 平台长期健康 | 新商家曝光 | 头部垄断 |
多目标怎么落地?
- 单模型多特征:把销量、价格、相关分都当特征,用一个 LTR 学综合序
- 分阶段:召回偏相关,精排偏转化,机制保生态
- 多目标模型:同时预测 CTR、CVR,再融合打分(ESMM、MMOE 等,进阶)
初学先掌握 1 和 2。
4. 匹配范式演变与算法选型
| 时代 | 范式 | 代表算法 | 优点 | 短板 | 典型场景 |
|---|---|---|---|---|---|
| 字面匹配 | 倒排 + TF-IDF / BM25 | Lucene、ES | 快、可解释、专名强 | 同义词、语义描述弱 | 型号精确搜、SKU |
| 语义匹配 | Embedding + ANN | BGE、双塔、HNSW | 同义、近义、跨表述 | 精确型号有时不如词匹配 | 「纯奶」→「纯牛奶」 |
| 行为匹配 | CF / 矩阵分解 | ItemCF、Swing、ALS | 挖行为相似 | 冷启动、稀疏 | 猜你喜欢 |
| 学习排序 | 特征 + GBDT/LTR | LambdaMART、DIN | 融合多信号、直接优化排序 | 依赖特征工程 | 搜索精排、Feed |
TF-IDF vs BM25
| 维度 | TF-IDF | BM25 |
|---|---|---|
| 词频处理 | 线性增长 | 饱和函数(参数 k1) |
| 文档长度 | 简单归一化 | 基于 avgdl 的非线性惩罚(参数 b) |
| 稀有词 | IDF 加权 | 改进 IDF 公式,含平滑项 |
| 现状 | 教学/基线 | ES 默认、工业界主流 |
BM25 是 TF-IDF 的工程升级版——解决词频无限膨胀和长文档偏置。Elasticsearch 默认相似度即为 BM25。
BM25 公式拆解
完整形式(Lucene / ES 常用变体):
[
\mathrm{BM25}(q,d)=\sum_{t\in q}\underbrace{\log\frac{N-n_t+0.5}{n_t+0.5}}{\mathrm{IDF}(t)}
\cdot
\underbrace{\frac{f(t,d)\cdot(k_1+1)}{f(t,d)+k_1\cdot\bigl(1-b+b\cdot\frac{|d|}{\mathrm{avgdl}}\bigr)}}{\text{词频饱和 + 长度归一}}
]
| 符号 | 含义 | 直觉 |
|---|---|---|
| (N) | 文档总数 | 语料规模 |
| (n_t) | 含词 (t) 的文档数 | 词越稀有,IDF 越大 |
| (f(t,d)) | 词 (t) 在文档 (d) 中出现次数 | TF |
| (|d|) | 文档长度(词数) | 长文档惩罚 |
| (\mathrm{avgdl}) | 平均文档长度 | 归一化基准 |
| (k_1) | 词频饱和速度(默认 1.2) | (k_1) 大 → 词频加分更「线性」 |
| (b) | 长度惩罚强度(默认 0.75) | (b=1) 完全按长度归一;(b=0) 不看长度 |
三个设计动机:
- IDF:常见词(「的」「手机」)权重低,稀有词(品牌、型号)权重高
- 词频饱和:(f) 从 1→2 加分明显,10→11 几乎不加——避免「关键词堆砌」霸榜
- 长度归一:长标题天然词多,(b) 惩罚过长文档,避免长文占优
手算片段: 某词 (f=2),(|d|=100),(\mathrm{avgdl}=50),(k_1=1.2),(b=0.75):
[
\text{TF 分量} = \frac{2 \times 2.2}{2 + 1.2 \times (1 + 0.75 \times 2)} = \frac{4.4}{2 + 3.0} \approx 0.88
]
若该词 IDF = 3.0,则该词对 BM25 贡献约 (3.0 \times 0.88 = 2.64)。Query 多词命中则逐项求和。
协同过滤(CF)原理
行为矩阵 (R_{u,i})(点击/购买/评分),目标:从稀疏矩阵中补全「用户可能喜欢的物品」。
UserCF: 找与目标用户行为相似的用户集合 (N(u)),推荐他们喜欢而 (u) 未交互的物品:
[
\hat{r}{u,i}=\sum{v\in N(u)} \mathrm{sim}(u,v)\cdot r_{v,i}
]
ItemCF(电商更常见): 物品共现——「买了 A 的人也买了 B」:
[
\mathrm{sim}(i,j)=\frac{|U_i \cap U_j|}{\sqrt{|U_i|\cdot|U_j|}}
\qquad
\mathrm{score}(u,i)=\sum_{j\in I_u}\mathrm{sim}(i,j)
]
(U_i) 为与物品 (i) 有过行为的用户集合,(I_u) 为用户 (u) 交互过的物品。
| 维度 | UserCF | ItemCF |
|---|---|---|
| 相似度计算 | 用户 ↔ 用户 | 物品 ↔ 物品 |
| 在线缓存 | 难(用户向量实时变) | 易(物品相似表离线预计算) |
| 适用 | 用户少、物品多 | 物品相对稳定、行为丰富 |
| 搜索主路 | 很少 | 相关推荐、兜底 |
局限: 冷启动(新用户/新物品无行为)、稀疏矩阵、马太效应(热门物品相似度虚高)。常与内容/向量召回互补。
MMR 多样性(机制层算法)
Maximal Marginal Relevance:在相关性与多样性之间折中,贪心选文档:
[
\mathrm{MMR}=\arg\max_{d\in R\setminus S}\Bigl[
\lambda\cdot \mathrm{Sim}1(d,q) - (1-\lambda)\cdot \max{s\in S}\mathrm{Sim}_2(d,s)
\Bigr]
]
- (\mathrm{Sim}_1):与 Query 的相关性(BM25 分或向量相似度)
- (\mathrm{Sim}_2):与已选结果的相似度(避免同店/同品牌刷屏)
- (\lambda \in [0,1]):越大越偏相关,越小越偏多样
典型用法:精排 Top50 之后、机制层打散之前,用 MMR 重排前几页。
搜索 vs 推荐:算法怎么选?
| 需求 | 搜索优先 | 推荐优先 |
|---|---|---|
| 有明确 Query | BM25 + 向量 + Query 理解 | — |
| 无 Query、有用户历史 | 热门兜底 | ItemCF / 双塔 / 序列模型 |
| 新用户/新物品 | 文本向量、类目热门 | 内容向量、热门、探索策略 |
| 要可解释 | BM25 分词命中、规则 | 「相似物品」解释 |
| 要转化 | LTR(转化 label) | 多目标模型(CTR + CVR) |
现代标配:
1 | 多路召回(字面 + 语义 + 热门 + 行为…) |
没有银弹。工业界赢在「组合 + 数据闭环 + 实验」,不是单一模型。
5. 在线系统与离线系统
| 离线(Offline) | 在线(Online) | |
|---|---|---|
| 触发 | 调度(小时/天) | 用户请求 |
| 典型工作 | 样本 ETL、特征生产、训练、评估、建索引、灌向量 | Query 理解、召回、打分、过滤、分页 |
| 约束 | 可慢、可重试、可批处理 | 延迟(如 P99 < 200ms)、可用性、降级 |
| 产物 | 模型文件、向量索引、统计特征表 | 有序列表 |
Train = Serve
1 | 离线训练时用的特征定义/公式 ≡ 在线预测时用的特征定义/公式 |
不一致会导致:离线指标很好,线上效果很差。
典型坑:离线用「次日汇总销量」,在线用「实时销量」;离线有「人工类目」,在线只有「模型预测类目」;离线特征含「是否被点击」(泄漏)。
降级思想
1 | 向量库超时 → 该路返回空,其它路继续 |
可用性 > 最优效果。 搜推系统首先是工程系统。
6. 数据闭环与归因
1 | 曝光 → 点击 / 转化 → 日志入库 |
| 事件 | 强度 | 用途 |
|---|---|---|
| 曝光 | 弱 | 构成候选、算位置、做负样本 |
| 点击 | 中 | 弱 label、分析漏斗 |
| 加购/下单 | 强 | 主 label(更贴近业务) |
位置偏差(排在前面更容易被点)详见 精排与评价指标。
7. 常见系统形态
| 形态 | 链路 | 主指标 |
|---|---|---|
| 电商搜索 | Query 理解 → 多路召回 → 精排 → 打散过滤 | CTR、GMV、无结果率 |
| 内容 Feed | 兴趣召回 → 粗排 → 精排 → 多样性 | 停留、完播、互动 |
| 搜索兜底 | 主链路零结果 → 语义召回 + 热门补齐 | 无结果率、兜底 CTR |
| 相关推荐 | 当前物品 → 相似物品召回 → 简单排序 | 点击率、关联 GMV |
8. 术语速查
| 术语 | 含义 |
|---|---|
| Query | 用户查询词 |
| Doc / Item | 文档或候选物品 |
| Recall | 召回(也指指标 Recall@K) |
| Ranking / LTR | 排序 / 学习排序 |
| Embedding | 向量化表示 |
| ANN | 近似最近邻检索 |
| CTR / CVR | 点击率 / 转化率 |
| NDCG | 排序质量离线指标 |
| AB Test | 对照实验 |
| Train=Serve | 训练与服务特征一致 |
下一步
- Query 理解 + 多路召回 → Query 理解与多路召回
- 向量语义召回 → 向量检索与 ANN
- 精排与评价 → 精排与评价指标


