用 Milvus 构建向量检索实战
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
向量:让计算机理解语义
1. 什么是向量
别被向量这个词吓到,它其实很简单:向量就是一组有序的数字。
举个例子,如果我们想用数字来描述一个人:
张三 = [身高175cm, 体重70kg, 年龄25岁]
= [175, 70, 25]
这个 [175, 70, 25] 就是张三的"向量",它是一个 3 维向量(因为有 3 个数字)。
同样的 道理,我们也可以用一组数字来描述一段文字的"语义":
"今天天气真好" = [0.12, -0.34, 0.78, ..., 0.56] // 假设有 1024 个数字
"今天阳光明媚" = [0.11, -0.32, 0.80, ..., 0.55] // 数字很接近!
"明天股票大跌" = [-0.67, 0.89, -0.12, ..., -0.45] // 数字差很远
关键点来了:
语义相近的文字,转成向量后,这些数字也会很接近。
2. Embedding:把文字变成向量
那谁来负责把文字转成这一串数字呢?答案是 Embedding 模型(也叫"嵌入模型")。
你可以把 Embedding 模型理解成一个"翻译官":
- 输入:一段文字
- 输出:一组数字(向量)

作为工程师,你不需要关心模型内部怎么计算的,只需要知道:
- 调用 API 或者本地模型
- 传入文字,拿到向量
- 向量维度是固定的(比如 1024 维或 4096 维等)
3. 向量相似度搜索
有了向量,我们就可以用数学方法计算"两段文字的语义有多接近"。
这就是向量相似度搜索的核心思路:
- 建库阶段:把所有文档都转成向量,存起来
- 查询阶段:把用户问题也转成向量,找出最相似的文档向量

三种相似度度量方式
计算两个向量"有多接近",有几种不同的方法。你不需要记住公式,只要知道什么场景用什么方法就行。
1. L2(欧氏距离)
一句话理解:两点之间的直线距离。
向量A = [1, 2]
向量B = [4, 6]
L2距离 = √[(4-1)² + (6-2)²] = 5
特点:
- 数值越小,表示越相似
- 对向量的"长度"敏感
适用场景:
- 图像相似度搜索
- 需要考虑数值大小的场景
2. COSINE(余弦相似度)
一句话理解:两个向量的夹角有多小。
B
/
/ 夹角小 = 方向相近 = 语义相似
/
A ———————
特点:
- 数值范围是 -1 到 1,越接近 1 越相似
- 只看"方向",不看"长度"
- 一段话写得长或短,不影响相似度判断
适用场景:
- 文本语义搜索(最常用)
- 文档长短不一的场景
3. IP(内积,Inner Product)
一句话理解:方向和长度都考虑。
特点:
- 数值越大越相似
- 如果向量已经做过归一化(长度都是 1),效果等同于余弦相似度
适用场景:
- 推荐系统
- 向量已归一化的场景
4. 怎么选?
对于 RAG 场景,90% 的情况选 COSINE 就对了:
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 文本语义搜索 | COSINE | 只关心语义方向,不关心文档长短 |
| 图像搜索 | L2 | 像素特征对绝对数值敏感 |
| 推荐系统 | IP | 通常向量已归一化 |
为什么需要专门的向量数据库
1. 暴力搜索的性能灾难
假设你的知 识库有 100 万条文档,每条文档的向量是 1024 维。
用户问一个问题,你需要:
- 把问题转成 1024 维向量
- 和 100 万条文档向量逐一计算相似度
- 排序,取最相似的 10 条
这意味着:100 万次向量距离计算,每次涉及 1024 个浮点数运算。
用 Java 写个 for 循环当然能实现,但是:
- 单次查询可能要好几秒
- 并发一上来,服务器直接挂掉
2. 向量数据库的解决方案
向量数据库(如 Milvus)使用一类叫 ANN(Approximate Nearest Neighbor,近似最近邻) 的算法。
核心思想是:不追求 100% 精确,用一点点准确率下降换取巨大的速度提升。
| 方式 | 100万条数据查询耗时 | 准确率 |
|---|---|---|
| 暴力搜索 | 几秒到几十秒 | 100% |
| ANN 算法 | 几毫秒到几十毫秒 | 95%+ |
对于 RAG 场景,我们要的是"最相关的几条文档",少返回一两条不太相关的问题不大。用 95% 的准确率换 1000 倍的性能提升,非常划算。
3. Milvus 是什么
Milvus 是一个开源的向量数据库,专门用来存储、索引和搜索大规模向量数据。
它的核心能力:
- 存储:高效存储数十亿级别的向量