向量数据库
学习目标
完成本节后,你将能够:
- 理解为什么 RAG 经常需要向量数据库
- 分清“向量”、“元数据”和“相似度检索”的关系
- 跑通一个最小可运行的向量检索示例
- 知道选择向量数据库时要关注哪些维度
一、为什么普通数据库不够用?
1.1 RAG 里要找的不是“完全相同”,而是“语义相近”
传统数据库擅长做:
- 精确匹配
- 条件过滤
- 关系查询
但 RAG 更常见的问题是:
用户问一句话,系统要找到“意思最接近”的文本块。
比如用户问:
“怎么退课?”
知识库里可能写的是:
“课程购买后 7 天内可申请退款”
这两句话字面不完全一样,但语义相关。
这就是向量检索擅长处理的场景。
1.2 向量数据库本质上是在管理“语义坐标”
你可以把每段文本的 embedding 想成一组坐标。
向量数据库做的事就是:
- 存下这些坐标
- 用户查询时,把问题也变成坐标
- 找离它最近的那些点
二、向量数据库里通常存什么?
2.1 不只是向量,还会存文本和元数据
一条记录通常至少包含:
idvectortextmetadata
比如:
record = {
"id": "doc_001",
"vector": [0.2, 0.8, 0.1],
"text": "课程购买后 7 天内可申请退款",
"metadata": {"section": "退款政策", "source": "policy.pdf"}
}
print(record)
2.2 元数据为什么重要?
因为很多时候你不只想“语义接近”,还想“满足业务过滤条件”。
例如:
- 只查
section=退款政策 - 只查某个产品版本
- 只查某个部门文档
所以向量数据库不是“只有向量”,而是“向量 + 文本 + 元数据”的组合管理。
三、一个最小可运行的向量检索器
下面我们用 numpy 手写一个迷你向量库,让原理完全可见。
import numpy as np
records = [
{
"id": "r1",
"vector": np.array([0.95, 0.05, 0.10]),
"text": "课程购买后 7 天内可申请退款",
"metadata": {"section": "退款政策"}
},
{
"id": "r2",
"vector": np.array([0.10, 0.95, 0.05]),
"text": "完成结课项目后可获得证书",
"metadata": {"section": "证书说明"}
},
{
"id": "r3",
"vector": np.array([0.20, 0.80, 0.15]),
"text": "通过结课测试后系统会发放证书",
"metadata": {"section": "证书说明"}
}
]
query_vector = np.array([0.90, 0.10, 0.10])
def cosine_similarity(a, b):
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
results = []
for item in records:
score = cosine_similarity(query_vector, item["vector"])
results.append((score, item["id"], item["text"]))
for score, rid, text in sorted(results, reverse=True):
print(rid, round(score, 4), text)
这里 query_vector 可以理解成“用户问题的 embedding”。