Embedding 检索实践
Embedding 检索把输入映射为向量,然后查找附近的向量。公式很简单,生产环境中的契约并不简单。
向量也有身份
维度不能单独定义兼容性。两个来自不同模型的 512 维 Embedding 通常位于不同向量空间,彼此比较没有意义。
一份可用的向量契约应包括:
- 模型及准确版本;
- 预处理步骤;
- 输出维度;
- 归一化策略;
- 相似度函数;
- 向量代表的实体;
- 迁移或重建索引版本。
这些字段应像数据库 Schema 一样管理。静默更新模型却不重建索引,本质上是数据兼容性错误。
检索是一条流水线
text
Query
│
├─ 使用匹配的模型编码
│
├─ 应用租户、站点、时间和实体过滤条件
│
├─ 检索 Top K 候选
│
├─ 使用更丰富的信号重新排序
│
└─ 分组、分页并解释结果执行顺序会改变语义。先取全局 Top K 再分组,并不等价于每组分别取 Top K。检索前严格过滤可能提高精度和速度;当元数据不完整时,同一个过滤条件也可能严重破坏 Recall。
余弦相似度
对于非零向量 $x$ 和 $y$:
$$ \operatorname{cosine}(x,y)=\frac{x\cdot y}{\lVert x\rVert\lVert y\rVert} $$
所有向量归一化为单位长度时,余弦相似度等价于点积。但索引向量和查询向量仍然必须使用相同的归一化假设。
阈值不能直接跨模型或数据集复用。应该根据带标注的真实样本校准,而不是凭直觉判断“0.8 应该足够相似”。
候选检索与最终排序
近似最近邻索引用准确率换取速度。它的目标是为最终排序生成足够好的候选集合,而不一定直接提供最终产品顺序。
Rerank 可以组合:
- 向量相似度;
- 关键词匹配;
- 新鲜度;
- 实体置信度;
- 业务规则;
- Cross-Encoder 或多模态模型。
日志中必须区分原始检索分数和最终排序分数,否则排序回归很容易被误判为索引问题。
按失败阶段评估
使用带标注的 Query 集合,并记录具体失败阶段:
| 失败类型 | 需要回答的问题 |
|---|---|
| 表示 | 相关内容在这个向量空间中是否足够接近? |
| 过滤 | 正确内容是否在检索前被排除? |
| 候选 Recall | Top K 中是否包含相关内容? |
| 排序 | 相关候选是否排在足够靠前的位置? |
| 展示 | 正确结果是否被分组或分页隐藏? |
整体 Precision 有价值,但阶段标签才能真正指出应该修改什么。
生产检查清单
- 为每个向量保存模型和预处理版本。
- 显式拒绝维度或向量空间不匹配。
- 定义 Top K 是全局还是按组计算。
- 记录过滤条件、候选数量和排序阶段。
- 维护稳定的评估集,包含困难负样本。
- 向量契约变化时主动重建索引。
- 在真实集合规模下同时比较延迟和质量。
当每个阶段都有明确契约和独立证据时,Embedding 检索就不再是无法解释的黑盒。