向量数据库实战(Milvus/Chroma)
从 Embedding 的第一个维度到 RAG 系统的最后一公里——手把手带你玩转向量数据库。
附录
A. pgvector vs Chroma vs Milvus 选型指南
核心对比
| 维度 | pgvector | Chroma | Milvus |
|---|---|---|---|
| 定位 | PostgreSQL 向量扩展 | 嵌入式向量数据库 | 生产级分布式向量引擎 |
| 安装 | CREATE EXTENSION vector | pip install chromadb | Docker Compose / K8s |
| 额外基建 | ❌ 无(复用已有 PG) | 需单独进程 | 需 etcd + MinIO + 多组件 |
| 学习曲线 | ⭐ 会 SQL 就会用 | ⭐ 极低 | ⭐⭐⭐ 需理解 Schema/索引 |
| Schema | SQL 表结构 | 无 Schema | 强 Schema |
| 索引类型 | HNSW / IVFFlat | HNSW(唯一) | HNSW / IVF / DiskANN 等 |
| 向量 + 业务数据 | ✅ 同表同事务 | ❌ 独立存储 | ❌ 独立存储 |
| SQL 支持 | ✅ 完整(JOIN/WHERE/GROUP BY) | ❌ 简单过滤 | 有限标量过滤 |
| ACID 事务 | ✅ | ❌ | ❌ |
| 混合检索 | ✅ 向量 + tsvector/BM25 | ❌ | ✅ Dense + Sparse |
| 数据规模 | < 500 万条 | < 50 万条 | 10 亿级 |
| 分布式 | 需 Citus 扩展 | ❌ | ✅ 原生支持 |
| GPU 加速 | ❌ | ❌ | ✅(v2.3+) |
| 托管服务 | Supabase / Neon / RDS | ❌ | Zilliz Cloud |
| 生态集成 | SQLAlchemy / Django ORM | LangChain 一键集成 | LangChain + LlamaIndex |
性能对比参考
测试环境:单机 16GB RAM,100 万条 1536 维向量
指标 pgvector(HNSW) Chroma Milvus(HNSW)
────────────────────────────────────────────────────────────
写入 10 万条 45s 30s 25s
Top-10 查询延迟 8-15ms 10-20ms 3-8ms
Recall@10 95%+ 93%+ 97%+
内存占用 ~4GB ~6GB ~5GB
结论:
→ Milvus 查询最快、精度最高
→ pgvector 综合表现优秀(且省了一套基建)
→ Chroma 轻量但大数据量下性能下降明显选型决策树
你的项目需要向量搜索:
│
├── 已经在用 PostgreSQL?
│ ├── 是 → 数据量 < 500 万?
│ │ ├── 是 → ✅ pgvector(零基建,SQL 混合查询)
│ │ └── 否 → ✅ Milvus(专业向量引擎)
│ └── 否 ↓
│
├── 只是做原型 / 学习 / Jupyter 实验?
│ └── 是 → ✅ Chroma(5 分钟上手)
│
├── 需要向量和业务数据在同一个事务中?
│ └── 是 → ✅ pgvector(ACID 事务保证)
│
├── 需要 Dense + Sparse 混合检索?
│ └── 是 → ✅ Milvus(原生 Sparse 支持)
│
├── 数据量 > 1000 万?
│ └── 是 → ✅ Milvus Distributed 或 Zilliz Cloud
│
└── 不想运维任何数据库?
├── 有 PostgreSQL 托管 → ✅ Supabase pgvector
└── 纯向量需求 → ✅ Zilliz Cloud / Pinecone按团队阶段推荐
| 阶段 | 推荐 | 理由 |
|---|---|---|
| 个人开发 / 学习 | Chroma | 零配置,pip 安装即用 |
| 初创团队 / MVP | pgvector | 复用已有 PG,无额外运维 |
| 中型团队 / 正式产品 | pgvector 或 Milvus Standalone | 按数据量和查询复杂度选 |
| 大型团队 / 亿级数据 | Milvus Distributed | 原生分布式,水平扩展 |
| 不想运维 | Supabase(pgvector) 或 Zilliz Cloud | 托管服务,开箱即用 |
💡 最常见的演进路径: Chroma(原型验证)→ pgvector(上线 MVP)→ Milvus(数据量增长后迁移)。不要一上来就用 Milvus——除非你确定数据量会超过百万级。
B. Embedding 模型选型速查
| 模型 | 维度 | 中文能力 | 最大 Token | 部署方式 | 推荐场景 |
|---|---|---|---|---|---|
| OpenAI text-embedding-3-small | 1536 | ⭐⭐⭐ | 8191 | API | 快速原型,多语言 |
| OpenAI text-embedding-3-large | 3072 | ⭐⭐⭐ | 8191 | API | 最高精度,预算充足 |
| BAAI/bge-large-zh-v1.5 | 1024 | ⭐⭐⭐⭐⭐ | 512 | 本地 | 中文场景首选 |
| BAAI/bge-m3 | 1024 | ⭐⭐⭐⭐⭐ | 8192 | 本地 | 混合检索(Dense+Sparse) |
| BAAI/bge-small-zh-v1.5 | 512 | ⭐⭐⭐⭐ | 512 | 本地 | 资源受限、轻量部署 |
| sentence-transformers/all-MiniLM-L6-v2 | 384 | ⭐ | 256 | 本地 | 英文场景、Chroma 默认 |
| nomic-ai/nomic-embed-text-v1.5 | 768 | ⭐⭐⭐ | 8192 | 本地 | 长文本、开源多语言 |
| Cohere embed-multilingual-v3 | 1024 | ⭐⭐⭐⭐ | 512 | API | 多语言、Cohere 生态 |
选型决策:
你的文档是什么语言?
│
├── 中文为主
│ ├── 需要混合检索? → BGE-M3
│ ├── 不需要混合检索? → BGE-large-zh-v1.5
│ └── 资源受限? → BGE-small-zh-v1.5
│
├── 英文为主
│ ├── 预算充足? → OpenAI text-embedding-3-large
│ ├── 想用本地模型? → nomic-embed-text-v1.5
│ └── 极度轻量? → all-MiniLM-L6-v2
│
└── 多语言混合
├── 用 API? → OpenAI text-embedding-3-small
└── 用本地? → BGE-M3Reranker 模型速查
| 模型 | 中文能力 | 最大长度 | 速度 | 推荐度 |
|---|---|---|---|---|
| BAAI/bge-reranker-v2-m3 | ⭐⭐⭐⭐⭐ | 512 | 中等 | ⭐⭐⭐⭐⭐ 首选 |
| BAAI/bge-reranker-large | ⭐⭐⭐⭐⭐ | 512 | 慢 | ⭐⭐⭐⭐ |
| cross-encoder/ms-marco-MiniLM-L-12-v2 | ⭐ | 512 | 快 | ⭐⭐⭐ 英文 |
| Cohere rerank-multilingual-v3 | ⭐⭐⭐⭐ | 4096 | API | ⭐⭐⭐⭐ 多语言 |
C. 常见问题与排查
搜索结果不准确
问题:搜索结果语义不相关
排查步骤:
─────────────────────────────────────
1. 检查 Embedding 模型是否匹配
→ 存储和查询必须用同一个模型
→ 常见错误:存储用了 BGE,查询用了 OpenAI
2. 检查分块策略
→ 块太大:语义被稀释,搜什么都"有点相关"
→ 块太小:只有片段,缺少上下文
→ 建议:chunk_size=400, overlap=80
3. 检查距离度量
→ 模型输出未归一化,但用了内积(IP)
→ 解决:换成 COSINE 或手动归一化
4. 尝试混合检索
→ 纯语义搜索对精确术语不友好
→ 加上 Sparse 检索可以互补Milvus 常见错误
错误 1:搜索时报 "collection not loaded"
─────────────────────────────────────
原因:搜索前没有 load
解决:collection.load()
错误 2:"dimension mismatch"
─────────────────────────────────────
原因:插入的向量维度和 Schema 定义不一致
解决:检查 Embedding 模型维度 == Schema 的 dim 参数
错误 3:"insert data size exceeds"
─────────────────────────────────────
原因:单次插入数据过大(超过 512MB)
解决:减小每批插入的数量
错误 4:Docker 启动后连不上
─────────────────────────────────────
原因:Milvus 各组件启动有先后顺序
解决:等待 30 秒后重试,或检查 docker compose ps
确保 etcd、minio、standalone 都是 running
错误 5:搜索变慢了
─────────────────────────────────────
原因:可能是数据增长后索引参数不够
解决:
→ 增大 ef_search(HNSW)或 nprobe(IVF)
→ 检查内存使用率(> 80% 会导致换页)
→ 考虑升级到更大内存的机器Chroma 常见错误
错误 1:"No embedding function provided"
─────────────────────────────────────
原因:get_collection 时没传 embedding_function
解决:每次 get_collection 都要传入
和 create_collection 时一样的 embedding_function
错误 2:重启后数据丢失
─────────────────────────────────────
原因:用了 Client() 而不是 PersistentClient()
解决:chromadb.PersistentClient(path="./data")
错误 3:"Batch size exceeds maximum"
─────────────────────────────────────
原因:Chroma 默认单批次上限 41666 条
解决:分批添加,每批 10000 条
错误 4:中文搜索效果差
─────────────────────────────────────
原因:默认的 all-MiniLM-L6-v2 对中文支持极弱
解决:换成 BGE-large-zh-v1.5 或 OpenAI EmbeddingD. 推荐工具与学习资源
开发工具
| 工具 | 用途 | 链接 |
|---|---|---|
| Attu | Milvus 可视化管理界面 | github.com/zilliztech/attu |
| LangChain | RAG 框架,集成 Chroma/Milvus | python.langchain.com |
| LlamaIndex | 数据索引框架,RAG 专用 | llamaindex.ai |
| Ragas | RAG 评测框架 | github.com/explodinggradients/ragas |
| MTEB | Embedding 模型评测排行榜 | huggingface.co/spaces/mteb/leaderboard |
官方文档
| 资源 | 链接 |
|---|---|
| Milvus 官方文档 | milvus.io/docs |
| Chroma 官方文档 | docs.trychroma.com |
| pymilvus API 参考 | milvus.io/api-reference/pymilvus/v2.4.x |
| BGE 模型仓库 | huggingface.co/BAAI |
| Sentence Transformers | sbert.net |
进阶阅读
深入学习路径:
向量检索理论
─────────────────────────────────────
• "Efficient and Robust ANN Search Using HNSW"(HNSW 原始论文)
• "Billion-scale similarity search with GPUs"(FAISS 论文)
• Ann-benchmarks.com(ANN 算法基准测试)
RAG 最佳实践
─────────────────────────────────────
• "Retrieval-Augmented Generation for Large Language Models: A Survey"
• "Seven Failure Points When Engineering a RAG System"
• LangChain RAG 教程系列
Embedding 模型
─────────────────────────────────────
• MTEB 排行榜(选模型的权威参考)
• "Text Embeddings by Weakly-Supervised Contrastive Pre-training"(BGE 论文)
• Sentence-BERT 论文快速命令备忘
bash
# === Chroma ===
pip install chromadb # 安装
chroma run --port 8000 # 启动 Server
docker run -p 8000:8000 chromadb/chroma # Docker 启动
# === Milvus ===
pip install pymilvus # 安装 SDK
# 下载 docker-compose
wget https://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml -O docker-compose.yml
docker compose up -d # 启动 Standalone
docker compose ps # 检查状态
docker compose down # 停止
docker compose down -v # 停止 + 删除数据
# === Embedding 模型 ===
pip install sentence-transformers # BGE 等本地模型
pip install openai # OpenAI API
# === 评测 ===
pip install ragas # RAG 评测框架📘 全书完。本教程从向量的基本概念出发,经过 Embedding 生成、相似度搜索、索引算法、Chroma/Milvus 实战、混合检索与 Reranker,最终构建了一个完整的生产级 RAG 知识库问答系统。希望这条从零到一的学习路径,能帮助你在 AI 应用开发中走得更远。