向量数据库 Milvus:从零搭建 RAG 向量数据库实战

在构建 RAG(检索增强生成)应用时,向量数据库是核心组件之一。本文将带你一步步使用 Milvus 和 LangChain,完成数据库创建、向量存储与相似度检索的全流程。

为什么需要向量数据库?

在 RAG 系统中,我们通常需要将外部知识库(如文档、网页)切分成片段,并通过嵌入模型(Embedding Model)将每个片段转换为高维向量。当用户提问时,同样将问题转为向量,然后在向量数据库中检索最相似的 K 个片段,最后将这些片段作为上下文交给大模型生成答案。

Milvus 是专为 AI 应用设计的开源向量数据库,支持海量向量的高效存储和检索。本文将基于 Milvus 的 Python SDK(pymilvus)和 LangChain 的嵌入模型接口,实战操作整个流程。


1. 环境准备

1.1 安装 Milvus(以Windows环境下通过Docker部署为例)

在这之前要先安装WSL

bash 复制代码
wsl --install

1、先下载dockerDocker官网

2、安装过程无脑下一步就行,安装完后它会提示你要重启电脑才会生效,重启就行。

3、跳过登录,直接进入设置配置镜像或者代理(要有魔法,由于作者没有魔法,此处不讲)。

3.1、镜像 点击上方小齿轮,点击Docker Engine

直接替换即可

json 复制代码
{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "registry-mirrors": [
    "https://docker.dockerimages.jobcher.com",
    "https://docker.xuanyuan.me",
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io"
  ]
}

4、以管理员身份运行powershell(win+x,然后按a进入) 安装到你想安装的地方,我这里是特意创了一个文件夹

下载安装脚本,并将其保存为standalone.bat

bash 复制代码
Invoke-WebRequest https://raw.githubusercontent.com/milvus-io/milvus/refs/heads/master/scripts/standalone_embed.bat -OutFile standalone.bat

等他完成后你的文件夹里就会多一个叫standalone.bat的文件

运行下载的脚本,以 Docker 容器的形式启动 Milvus。

bash 复制代码
.\standalone.bat start

然后就会开始下载Milvus,等他下完就行了,然后docker里就有服务了,服务默认是启动的。

后续你就可以在docker里直接启动和关闭Milvus了

启动后,Milvus 服务会监听 localhost:19530

一脸懵?那就看官方文档在 Docker 中运行 Milvus(Windows) | Milvus 文档 (ps:这就是在官方文档上整下来的)

1.2 安装 Python 依赖

bash 复制代码
pip install pymilvus langchain python-dotenv rich
  • pymilvus:Milvus 官方 Python 客户端。
  • langchain:用于嵌入模型统一接口。
  • python-dotenv:加载环境变量(如 API Key)。
  • rich:美化打印调试信息(可选)。

1.3 获取嵌入模型 API

整一个平台的apikey,找一个嵌入模型,你需要注册并获取 API Key。当然你也可以使用其他兼容 OpenAI API 的嵌入服务。

创建 .env 文件:

env 复制代码
OPENROUTER_API_KEY=your-api-key
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1

2. 连接 Milvus 并创建数据库

2.1 建立客户端连接

python 复制代码
from pymilvus import MilvusClient

client = MilvusClient("http://localhost:19530")
print(client.list_databases())  # 默认有 'default'

2.2 创建自定义数据库(可选)

Milvus 支持多数据库隔离,我们创建一个名为 rag_demo 的数据库:

python 复制代码
db_name = "rag_demo"
existing_dbs = client.list_databases()

if db_name not in existing_dbs:
    client.create_database(db_name)

# 切换到该数据库
client.use_database(db_name)

注意:删除数据库前需确保其中没有 collection,否则会报错。


3. 创建 Collection(表)

Collection 类似于关系数据库中的表,用于存储向量及其元数据。创建时需要指定向量维度(与嵌入模型一致)和相似度度量类型。

3.1 检查并创建 Collection

python 复制代码
collection_name = "docs"
collections = client.list_collections()

if collection_name not in collections:
    client.create_collection(
        collection_name=collection_name,
        dimension=1024,          # bge-m3 的输出维度
        metric_type="COSINE",    # 余弦相似度
    )

关键参数解释

  • dimension:必须与嵌入模型输出维度一致,bge-m3 为 1024。

  • metric_type:相似度计算方法。

    • COSINE(余弦相似度):关注方向,值越接近 1 表示越相似,适合语义检索。
    • L2(欧氏距离):关注距离,值越小越相似。
    • IP(内积):适用于归一化向量。

3.2 查看 Collection 元数据

python 复制代码
from rich import print as rprint

metadata = client.describe_collection(collection_name)
rprint(metadata)

你会看到默认字段:id(主键)、vector(浮点向量),以及动态字段支持(enable_dynamic_field=True),意味着可以插入任意额外字段。


4. 准备嵌入模型

4.1 加载环境变量并初始化

python 复制代码
import os
from dotenv import load_dotenv
from langchain.embeddings import init_embeddings
load_dotenv(override=True)

embedding_model = init_embeddings(
    model="openai:bge-m3",YOUR_
    api_key=os.getenv("OPENROUTER_API_KEY"),
    base_url=os.getenv("OPENROUTER_BASE_URL"),
)

4.2 生成测试文本的向量

我们准备 4 条关于 RAG 和 Milvus 的示例文本:

