向量数据库实战
1. 嵌入模型 (Embedding Models)
1.1 嵌入模型概述
嵌入模型将文本转换为高维向量,使语义相似的文本在向量空间中距离更近。选择合适的嵌入模型是RAG系统性能的关键。
1.2 主流嵌入模型对比
| 模型 | 维度 | 最大长度 | 中文支持 | 特点 |
|---|---|---|---|---|
| OpenAI text-embedding-ada-002 | 1536 | 8191 tokens | 好 | 通用性强,API调用 |
| OpenAI text-embedding-3-small | 1536 | 8191 tokens | 好 | 性价比高 |
| OpenAI text-embedding-3-large | 3072 | 8191 tokens | 好 | 精度最高 |
| BGE-large-zh | 1024 | 512 tokens | 优秀 | 中文最佳开源模型之一 |
| BGE-M3 | 1024 | 8192 tokens | 优秀 | 多语言、多粒度、多功能 |
| E5-large-v2 | 1024 | 512 tokens | 好 | 微软出品,性能优秀 |
| E5-mistral-7b | 4096 | 32768 tokens | 好 | 基于LLM的嵌入模型 |
| Cohere embed-v3 | 1024 | 512 tokens | 好 | 支持检索/分类/聚类 |
| Jina-embeddings-v2 | 768 | 8192 tokens | 好 | 长文本支持好 |
1.3 选择建议
- 中文场景: BGE-M3 或 BGE-large-zh
- 多语言: BGE-M3 或 Cohere embed-v3
- 快速原型: OpenAI text-embedding-3-small
- 最高精度: OpenAI text-embedding-3-large
- 长文本: E5-mistral-7b 或 Jina-embeddings-v2
- 私有部署: BGE系列 或 E5系列
1.4 使用示例
# OpenAI Embeddings
from openai import OpenAI
client = OpenAI()
response = client.embeddings.create(
model="text-embedding-3-small",
input=["什么是向量数据库?", "Vector database introduction"]
)
embeddings = [item.embedding for item in response.data]
# BGE Embeddings (本地部署)
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-large-zh-v1.5")
texts = ["什么是向量数据库?", "向量检索的原理"]
embeddings = model.encode(texts, normalize_embeddings=True)
2. 向量数据库对比
2.1 主流向量数据库
ChromaDB — 轻量级入门
import chromadb
# 创建客户端
client = chromadb.PersistentClient(path="./chroma_db")
# 创建集合
collection = client.create_collection(
name="documents",
metadata={"hnsw:space": "cosine"}
)
# 添加文档
collection.add(
documents=["文档1内容", "文档2内容"],
metadatas=[{"source": "file1"}, {"source": "file2"}],
ids=["id1", "id2"]
)
# 查询
results = collection.query(
query_texts=["搜索关键词"],
n_results=5
)
特点: 嵌入式、Python原生、零配置、适合原型开发
Pinecone — 全托管服务
from pinecone import Pinecone
pc = Pinecone(api_key="your-api-key")
# 创建索引
pc.create_index(
name="documents",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
index = pc.Index("documents")
# 写入
index.upsert(
vectors=[
{"id": "id1", "values": embedding1, "metadata": {"text": "..."}},
{"id": "id2", "values": embedding2, "metadata": {"text": "..."}},
]
)
# 查询
results = index.query(vector=query_embedding, top_k=5, include_metadata=True)
特点: 全托管、免运维、自动扩缩、企业级SLA
Milvus — 可扩展开源方案
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
# 连接
connections.connect("default", host="localhost", port="19530")
# 定义Schema
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1536),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535),
]
schema = CollectionSchema(fields)
# 创建集合
collection = Collection("documents", schema)
# 创建索引
collection.create_index(
field_name="embedding",
index_params={"index_type": "HNSW", "metric_type": "COSINE", "params": {"M": 16, "efConstruction": 256}}
)
# 搜索
collection.load()
results = collection.search(
data=[query_embedding],
anns_field="embedding",
param={"metric_type": "COSINE", "params": {"ef": 64}},
limit=5,
output_fields=["text"]
)
特点: 分布式架构、亿级向量、GPU加速、生产级可靠性
pgvector — PostgreSQL扩展
-- 安装扩展
CREATE EXTENSION vector;
-- 创建表
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536)
);
-- 创建索引
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);
-- 插入数据
INSERT INTO documents (content, embedding)
VALUES ('文档内容', '[0.1, 0.2, ...]');
-- 查询
SELECT content, 1 - (embedding <=> query_embedding) AS similarity
FROM documents
ORDER BY embedding <=> query_embedding
LIMIT 5;
特点: 利用现有PostgreSQL基础设施、SQL查询、事务支持、与关系数据联合查询
Weaviate — 语义搜索引擎
import weaviate
client = weaviate.Client("http://localhost:8080")
# 创建Schema
client.schema.create_class({
"class": "Document",
"vectorizer": "text2vec-openai",
"properties": [
{"name": "content", "dataType": ["text"]},
{"name": "source", "dataType": ["string"]},
]
})
# 添加数据(自动向量化)
client.data_object.create(
{"content": "文档内容", "source": "file1"},
class_name="Document"
)
# 语义搜索
result = client.query.get("Document", ["content", "source"]) \
.with_near_text({"concepts": ["搜索关键词"]}) \
.with_limit(5) \
.do()
特点: 内置向量化、GraphQL API、混合搜索、模块化架构
2.2 对比总结
| 数据库 | 部署方式 | 扩展性 | 易用性 | 适用场景 |
|---|---|---|---|---|
| ChromaDB | 嵌入式/本地 | 低 | 极高 | 原型开发、小规模应用 |
| Pinecone | 全托管 | 高 | 高 | 企业级、免运维 |
| Milvus | 自部署/云 | 极高 | 中 | 大规模、高性能需求 |
| pgvector | PostgreSQL扩展 | 中 | 高 | 已有PG基础设施 |
| Weaviate | 自部署/云 | 高 | 高 | 语义搜索、多模态 |
3. 相似度搜索
3.1 距离度量
余弦相似度 (Cosine Similarity)
\[\text{cosine}(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{||\mathbf{a}|| \cdot ||\mathbf{b}||}\]
- 范围: [-1, 1],1表示完全相同
- 适用: 文本语义相似度(最常用)
- 对向量长度不敏感
点积 (Dot Product)
\[\text{dot}(\mathbf{a}, \mathbf{b}) = \mathbf{a} \cdot \mathbf{b} = \sum_{i} a_i \cdot b_i\]
- 范围: 无限制
- 适用: 归一化向量(等价于余弦相似度)
- 计算速度最快
欧几里得距离 (Euclidean Distance)
\[L_2(\mathbf{a}, \mathbf{b}) = \sqrt{\sum_{i}(a_i - b_i)^2}\]
- 范围: [0, +∞),0表示完全相同
- 适用: 需要考虑向量幅度的场景
3.2 选择建议
- 文本检索: 余弦相似度(推荐)
- 归一化嵌入: 点积(更快)
- 图像/多模态: 欧几里得距离
4. 索引类型
4.1 HNSW (Hierarchical Navigable Small World)
层级结构:
Level 2: ●───────────────●
Level 1: ●───●───●───●───●
Level 0: ●●●●●●●●●●●●●●●●
- 原理: 构建多层图结构,从高层开始搜索,逐层下降到低层
- 优点: 查询速度快、精度高
- 缺点: 内存占用大(需要存储图结构)
- 参数:
-
M: 每个节点的连接数(16-64) -efConstruction: 构建时搜索宽度(越大越精确但越慢) -ef: 查询时搜索宽度
4.2 IVF (Inverted File Index)
聚类中心: C1, C2, C3, ...
C1 → [v1, v5, v12, ...]
C2 → [v2, v7, v15, ...]
C3 → [v3, v8, v20, ...]
- 原理: 先将向量聚类,查询时只搜索最近的几个聚类
- 优点: 内存效率高
- 缺点: 精度不如HNSW
- 参数:
-
nlist: 聚类数量 -nprobe: 查询时搜索的聚类数
4.3 索引选择建议
| 数据规模 | 推荐索引 | 说明 |
|---|---|---|
| < 10万 | Flat (暴力搜索) | 数据量小,精确搜索 |
| 10万-100万 | HNSW | 精度和速度的最佳平衡 |
| 100万-1000万 | IVF + HNSW | 分层索引 |
| > 1000万 | IVF + PQ | 压缩向量,节省内存 |
5. 实践建议
5.1 性能优化
- 批量写入: 使用batch API而非逐条插入
- 预热索引: 查询前加载索引到内存
- 异步查询: 使用异步API提高并发
- 缓存热点: 缓存高频查询结果
5.2 数据管理
- 元数据过滤: 利用元数据缩小搜索范围
- 增量更新: 支持文档的添加、更新、删除
- 数据备份: 定期备份向量数据
- 版本管理: 跟踪嵌入模型版本,模型变更时需重新嵌入
5.3 监控指标
- 查询延迟(P50, P95, P99)
- 召回率 (Recall@K)
- 索引大小和内存使用
- QPS(每秒查询数)
参考资料
- MTEB Leaderboard (Massive Text Embedding Benchmark)
- ANN Benchmarks (ann-benchmarks.com)
- RAG架构设计 — RAG Pipeline整体架构
- RAG评估与优化 — 检索质量评估方法