FastAPI 实战:封装 Milvus 向量数据库工具类,实现知识库增删查检索

在 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)

即可快速删除该课程下的所有知识块。

  1. 条件查询

除了向量搜索外,也可以通过课程 ID 直接查询知识内容:

python 复制代码
query_by_course(course_id)

适用于:

  • 后台管理系统
  • 知识库列表展示
  • 数据检查与调试