前言:为什么向量数据库是 RAG 的“心脏”?

最近我正在闭门开发我的私有化代码 AI 平台 —— CodeFlow AI。在对 Qwen2.5-Coder 大模型和 BGE-Code 嵌入模型进行深度微调的间隙,我反思了一个核心问题:

即使模型再聪明,如果检索不到准确的本地代码上下文,它也会满口“胡言乱语”(幻觉)。

在 RAG(检索增强生成)架构中,向量数据库(Vector Database) 承担着大模型“外挂记忆体”的角色。面对市面上琳琅满目的向量数据库,开发者该如何选型?今天我就结合项目实战,带大家深度拆解几款主流的向量库。


一、 核心对比:谁才是你的“真命天子”?

在选型时,我们需要关注:部署难度、扩展性、混合搜索能力以及性能。以下是我整理的对比表:

维度 Chroma Qdrant Milvus (项目首选) Faiss
定位 轻量级、极简上手 高性能、工程化极佳 企业级、分布式云原生 基础算法库
底层语言 Python Rust Go / Python / C++ C++
部署感 就像安装一个 Python 包 Docker 一键启动 分布式集群/Docker 纯本地调用
数据规模 万级 ~ 十万级 十万级 ~ 千万级 千万级 ~ 亿级 取决于内存大小
适用场景 快速原型、个人助手 中大规模生产环境 企业级私有化、多租户 算法研究、离线检索

附带一个主流向量数据库横向对比表

维度 Milvus (项目当前选型) Qdrant Chroma Weaviate Faiss pgvector (Postgres)
定位 企业级分布式云原生 高性能、工程化友好 轻量级、开发友好 知识图谱+向量混合 纯算法库 (非数据库) 传统数据库扩展
开发语言 Go / Python / C++ Rust Python Go C++ C / SQL
部署方式 离线/Docker/集群 Docker/二进制/云 内存/持久化/Docker Docker/集群 本地 Library 插件安装
扩展性 极强 (分片/流式/批式) 强 (分布式集群) 较弱 (单机为主) 无 (需手动实现) 依赖 Postgres 架构
混合搜索 支持 (标量+向量) 支持 (功能极强) 基础支持 支持 (带 GraphQL) 不支持 强 (SQL 语法)
适用场景 海量数据、多租户、生产环境 中大规模、追求极致速度 快速原型、本地 Demo 复杂关联搜索 算法研究、纯本地检索 已有 PG 数据库的企业

二、 主流向量数据库实战 Demo

为了让大家更有体感,我分别为这四款库编写了简单的 Python Demo。

1. Chroma:开发者的“第一口奶”

如果你想在 5 分钟内跑通一个 RAG Demo,选 Chroma。

import chromadb

# 初始化持久化客户端
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.get_or_create_collection(name="code_repo")

# 插入代码片段
collection.add(
    documents=["def get_user_id(): return 1", "class AuthManager: pass"],
    metadatas=[{"lang": "python"}, {"lang": "python"}],
    ids=["id1", "id2"]
)

# 检索
results = collection.query(query_texts=["How to auth?"], n_results=1)
print(f"Chroma 结果: {results['documents']}")

2. Qdrant:追求极致性能的“工业模范”

Qdrant 用 Rust 编写,其“过滤检索”功能非常强大,适合需要复杂业务过滤的场景。

from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct

client = QdrantClient(":memory:") # 内存模式
client.recreate_collection(
    collection_name="code_data",
    vectors_config=VectorParams(size=4, distance=Distance.COSINE)
)

# 插入带 Payload 的数据
client.upsert(
    collection_name="code_data",
    points=[PointStruct(id=1, vector=[0.1, 0.2, 0.3, 0.4], payload={"path": "src/main.py"})]
)

print("Qdrant 数据已就绪...")

3. Milvus:CodeFlow AI 的企业级选择

为什么我的项目最终选择了 Milvus?因为它支持存算分离多租户。在企业环境中,不同部门的代码需要物理或逻辑隔离,Milvus 的 Partition 机制简直是救星。

from pymilvus import connections, CollectionSchema, FieldSchema, DataType, Collection

connections.connect("default", host="localhost", port="19530")

# 定义 Schema (严谨的企业级开发)
fields = [
    FieldSchema(name="pk", dtype=DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema(name="embeddings", dtype=DataType.FLOAT_VECTOR, dim=768) # 匹配 BGE 维度
]
schema = CollectionSchema(fields, "Code Flow AI Data")
col = Collection("project_v1", schema)

print("Milvus 集合创建成功,准备迎接亿级数据!")

4. FAISS:不朽的算法鼻祖

FAISS 是 Meta 开发的算法库,如果你不需要数据库功能(如持久化、API、多用户),只要纯粹的检索速度,选它。

import faiss
import numpy as np

d = 768  # 维度
index = faiss.IndexFlatL2(d) 
data = np.random.random((100, d)).astype('float32')
index.add(data) # 极其纯粹的内存向量操作

D, I = index.search(data[:1], 5)
print(f"FAISS 检索到的最近索引: {I}")

三、 避坑与经验:我在 CodeFlow AI 中的思考

在从 Chroma 迁移到 Milvus 的过程中,我总结了三点经验:

  1. 维度匹配(Dimension): 无论选哪个库,必须确保向量库定义的维度与你的 Embedding 模型(如 bge-code)输出维度一致。

  2. 索引算法的选择:

    • 数据量小:FLAT(暴力搜索,最准)。

    • 数据量大:HNSW(基于图的搜索,速度与精度的平衡点)。

  3. 不仅仅是向量: 在代码检索场景中,标量过滤(Scalar Filtering) 极其重要。比如:“只在 Python 项目中检索关于登录逻辑的代码”。这就要求向量库必须具备强大的混合搜索能力。


如果你对 AI 辅助编程或 RAG 架构感兴趣,欢迎点赞关注,我们一起交流!

更多推荐