向量数据库入门指南:从原理到实战
什么是向量数据库
向量数据库(Vector Database)是一种专门存储和检索向量数据的数据库。
要理解它,先要搞清楚"向量"在这里指的是什么。
向量的本质
一段文字经过 embedding 模型(比如 BGE-M3、text-embedding-3)处理后,会输出一串浮点数:
"国际货代系统" → [0.023, -0.156, 0.891, ..., 0.342]
这串数字通常有 768 维、1024 维甚至 1536 维。每个数字代表一个语义特征。模型在海量语料上训练过,学会把"语义"压缩成数值。
关键特性:
- 语义相近的句子,向量在空间里挨得近
- 语义无关的句子,向量在空间里离得远
- 不同语言的同义内容,也会靠近(多语言模型)
"报关单" → [0.12, -0.34, 0.78, ...]
"customs dec" → [0.15, -0.31, 0.81, ...] ← 挨得很近
"今晚吃什么" → [-0.67, 0.92, -0.13, ...] ← 离得很远
这就是整个系统的魔法基础。
和传统数据库的区别
MySQL:精确匹配
SELECT * FROM users WHERE id = 123;
-- 对就对,错就错
向量库:模糊匹配
找和"报关单怎么写"最相似的 5 条文档片段
-- 不比谁一模一样,比谁最接近
打个比方:
- MySQL 像查字典 — 按拼音找到唯一那条
- 向量库像在茫茫人海里找"长得最像你的人" — 算距离,返回相似度最高的几条
Embedding — 文字怎么变成向量
你输入一段文字,经过 embedding 模型,输出就是一串数字。
核心原理:
模型通过训练学会了"语义的数学表达"。同一个词在不同语境下的含义不同,embedding 会捕捉这种差异。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-m3")
sentences = ["报关单", "海关申报文件", "今晚吃什么"]
vectors = model.encode(sentences)
# 报关单 和 海关申报文件 的相似度:0.89
# 报关单 和 今晚吃什么 的相似度:0.12
不同语言的同义内容也会靠近,这就是多语言 embedding 模型的厉害之处。
向量空间 — 高维世界
人类只能想象 3 维。但向量数据库工作在 1024 维、1536 维的空间里。
不用试图想象它,用 2 维类比就行:
y
↑
"猫" ·
| · "狗"
|
· "报关" |
| · "物流"
|
──────+────────────→ x
|
· "今晚吃什么"
在这个空间里,"猫"和"狗"挨着,"报关"和"物流"挨着,但它们两组之间离很远。
1024 维就是 1024 个这样的轴。每个轴捕捉一种语义特征,只是人类没法给它命名。
相似度计算 — 怎么判断"谁最像"
最常用的是余弦相似度:
cos(θ) = A · B / (|A| × |B|)
两个向量的夹角越小,相似度越高:
- 结果 = 1.0 → 完全一致
- 结果 = 0.8 → 非常相似
- 结果 = 0.3 → 关系不大
- 结果 = 0.0 → 完全无关
另一个是欧氏距离,算两个点之间的直线距离。距离越短越相似。
大多数向量库默认用余弦相似度(内积),因为对向量长度不敏感,只关心"方向",也就是语义。
索引算法 — 为什么快
这才是向量库的核心技术。
最笨的方法是遍历所有向量,一个一个算相似度。10 万条数据就要算 10 万次,这叫暴力搜索,慢但准确。
ANN(Approximate Nearest Neighbor):近似最近邻搜索,牺牲一点点准确率,换来百倍千倍的速度。
HNSW — 最常用
Hierarchical Navigable Small World。把向量空间想象成一张地图:
- 最上层:只有一些"地标城市",大跨度跳跃
- 中间层:城市 + 大镇,中距离导航
- 最底层:每个村镇都有,精细定位
搜索时先从顶层粗略定位区域,然后逐层细化。像高德地图从全国到省到市到街道的缩放。
速度:百万级数据,几毫秒出结果。
IVF — 分区索引
Inverted File Index。先把向量空间划分成 1000 个"小区",每个小区有自己的向量列表。
搜索时:
- 判断查询向量落在哪几个小区
- 只在这几个小区里暴力搜索
相当于你要找"朝阳区所有川菜馆",不用搜全北京,只搜朝阳区就行。
速度:比暴力搜索快 10-50 倍,适合亿级数据。
PQ — 乘积量化
Product Quantization。把 1024 维向量切成 8 段,每段 128 维。每段的向量都被压缩成一个"代号"(比如 1-256 的数字)。
原来存一个向量要 1024 × 4 字节 = 4KB。压缩后只要 8 字节。
10 亿条向量:
- 原始:4TB
- PQ 压缩后:8GB
代价是精度损失 1-3%,但内存占用降到原来的 1/500。
主流产品对比
| 产品 | 语言 | 特点 | 适合场景 |
|---|---|---|---|
| Qdrant | Rust | 性能好,支持过滤 | 中小项目,本地部署 |
| Milvus | Go/C++ | 企业级,分布式 | 大规模生产环境 |
| Chroma | Python | 极简,嵌入式 | 原型开发,单机 |
| Pinecone | 云端 | 托管服务,零运维 | SaaS,不想管服务器 |
| Weaviate | Go | 支持图+向量混合 | 知识图谱场景 |
| FAISS | C++ | Meta 出品,纯算法库 | 底层研究,自己封装 |
实际应用场景
RAG(检索增强生成)
用户问:报关单怎么生成?
↓
问题向量化 → [0.12, -0.34, ...]
↓
在向量库里找最相似的 3 条文档片段
↓
把找到的内容 + 原始问题一起给大模型
↓
大模型基于找到的内容回答
没有向量库,大模型只能靠训练记忆回答(可能过时)。有了向量库,它能查到你的最新文档再回答。
推荐系统
用户喜欢了文章 A → 找到 A 的最相似 10 篇文章 → 推荐给用户。这就是今日头条、抖音的底层逻辑之一。
图像搜索
上传一张图片 → 图片向量化 → 在图片库里找最相似的 → 返回外观相似的图片。淘宝"拍立淘"就是这样工作的。
语义去重
新来一条数据 → 向量化 → 在库里找相似度 > 0.95 的 → 找到了就是重复的,丢弃;没找到就入库。
完整数据流
以立刻云系统的 AI 会话查询为例:
1. 原始数据准备
历史订单、报关单、客户沟通记录,整理为文本格式。
2. 分块(Chunking)
每条记录切分成 500-1000 字的片段,重叠 10% 防止切断语义。
3. 向量化(Embedding)
每个片段调用 BGE-M3 生成 1024 维向量。1000 条片段 = 1000 个向量。
4. 入库
向量存进 Qdrant,原文存进 MySQL(带 ID 关联)。
5. 用户查询
用户问"上个月越南那批货的报关单号?" → 问题向量化 → 在 Qdrant 里找 top-5 相似片段 → 拿到 5 段原文 → 交给大模型 → 大模型综合回答。
核心总结
三句话记住向量数据库:
1. 向量是语义的数学表达 — 文字变数字,让机器能"理解"语义
2. 索引是速度的保证 — 暴力搜索太慢,HNSW/IVF/PQ 让亿级数据毫秒级响应
3. 向量库不替代关系库 — 它们互补。向量管"像不像",MySQL 管"准不准"
评论 ({{ comments.length }})
暂无评论,来说两句吧