向量数据库Milvus本地搭建私有问答库:零基础完整教程
为什么需要本地私有问答库
很多场景下,你希望用自己的文档(如公司手册、技术文档或笔记)搭建一个问答机器人,但数据敏感不能上传到云端。
向量数据库Milvus能帮你在本地存储文档的向量表示,再配合嵌入模型(如all-MiniLM-L6-v2)和检索接口,就能实现基于语义的私有问答搜索。
本文从零开始,带你走通Milvus本地搭建私有问答库的全流程。
1. 搭建前的软硬件准备
- 一台Linux服务器或本地虚拟机(推荐Ubuntu 20.04/22.04,内存至少4GB,磁盘20GB以上)
- 安装Docker和Docker Compose(用于快速启动Milvus)
- Python 3.8及以上环境(用于编写数据导入和查询脚本)
- 网络畅通,能拉取Docker镜像和Python包
检查Docker是否已安装:
docker --version
如果未安装,参考官方文档一键安装:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
2. 使用Docker快速启动Milvus服务
Milvus官方提供了基于Docker Compose的部署文件,包含MinIO(对象存储)和etcd(元数据存储)。
我们直接用官方推荐方式启动:
# 下载Milvus standalone的docker-compose文件
wget https://github.com/milvus-io/milvus/releases/download/v2.4.6/milvus-standalone-docker-compose.yml -O docker-compose.yml
# 启动服务(需要sudo权限)
sudo docker-compose up -d
等待几分钟,检查容器状态:
sudo docker-compose ps
看到三个容器(etcd、minio、milvus)状态均为Up,说明启动成功。
Milvus默认监听19530端口,后续程序通过该端口连接。
3. 准备文档数据并生成向量
我们需要将本地文档(如TXT或PDF)切分成段落,并调用嵌入模型转换成向量。
这里以简单的TXT文件为例,使用sentence-transformers库生成384维向量。
安装依赖:
pip install pymilvus sentence-transformers
创建一个Python脚本prepare_data.py:
from sentence_transformers import SentenceTransformer
import os
# 加载轻量级嵌入模型(首次运行会自动下载)
model = SentenceTransformer('all-MiniLM-L6-v2')
# 读取文档(这里假设有一个my_doc.txt,每行一条段落)
with open('my_doc.txt', 'r', encoding='utf-8') as f:
paragraphs = [line.strip() for line in f if line.strip()]
# 生成向量
embeddings = model.encode(paragraphs, show_progress_bar=True)
print(f"已生成 {len(embeddings)} 个向量,维度 {embeddings.shape[1]}")
4. 向Milvus创建集合并插入数据
随后连接Milvus,创建一个名为private_qa的集合,并插入段落文本和向量。
创建insert_to_milvus.py:
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection, utility
# 连接Milvus
connections.connect(host='localhost', port='19530')
# 定义集合结构
fields = [
FieldSchema(name='id', dtype=DataType.INT64, is_primary=True, auto_id=False),
FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, dim=384),
FieldSchema(name='text', dtype=DataType.VARCHAR, max_length=512)
]
schema = CollectionSchema(fields=fields, description='private qa collection')
collection_name = 'private_qa'
# 如果集合已存在则删除
if utility.has_collection(collection_name):
Collection(collection_name).drop()
collection = Collection(name=collection_name, schema=schema)
print(f"集合 {collection_name} 创建成功")
# 准备数据(假设paragraphs和embeddings已从上一步获取)
from prepare_data import paragraphs, embeddings
ids = list(range(len(paragraphs)))
entities = [ids, embeddings, paragraphs]
insert_result = collection.insert(entities)
print(f"插入了 {len(insert_result.primary_keys)} 条数据")
# 创建索引(加速搜索)
index_params = {
'metric_type': 'COSINE', # 余弦相似度
'index_type': 'IVF_FLAT',
'params': {'nlist': 128}
}
collection.create_index(field_name='embedding', index_params=index_params)
# 加载集合到内存
collection.load()
print("数据加载完成,等待查询")
5. 实现私有问答搜索
写一个查询脚本search_qa.py,接收用户问题,生成向量后在Milvus中检索最相似的段落:
from pymilvus import Collection, connections
from sentence_transformers import SentenceTransformer
connections.connect(host='localhost', port='19530')
collection = Collection('private_qa')
collection.load()
model = SentenceTransformer('all-MiniLM-L6-v2')
question = "Milvus支持哪些索引类型?"
question_vec = model.encode([question])[0]
search_params = {
'metric_type': 'COSINE',
'params': {'nprobe': 16}
}
results = collection.search(
data=[question_vec],
anns_field='embedding',
param=search_params,
limit=3,
output_fields=['text']
)
for hits in results:
for hit in hits:
print(f"相似度 {hit.score:.4f} -> {hit.entity.get('text')}")
运行python search_qa.py,看到输出结果即验证成功。
6. 常见问题与避坑
- docker-compose命令找不到:安装Docker Compose插件,或者改用
docker compose(新版本) - 连接Milvus失败:检查防火墙是否开放19530端口,或使用
sudo ufw allow 19530 - 内存不足导致容器闪退:确认主机内存至少4GB,可调整docker-compose中etcd和Milvus的资源限制
- 向量维度不匹配:确保嵌入模型输出的维度与集合定义的dim一致(这里384)
- 无法下载模型:先手动下载sentence-transformers模型文件到本地缓存,或设置代理
7. 效果验证与扩展
运行查询脚本后,你应该能看到与问题语义相关的前3个段落。
可以进一步集成一个简单的Web界面(如Flask)或接入大模型做生成式回答。
本文的Milvus本地搭建私有问答库方案完全离线,数据不离开你的服务器。
如果你在操作中遇到其他报错,欢迎留言讨论。
记住,搭建完成后建议定期备份Milvus数据目录(默认挂载卷的数据),防止意外丢失。