Embedding、向量与相似度检索
# Embedding、向量与相似度检索
理解 Embedding 怎样把内容映射为向量、余弦相似度怎样比较语义,以及向量检索为什么不能单独保证事实、权限和答案质量。
# 先记住一句话
Embedding 把文本等内容转换成一组表示语义特征的数字;向量越接近,内容通常越相关,但相关不等于正确,也不等于有权访问。
# Embedding 是什么
Embedding 可以理解为内容在一个高维语义空间中的坐标。输入一段文本,Embedding 模型返回固定维度的数字数组:
“怎样避免数据库长事务”
↓ Embedding 模型
[0.12, -0.47, 0.83, ...]
2
3
向量中的单个数字通常没有直接业务含义。真正有用的是多个向量之间的距离或方向关系:语义相近的内容通常距离更近。
Embedding 不是摘要、加密或压缩文件。向量不能代替原文,索引中仍要保存或关联原文、来源、权限和更新时间。
# 生成模型和 Embedding 模型有什么区别
| 类型 | 输入 | 输出 | 常见用途 |
|---|---|---|---|
| 生成模型 | Prompt 与上下文 | 新文本、结构化结果 | 问答、摘要、抽取、推理 |
| Embedding 模型 | 文本、图片等内容 | 固定维度向量 | 检索、聚类、去重、推荐 |
生成模型内部也会使用向量表示 Token,但工程中所说的 Embedding API 通常指用于比较和检索的输出向量。
# 余弦相似度是什么
余弦相似度比较两个向量方向是否接近:
cosine(a, b) = a · b / (|a| × |b|)
下面是不依赖第三方库的完整计算示例:
# 文件位置: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))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
这个示例只演示数学计算,数组是人为构造的,不代表真实模型向量。生产环境通常由向量数据库或数值库批量计算,并建立近似最近邻索引加速搜索。
# 一次向量检索怎样工作
离线阶段
文档 → 解析与分片 → Embedding → 向量 + 原文 + 元数据 → 索引
在线阶段
问题 → Embedding → 权限与元数据过滤 → 相似度搜索 → 候选片段
2
3
4
5
文档与查询必须使用兼容的 Embedding 模型和相同维度。更换模型后,旧向量通常需要重新生成,不能把不同向量空间中的结果直接比较。
# 为什么还需要关键词检索
向量检索擅长语义相近表达,例如 “怎样结束后台任务” 可以找到 “Goroutine 优雅退出”。关键词检索则更擅长:
- 错误码和日志原文;
- 类名、函数名和版本号;
- 产品编号和专有名词;
- 必须完全匹配的短语。
真实系统常使用混合检索:关键词找精确命中,向量找语义候选,再使用 Reranker(重排模型)对候选进行更精细排序。
# 相似度阈值怎样设置
不存在跨模型、跨数据集通用的阈值。向量模型、距离算法、文档类型和查询难度都会影响分数分布。
正确做法是准备包含相关与不相关样本的检索评测集,观察不同阈值下的召回率和误召回率。阈值过高会漏掉正确资料,过低会把大量噪声交给生成模型。
# 权限为什么必须在检索阶段处理
未授权内容只要进入候选结果或模型上下文,就已经产生泄漏风险。向量库中的每条记录应携带用户、组织、知识库等元数据,查询时先根据服务端认证结果过滤。
不能先检索所有人的资料,再用 Prompt 告诉模型 “不要泄露” 。模型不是权限边界。
# Embedding 在 RAG 中处于哪一层
Embedding 只负责把查询和文档映射到可比较空间。完整 RAG 还包括文档解析、分片、权限过滤、召回、重排、上下文组织、生成、引用和评测。
如果正确资料没有进入候选结果,继续修改生成 Prompt 通常解决不了根因;应先检查解析、分片、向量模型和检索策略。
# 高频面试题与回答
1. Embedding 是什么?参考答案
Embedding 是把文本等内容映射成固定维度向量的过程。向量中的单个数字通常没有直接业务含义,主要用于比较内容在语义空间中的距离,从而完成检索、聚类和去重。
2. 向量相似是否代表事实一致?参考答案
不代表。两段内容可能讨论同一主题却给出相反结论,向量仍然很接近。检索结果还要经过来源、时间、权限和内容校验,生成答案时也要保留引用。
3. 为什么换 Embedding 模型后通常要重建索引?参考答案
不同模型生成的维度和语义空间可能不同,旧文档向量与新查询向量不能可靠比较。因此应给索引记录模型版本,并在迁移时重新生成文档向量和回归检索效果。
4. 向量检索和关键词检索怎样选择?参考答案
语义改写和自然语言问题适合向量检索,错误码、函数名和编号等精确内容适合关键词检索。多数知识库会结合两者,再用重排和真实问题评测确定权重。
# 接下来学什么
下一篇学习 模型选择:质量、延迟、成本与上下文,理解不同任务为什么不应该无条件使用同一个最大模型。