Embedding、向量与相似度检索

# Embedding、向量与相似度检索

本篇目标

理解 Embedding 怎样把内容映射为向量、余弦相似度怎样比较语义,以及向量检索为什么不能单独保证事实、权限和答案质量。

理解 Embedding计算余弦相似度建立向量检索认识检索边界

# 先记住一句话

Embedding 把文本等内容转换成一组表示语义特征的数字;向量越接近,内容通常越相关,但相关不等于正确,也不等于有权访问。

# Embedding 是什么

Embedding 可以理解为内容在一个高维语义空间中的坐标。输入一段文本,Embedding 模型返回固定维度的数字数组:

“怎样避免数据库长事务”
          ↓ Embedding 模型
[0.12, -0.47, 0.83, ...]
1
2
3

向量中的单个数字通常没有直接业务含义。真正有用的是多个向量之间的距离或方向关系:语义相近的内容通常距离更近。

Embedding 不是摘要、加密或压缩文件。向量不能代替原文,索引中仍要保存或关联原文、来源、权限和更新时间。

# 生成模型和 Embedding 模型有什么区别

类型 输入 输出 常见用途
生成模型 Prompt 与上下文 新文本、结构化结果 问答、摘要、抽取、推理
Embedding 模型 文本、图片等内容 固定维度向量 检索、聚类、去重、推荐

生成模型内部也会使用向量表示 Token,但工程中所说的 Embedding API 通常指用于比较和检索的输出向量。

# 余弦相似度是什么

余弦相似度比较两个向量方向是否接近:

cosine(a, b) = a · b / (|a| × |b|)
1

下面是不依赖第三方库的完整计算示例:

# 文件位置:examples/cosine_similarity.py
from math import sqrt


def cosine_similarity(left: list[float], right: list[float]) -> float:
    if len(left) != len(right):
        raise ValueError("两个向量的维度必须一致")
    if not left:
        raise ValueError("向量不能为空")

    dot_product = sum(a * b for a, b in zip(left, right))
    left_length = sqrt(sum(value * value for value in left))
    right_length = sqrt(sum(value * value for value in right))
    if left_length == 0 or right_length == 0:
        raise ValueError("零向量无法计算余弦相似度")

    return dot_product / (left_length * right_length)


if __name__ == "__main__":
    query = [0.8, 0.1, 0.3]
    document = [0.7, 0.2, 0.4]
    print(cosine_similarity(query, document))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

这个示例只演示数学计算,数组是人为构造的,不代表真实模型向量。生产环境通常由向量数据库或数值库批量计算,并建立近似最近邻索引加速搜索。

# 一次向量检索怎样工作

离线阶段
文档 → 解析与分片 → Embedding → 向量 + 原文 + 元数据 → 索引

在线阶段
问题 → Embedding → 权限与元数据过滤 → 相似度搜索 → 候选片段
1
2
3
4
5

文档与查询必须使用兼容的 Embedding 模型和相同维度。更换模型后,旧向量通常需要重新生成,不能把不同向量空间中的结果直接比较。

# 为什么还需要关键词检索

向量检索擅长语义相近表达,例如 “怎样结束后台任务” 可以找到 “Goroutine 优雅退出”。关键词检索则更擅长:

  • 错误码和日志原文;
  • 类名、函数名和版本号;
  • 产品编号和专有名词;
  • 必须完全匹配的短语。

真实系统常使用混合检索:关键词找精确命中,向量找语义候选,再使用 Reranker(重排模型)对候选进行更精细排序。

# 相似度阈值怎样设置

不存在跨模型、跨数据集通用的阈值。向量模型、距离算法、文档类型和查询难度都会影响分数分布。

正确做法是准备包含相关与不相关样本的检索评测集,观察不同阈值下的召回率和误召回率。阈值过高会漏掉正确资料,过低会把大量噪声交给生成模型。

# 权限为什么必须在检索阶段处理

未授权内容只要进入候选结果或模型上下文,就已经产生泄漏风险。向量库中的每条记录应携带用户、组织、知识库等元数据,查询时先根据服务端认证结果过滤。

不能先检索所有人的资料,再用 Prompt 告诉模型 “不要泄露” 。模型不是权限边界。

# Embedding 在 RAG 中处于哪一层

Embedding 只负责把查询和文档映射到可比较空间。完整 RAG 还包括文档解析、分片、权限过滤、召回、重排、上下文组织、生成、引用和评测。

如果正确资料没有进入候选结果,继续修改生成 Prompt 通常解决不了根因;应先检查解析、分片、向量模型和检索策略。

# 高频面试题与回答

1. Embedding 是什么?参考答案

Embedding 是把文本等内容映射成固定维度向量的过程。向量中的单个数字通常没有直接业务含义,主要用于比较内容在语义空间中的距离,从而完成检索、聚类和去重。

2. 向量相似是否代表事实一致?参考答案

不代表。两段内容可能讨论同一主题却给出相反结论,向量仍然很接近。检索结果还要经过来源、时间、权限和内容校验,生成答案时也要保留引用。

3. 为什么换 Embedding 模型后通常要重建索引?参考答案

不同模型生成的维度和语义空间可能不同,旧文档向量与新查询向量不能可靠比较。因此应给索引记录模型版本,并在迁移时重新生成文档向量和回归检索效果。

4. 向量检索和关键词检索怎样选择?参考答案

语义改写和自然语言问题适合向量检索,错误码、函数名和编号等精确内容适合关键词检索。多数知识库会结合两者,再用重排和真实问题评测确定权重。

# 接下来学什么

下一篇学习 模型选择:质量、延迟、成本与上下文,理解不同任务为什么不应该无条件使用同一个最大模型。

# 参考资料