在 AI 知识库、RAG(Retrieval-Augmented Generation)以及智能问答系统开发过程中,向量数据库是核心组件之一。
Milvus 作为目前主流的开源向量数据库,能够高效完成海量向量的存储与相似度检索。本文基于 FastAPI 项目实践,封装一个通用的 MilvusUtil 工具类,实现知识库数据的批量插入、向量搜索、课程知识删除以及条件查询等功能。
功能设计
本工具类主要实现以下功能:
- 批量插入知识库数据
- 向量相似度检索
- 按课程删除知识数据
- 按课程查询知识数据
- 统一封装 Milvus 操作接口
知识库集合名称:
COLLECTION_NAME = "knowledge_base"
集合中主要字段包括:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| course_id | VARCHAR | 课程ID |
| content | VARCHAR | 文本内容 |
| embedding | FLOAT_VECTOR | 向量数据 |
| create_time | INT64 | 创建时间 |
| chunk_index | INT64 | 文档块序号 |
安装milvus
python
pip install pymilvus
封装连接milvus工具
python
from pymilvus import MilvusClient
from dotenv import load_dotenv
import os
load_dotenv()
client = MilvusClient(
uri=os.getenv("MILVUS_URI"),
user=os.getenv("MILVUS_USER"),
password=os.getenv("MILVUS_PASSWORD"),
db_name="ai_education"
)
if __name__ == "__main__":
print(client.describe_collection("knowledge_base"))
查询、删除封装工具
python
from app.config import client
import time
COLLECTION_NAME = "knowledge_base"
class MilvusUtil:
@staticmethod
def insert_data(course_id: str, text_chunks: list[str], vectors: list[list[float]]):
"""
将文档分块及对应向量批量插入 knowledge_base 集合。
:param course_id: 所属课程ID
:param text_chunks: 文本分块列表
:param vectors: 每个文本块对应的向量列表(维度1024),与 text_chunks 一一对应
:return: Milvus 插入结果(含插入条数等信息)
"""
now = int(time.time() * 1000)
data = []
for i, (text, vector) in enumerate(zip(text_chunks, vectors)):
data.append({
"course_id": course_id,
"content": text,
"embedding": vector,
"create_time": now,
"chunk_index": i
})
res = client.insert(
collection_name=COLLECTION_NAME,
data=data
)
return res
@staticmethod
def search(vector: list[float], top_k: int = 5, course_id: int = None):
"""
根据向量在 knowledge_base 中进行相似度检索。
:param vector: 查询向量(维度1024)
:param top_k: 返回最相似的 Top K 条结果,默认5条
:param course_id: 可选,限定在指定课程范围内检索;为 None 时全局检索
:return: Milvus 检索结果列表
"""
filter_expr = f"course_id == {course_id}" if course_id else None
res = client.search(
collection_name=COLLECTION_NAME,
data=[vector],
limit=top_k,
filter=filter_expr,
output_fields=["course_id", "content", "chunk_index", "create_time"]
)
return res
@staticmethod
def delete_by_course(course_id: int):
"""
删除指定课程下的所有知识条目。
:param course_id: 要删除的课程ID
:return: Milvus 删除结果
"""
res = client.delete(
collection_name=COLLECTION_NAME,
filter=f"course_id == {course_id}"
)
return res
@staticmethod
def query_by_course(course_id: int, limit: int = 10):
"""
按课程ID查询知识条目(非向量检索,直接按条件过滤)。
:param course_id: 要查询的课程ID
:param limit: 返回条数上限,默认10条
:return: 符合条件的知识条目列表
"""
res = client.query(
collection_name=COLLECTION_NAME,
filter=f"course_id == {course_id}",
limit=limit,
output_fields=["course_id", "content", "chunk_index", "create_time"]
)
return res
功能介绍
1. 批量插入知识库数据
在完成文档切分和 Embedding 向量生成后,可通过 insert_data() 方法批量写入 Milvus。
实现流程:
- 接收课程ID
- 接收文本分块列表
- 接收对应向量列表
- 组装数据结构
- 批量写入 Milvus
优势:
- 减少网络请求次数
- 提高写入效率
- 保证文本与向量一一对应
2. 向量相似度检索
用户提问后:
- 调用 Embedding 模型生成问题向量
- 执行 Milvus Search
- 返回 TopK 最相似知识片段
支持:
- 全库检索
- 指定课程检索
- 自定义返回数量
典型场景:
- AI 问答
- RAG 检索增强
- 企业知识库
- 智能客服
3. 删除课程知识库
当课程内容更新时,需要删除旧数据重新导入。
通过课程 ID 直接执行:
python
delete_by_course(course_id)
即可快速删除该课程下的所有知识块。
- 条件查询
除了向量搜索外,也可以通过课程 ID 直接查询知识内容:
python
query_by_course(course_id)
适用于:
- 后台管理系统
- 知识库列表展示
- 数据检查与调试