python 复制代码
texts = [
    "LangChain 是一个用于构建 LLM 应用的开发框架。",
    "Milvus 是一个适合 AI 应用的向量数据库。",
    "RAG 的核心是先检索相关知识,再让大模型生成答案。",
    "Docker Desktop 可以方便地在本地运行 Milvus Standalone。"
]

vectors = embedding_model.embed_documents(texts)
print(len(vectors))       # 4
print(len(vectors[0]))    # 1024

5. 插入数据(Upsert)

构造符合 Milvus 插入格式的数据列表,每个元素是一个字典,包含 idvector 以及自定义字段(textsource)。

python 复制代码
data = [
    {
        "id": i,
        "vector": vectors[i],
        "text": texts[i],
        "source": "demo"
    }
    for i in range(len(texts))
]

insert_res = client.upsert(
    collection_name=collection_name,
    data=data,
)
print(insert_res)  # {'upsert_count': 4, 'ids': [0, 1, 2, 3]}

注意upsert 会插入新数据或更新已存在的 id。数据插入后不会立即持久化到磁盘,可以手动调用 flush 强制落盘:

python 复制代码
client.flush(collection_name=collection_name)

查看集合统计信息,确认行数:

python 复制代码
stats = client.get_collection_stats(collection_name)
print(stats)  # {'row_count': 4}

6. 数据查询与检索

6.1 遍历所有数据(Query Iterator)

使用 query_iterator 分批读取数据,适合大数据量场景:

python 复制代码
iterator = client.query_iterator(
    collection_name=collection_name,
    output_fields=["*"]   # 返回所有字段
)

i = 0
while True:
    rows = iterator.next()
    if not rows:
        break
    for row in rows:
        print(f"第{i+1}条数据")
        print(f"id:{row['id']}, text:{row['text']}, source:{row['source']}")
        i += 1
iterator.close()

6.2 通过主键批量查询

python 复制代码
res = client.get(
    collection_name=collection_name,
    ids=[0, 1, 3]
)
print(len(res))  # 3

6.3 相似度检索(核心功能)

当用户提出问题时,将问题向量化,然后在 Milvus 中搜索最相似的 Top-K 片段。

python 复制代码
query = "什么是向量数据库?"
query_vector = embedding_model.embed_query(query)

search_res = client.search(
    collection_name=collection_name,
    data=[query_vector],          # 支持批量,这里单个
    limit=3,                      # 返回前 3 个最相似结果
    output_fields=["text", "id"], # 返回的额外字段
)

for hit in search_res[0]:
    print(hit)

输出示例:

json 复制代码
{
  "id": 1,
  "distance": 0.602188,
  "entity": {
    "id": 1,
    "text": "Milvus 是一个适合 AI 应用的向量数据库。"
  }
}
  • distance 即余弦相似度得分,值越高越相关。可以看到与"向量数据库"最匹配的是第 1 条(Milvus 描述),其次是 RAG 和 Milvus Standalone 相关文本,而 LangChain 描述得分较低,符合语义预期。

7. 清理资源(可选)

如果不再需要该 collection 或 database,可以删除:

python 复制代码
# 删除 collection(需先确认无查询)
client.drop_collection(collection_name)

# 删除 database(需先删除其中的所有 collection)
client.drop_database(db_name)

8. 注意!

  1. 维度必须一致 :创建 collection 时的 dimension 必须与嵌入模型输出维度严格匹配,否则插入会报错。
  2. 度量类型选择 :RAG 场景推荐使用 COSINE,因为语义相似度通常用余弦衡量。
  3. 动态字段 :启用 enable_dynamic_field=True(默认开启)后,可以任意添加字段,无需提前定义 schema,非常灵活。
  4. 批量操作:插入和搜索均支持批量,能有效提升吞吐量。
  5. 索引构建:本示例使用默认索引(FLAT),生产环境建议根据数据量创建 IVF 或 HNSW 索引以加速检索,但本文未展开。

9. 总结

通过本文的实战,你已经掌握了:

  • 使用 Docker 运行 Milvus Standalone。
  • 通过 pymilvus 连接、创建数据库和 collection。
  • 利用 LangChain 统一接口调用嵌入模型(OpenRouter bge-m3)。
  • 插入向量数据并执行相似度检索。

这构成了 RAG 系统的数据层基础。接下来,你可以将检索到的文本片段与 LLM 结合,实现完整的问答应用。


延伸阅读

相关推荐
wangruofeng1 小时前
从 QQ 机器人到多租户 Agent 平台,LangBot 用一条流水线接住了 17 个 IM
aigc·agent·ai编程
春水碧于天,画船听雨眠1 小时前
LangChain学习笔记(二)
笔记·学习·langchain
大地之灯1 小时前
从零做一个自己的 CLI
python·agent
2601_955759621 小时前
企业 Claude API 用量峰值管理实战
数据库
孙启超1 小时前
【AI应用开发】怎么降低 Agent 幻觉?有几种可行方案?
大数据·人工智能·llm·agent·rag·幻觉·ai应用开发
酱学编程2 小时前
Harness Engineering - 是什么、怎么设计、往哪走
ai·agent·harness
runningshark2 小时前
DeepSeek V4 Flash 0423 实效评测与能力全景
大数据·数据库
武子康2 小时前
GPT-5.6 Sol 的 ARC-AGI-3 分数为何翻近三倍:Agent 评测必须记录整套运行合同
人工智能·chatgpt·agent
weixin_431600442 小时前
做 Agent 会用到的 Node API(4):取消与 AbortController
前端·学习·ai·agent·ai编程