为什么需要向量数据库

embedding 数量大了之后:

  • 内存装不下(百万级向量需要 GB 级)
  • 暴力搜索慢(百万 × 1024 维 = 10 亿次乘法)

向量数据库做两件事:

  1. 持久化存向量
  2. 近似最近邻搜索(ANN)——用索引加速

三大主流

特点 适合
FAISS Meta 出品,纯库,最快 单机 / 嵌入式
Chroma 最易上手,开箱即用 原型 / 中小项目
Qdrant Rust 写的服务端,功能全 生产环境

还有:Weaviate / Milvus / pgvector(PostgreSQL 插件)。

FAISS:最快最纯粹

pip install faiss-cpu          # 或 faiss-gpu
import faiss
import numpy as np

dim = 1024
n = 10000

# 准备向量(实际是 embedding 模型生成的)
vectors = np.random.randn(n, dim).astype(np.float32)
faiss.normalize_L2(vectors)    # 归一化

# 建索引
index = faiss.IndexFlatIP(dim)    # IP = 内积,配合归一化向量 = 余弦相似
index.add(vectors)
print(index.ntotal)                # 10000

# 搜索:找前 5 相似
query = np.random.randn(1, dim).astype(np.float32)
faiss.normalize_L2(query)
distances, ids = index.search(query, k=5)
print(ids[0], distances[0])

万级向量用 IndexFlatIP(暴力搜索,最准);百万级要用 IVF / HNSW 索引(更快但稍微不准)。

Chroma:最好上手

pip install chromadb
import chromadb

client = chromadb.PersistentClient(path="./chroma_db")
collection = client.get_or_create_collection("my_docs")

# 添加文档(Chroma 自动算 embedding 并存)
collection.add(
    documents=["Python 是编程语言", "今天天气真好", "机器学习入门"],
    ids=["1", "2", "3"],
    metadatas=[{"source": "wiki"}, {"source": "blog"}, {"source": "wiki"}],
)

# 搜索
results = collection.query(
    query_texts=["编程语言"],
    n_results=2,
)
print(results["documents"])
print(results["distances"])

带过滤搜索:

collection.query(
    query_texts=["编程"],
    n_results=5,
    where={"source": "wiki"},
)

Chroma 自动算 embedding——最省心。也能换自定义 embedding 函数。

Qdrant:生产推荐

# 用 Docker
docker run -p 6333:6333 qdrant/qdrant
pip install qdrant-client
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct

client = QdrantClient(host="localhost", port=6333)

client.create_collection(
    collection_name="docs",
    vectors_config=VectorParams(size=1024, distance=Distance.COSINE),
)

client.upsert(
    collection_name="docs",
    points=[
        PointStruct(id=1, vector=vec1.tolist(), payload={"text": "..."}),
        PointStruct(id=2, vector=vec2.tolist(), payload={"text": "..."}),
    ],
)

results = client.search(
    collection_name="docs",
    query_vector=q_vec.tolist(),
    limit=5,
)
for r in results:
    print(r.score, r.payload["text"])

支持过滤、混合搜索、HTTP API、副本集——生产环境推荐。

选哪个

场景
学习 / 单文件玩具 FAISS
快速原型 / 小数据 Chroma
生产环境 / 大数据 / 团队共享 Qdrant 或 Weaviate
已经用 PostgreSQL pgvector
极致性能 / 边缘部署 FAISS

关于"近似"

向量数据库的搜索叫 ANN(Approximate Nearest Neighbor)——为了快牺牲一点准确率。recall@10 = 0.95 表示前 10 结果里 95% 是真正最相似的。对 RAG 来说完全够用

下一篇用这些工具搭真正的 RAG。