跳到主要内容

Milvus 向量库实践

Milvus 是面向 大规模向量相似检索 的开源向量数据库,RAG 里负责存 embedding、做 top-k 搜索。本篇讲核心概念与最小 ingest / search;与 LangChain 拼装见下文「LangChain + Milvus」。流水线概念见 RAG 与检索增强;Chroma 本地 PoC 见 [LangChain RAG 实践](/docs/ai/RAG/LangChain RAG 实践)。

在 RAG 里的位置​

切分(chunk) → embedding → 【Milvus 入库】→ 问句 embedding → 【Milvus search】→ 拼 Prompt → 生成
RAG 阶段Milvus 对应
写入索引insert / LangChain add_documents
检索 top-ksearch / as_retriever
元数据过滤collection 里 VARCHAR 字段 + filter 表达式
持久化Milvus Lite 文件 / Docker 服务 / Zilliz Cloud

何时从 Chroma 换 Milvus:数据量上来、要多副本与高可用、要混合检索(dense + sparse)、要上生产集群——PoC 继续用 Chroma 即可。

部署形态(选型)​

形态URI 示例适合
Milvus Lite./milvus.db本地开发、小库、零 Docker
Standalone(Docker)http://localhost:19530本机/团队联调、中等规模
Zilliz Cloud云端 endpoint + token托管、免运维

Milvus Lite 把库写在本地文件,API 与服务器版一致,最适合「先跑通再迁 Docker」。

本地 Standalone(示意):

# 见 https://milvus.io/docs/install_standalone-docker.md
curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh | bash -s -- start

核心概念​

概念直觉
Collection类似表;一个 RAG 知识库常对应一个 collection
Schema字段定义:主键、FLOAT_VECTOR、文本/metadata(VARCHAR)
Index向量索引(如 AUTOINDEX、HNSW);必须先建 index 再 load/search
metric_type距离度量:COSINE(文本常用)、L2、IP;与 embedding 训练方式一致

PyMilvus 最小流程​

依赖:pip install pymilvus(版本以 Milvus 文档 为准)。

# milvus_rag/ingest_search.py
from pymilvus import MilvusClient, DataType

URI = "./milvus.db" # Milvus Lite;Docker 用 http://localhost:19530
COLLECTION = "rag_docs"
DIM = 128 # 与 embedding 模型维度一致

client = MilvusClient(uri=URI)

if client.has_collection(COLLECTION):
client.drop_collection(COLLECTION)

schema = client.create_schema(auto_id=True)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=DIM)
schema.add_field("text", DataType.VARCHAR, max_length=2048)
schema.add_field("source", DataType.VARCHAR, max_length=256)

index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector",
index_type="AUTOINDEX",
metric_type="COSINE",
)

client.create_collection(
collection_name=COLLECTION,
schema=schema,
index_params=index_params,
)

# 示例:实际应换真实 embedding
rows = [
{"vector": [0.1] * DIM, "text": "退货 7 天内可退", "source": "policy.txt"},
{"vector": [0.2] * DIM, "text": "包邮门槛 99 元", "source": "policy.txt"},
]
client.insert(collection_name=COLLECTION, data=rows)

query_vec = [[0.15] * DIM]
hits = client.search(
collection_name=COLLECTION,
data=query_vec,
limit=3,
output_fields=["text", "source"],
)
print(hits)

顺序要点:create_collection → insert →(若未随 collection 自动建索引则 create_index)→ load(Lite 常自动)→ search。无 index 就 search 会报错。

与 LangChain 拼装​

PoC 用 Chroma;换 Milvus 通常只改 VectorStore,Loader / Splitter / Retriever 不变。包:langchain-milvus(以官方集成文档为准)。

from langchain_community.document_loaders import TextLoader
from langchain_community.embeddings import FakeEmbeddings
from langchain_milvus import Milvus
from langchain_text_splitters import RecursiveCharacterTextSplitter
from pathlib import Path

embeddings = FakeEmbeddings(size=128) # 上线换真实 Embeddings

docs = []
for path in Path("data").glob("*.txt"):
docs.extend(TextLoader(str(path), encoding="utf-8").load())

splits = RecursiveCharacterTextSplitter(
chunk_size=200, chunk_overlap=40
).split_documents(docs)

vector_store = Milvus.from_documents(
documents=splits,
embedding=embeddings,
connection_args={"uri": "./milvus.db"},
collection_name="langchain_rag",
drop_old=True,
)

retriever = vector_store.as_retriever(search_kwargs={"k": 3})
docs = retriever.invoke("退货几天内可以?")
[LangChain RAG 实践](/docs/ai/RAG/LangChain RAG 实践)LangChain + Milvus
Chroma(persist_directory=...)Milvus(connection_args={"uri": ...})
本地目录持久化Lite 文件或 19530 服务
小 PoC更接近生产的向量库

生成与拒答逻辑直接复用 LangChain 篇的 answer 模板即可。

混合检索(点到为止)​

Milvus 2.x 支持 dense + sparse(如 BM25 内置函数)做混合检索,适合专有名词、编号类 query。配置比单向量复杂,建议 Naive 向量基线评测后再加。详见 Milvus 全文检索文档。

常见坑​

  1. 维度不一致:schema 的 dim 必须与 embedding 输出长度相同。
  2. metric 选错:文本 embedding 多用 COSINE;换模型时确认训练时用的相似度。
  3. 未建 index / 未 load:insert 后 search 失败,先查 index 与 load 状态。
  4. insert 与 query 不是同一 URI:Lite 文件路径或 Docker 地址 ingest / query 必须一致。
  5. 把 Milvus 当 GraphRAG:Milvus 是向量库;全局主题归纳仍见 [GraphRAG 概览与查询](/docs/ai/RAG/GraphRAG 概览与查询)。

与 Chroma / FAISS 对比​

Chroma / 本地 FAISSMilvus
定位轻量 PoC、嵌入式生产级向量库、可扩展
部署进程内 / 本地目录Lite 文件 / Docker / 云
混合检索、分区有限原生支持更强
RAG 教程默认常见默认数据量大时更常见

实践要点​

  1. 先 RAG 落地实践 → [LangChain RAG 实践](/docs/ai/RAG/LangChain RAG 实践),再把 VectorStore 换成 Milvus,改动最小。
  2. 本地用 Milvus Lite(./milvus.db)即可对照学习,不必先搭 K8s。
  3. collection 设计时预留 source、租户 id 等 VARCHAR,便于 RAG 权限过滤(见概念篇失效模式)。
  4. 用同一套 eval_set.jsonl 对比 Chroma vs Milvus 召回,验证迁移未退化。
  5. 面试挂钩:说清 Collection / Index / metric / top-k search,以及 Milvus 在 RAG 流水线中的位置即可。