「Embedding」这个词在论文里被翻译成嵌入、向量化、表示学习,初见容易发懵,但它就是全书的原子概念:把一段非结构化内容压成一串固定长度的浮点数。本节是全书概念的起点,先把词汇表立起来,再亲手算一次最小规模的相似检索,最后划清它与关系型数据库的分野——后面六章的每一个技术决策,都建立在这些定义之上。
向量与维度。 向量就是一串有序的数,数的个数叫维度。一个 768 维的文本向量就是 768 个浮点数排成的序列,在数学上可以被看作高维空间里的一个点。维度本身不携带语义单位——第 37 维并不对应"某个具体概念"——语义分布在整条向量的方向和长度里,这是它和"一个字段存一个属性"最本质的差别。
嵌入。 嵌入是把原始内容映射为向量的过程和结果的统称。映射由嵌入模型完成:文本模型把句子编码成向量,图像模型把像素编码成向量,训练目标通常被概括成一句话——语义相近的内容,向量在空间中也彼此靠近。这句话是整个技术栈的公理:如果模型认为两条差评不相似,再好的数据库也查不出它们的相似。
近邻搜索与 TopK。 给定查询向量和一个向量集合,按距离从小到大排序,取前 K 个,就是 K 近邻搜索,返回的结果叫 TopK。数据库语境下它对应这样的查询:"给我返回最相似的十条"。注意它没有"WHERE 等于某个值"的精确语义,返回的是排序后的近似最优解——"近似"二字是第三章的主角。
召回率。 衡量近似检索质量的核心指标:近似算法返回的 TopK 里,有多少条真的属于精确算法会给出的 TopK。若精确答案有十条、近似结果猜对了九条,召回率就是九成。召回率和延迟、内存构成一条铁三角,全书都在这条三角里挪动支点。
索引与过滤。 索引是为加速近邻搜索而构建的辅助数据结构,代价是额外的内存和构建时间;过滤指在检索时叠加标量条件,比如"只在某个租户的数据里找""只要上架状态的商品"。带过滤的向量检索是第四章和第五章的重要话题。
抽象定义说再多,不如亲手排一次序。下面这段代码只依赖 numpy,构造了六个二维"文档向量"和一个查询向量,分别用欧氏距离和余弦相似度找出前三近邻:
import numpy as np # 六个二维点,想象成六篇文档的"超简化嵌入" docs = np.array([ [1.0, 1.0], # d0 [1.5, 0.8], # d1,与 d0 方向接近、距离很近 [3.0, 4.0], # d2,与查询同方向但更远 [4.0, 1.0], # d3 [2.0, 2.2], # d4 [0.5, 3.0], # d5 ]) query = np.array([2.8, 2.6]) # 口径一:欧氏距离,衡量绝对位置差 l2 = np.linalg.norm(docs - query, axis=1) # 口径二:余弦相似度,衡量方向是否一致 cos = (docs @ query) / (np.linalg.norm(docs, axis=1) * np.linalg.norm(query)) top_l2 = np.argsort(l2)[:3] # 距离最小 top_cos = np.argsort(-cos)[:3] # 相似度最大 print("按欧氏距离 Top3 :", top_l2, np.round(l2[top_l2], 3)) print("按余弦相似度 Top3:", top_cos, np.round(cos[top_cos], 3))
运行结果值得盯着看:欧氏距离口径返回的是 d4、d2、d1,余弦口径返回的是 d2、d4、d0。同一份数据、同一个查询,仅仅换了距离定义,排名就变了——d0 位置离查询最远,但方向和查询几乎一致,于是在余弦口径下挤进了前三。这个十几行的小实验浓缩了向量检索的第一课:"相似"没有唯一答案,它取决于你选的度量口径。第二章会系统地讲每种口径的适用场景;这里只需记住,任何向量数据库返回结果的顺序,都隐含了你当初建集合时选定的度量方式。
用一张表把两种存储设施在关键维度上摆在一起:
| 维度 | 关系型数据库 | 向量数据库 |
|---|---|---|
| 一等公民 | 行与列,字段有明确语义 | 高维坐标点,语义分布在整条向量 |
| 查询语义 | 等值与范围匹配,结果确定 | 邻域排序,结果是近似最优 |
| 索引目标 | 加速等值查找与范围扫描 | 加速距离比较与剪枝 |
| 结果评价 | 对或错,无中间态 | 召回率,允许可控的漏召 |
| 典型延迟来源 | 磁盘 IO 与锁竞争 | 内存带宽与距离计算量 |
| 数据更新 | 原地更新,事务保证 | 常用标记删除加后台整理 |
这张表不是要说谁取代谁,恰恰相反:生产系统里它们几乎总是并存的。业务的主数据、订单、库存放在关系库里,向量和它的过滤字段放在向量库里,用业务主键互相勾连。第六章讲选型时会反复用到这个分工原则——向量库接管的是"找相似"这一步,而不是整个业务数据面。
还有一点值得提醒:向量数据库的"近似"不是缺陷,而是刻意的设计取舍。精确的近邻搜索在三维四维里毫无压力,可维度一高,距离计算的代价会以肉眼可见的速度失控,3.1 节会用实验让你亲眼看到这堵墙。理解了这堵墙,才能理解为什么整本书要花那么多篇幅在索引结构上。
问:有了 Elasticsearch 这类搜索引擎,为什么还需要向量数据库? 搜索引擎的强项是倒排索引——按词项精确命中再按相关性打分,它理解"词的重合",不直接理解"语义的接近"。两个说法完全不同但意思一致的句子,词面几乎不重叠,倒排检索会失手,向量检索能命中。反方向的例子也成立:代码搜索、日志检索这类强词面场景,倒排依然是更好的选择。生产系统里两者正在融合成混合检索,第六章会看到各家产品的实现差异。
问:维度是不是越高越好? 不是。维度决定表达能力的上限,但也决定成本的下限:内存、带宽、距离计算时间全部随维度线性增长。更微妙的是,维度翻倍并不保证语义区分度翻倍——嵌入模型的训练质量对区分度的影响远大于维度本身。选型的正确顺序是先用低维模型跑通全链路量出基线,再评估升级换来的召回提升是否值回成本,而不是从维度表上挑最大的。
问:TopK 的 K 应该怎么定? 由下游消费方式倒推。直接展示给用户的列表,K 就是页面容量加少量冗余;喂给重排模型的,K 是精排容量乘以损耗系数(5.2 的超量取回);喂给大模型的检索增强,K 受上下文窗口预算约束,还要给每段内容留字符余地。K 越大召回越难保证(同样的索引参数下,TopK 为一百的召回率低于 TopK 为十),调参时 K 变了参数必须重扫——这条纪律能省掉大量"参数失灵"的冤案。
下一节把镜头拉远,看看这些概念是怎么一步步从论文走进生产系统的——演化路径会解释今天每一项设计为什么长成这样。