惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
GbyAI
GbyAI
S
SegmentFault 最新的问题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Visual Studio Blog
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
B
Blog
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
雷峰网
雷峰网
爱范儿
爱范儿
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
U
Unit 42
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
P
Proofpoint News Feed
A
About on SuperTechFans
I
InfoQ
F
Fortinet All Blogs
L
LangChain Blog
T
Tailwind CSS Blog

博客园 - VipSoft

FastAPI 全局 HTTP 异常处理器 + 统一响应封装 SpringBoot 心跳日志不记录 access.log Qdrant Linux 安装(非Docker) LangChain — RAG 构建知识库(理论) LangChain — RAG 构建知识库(实操) Python PyCharm 运行,取不到 .env 文件中的值 Qdrant 安装(Windows) LangChain — RAG 构建知识库 Python 项目简单部署(Linux) MinerU - 将非结构化文档(PDF、图片、Office 文件等)转换为机器可读的 Markdown 和 JSON LangChain 入门 服务端部署-FastAPI LangChain 入门 LangSmith LangChain 入门 实战 - 食谱推荐 LangChain 入门 Memory 会话记忆 LangChain 入门 Tools 工具 LangChain 入门 Tools 工具 LangChain 入门 Prompts 提示词 LangChain 入门 Message 消息 LangChain 入门 Model 的初始化和调用 LangChain 入门 Agent 的基本运行机制 AI 0基础学习,名词解析 LangChain 和 LangGraph AI大模型知识体系 Dify — Workflow - 数据可视化 Dify — 连接MySQL配置 Dify — Chatflow - 数据库智能查询 Dify — Chatflow - 文档知识库 Dify — Agent 智能体 高安全券码、注册码生成 Dify — 文本生成应用
LangChain — RAG 知识库(实操)
VipSoft · 2026-08-10 · via 博客园 - VipSoft

VipRAG 是一个面向小规模正式服务的中文医学指南检索增强生成(RAG)项目。系统使用在线 MinerU 解析 PDF、DashScope 生成文本向量、Qdrant 检索、MySQL 保存文档与任务 状态,并通过千问生成带来源的回答。以《中国心血管病风险评估和管理指南.pdf》做为知识库,构建RAG系统,模拟生产环境,部署成多人使用、长期运行的 FastAPI 服务,直接采用 Qdrant 向量库

LangChain — RAG 构建知识库(理论)
Python 项目部署(Linux)
各大向量数据库对比(Vector Database)
Dify — Chatflow - 文档知识库 -- 本文是它的代码版

环境要求

  • Python 3.12+
  • MySQL 5.7
  • Qdrant v1.18.3
  • MinerU API 令牌
  • DashScope API 密钥,供文本嵌入和千问使用

项目不需要 GPU

项目构建

项目分两个部分知识库构建用户问答
可以理解成,把上次搞的 Dify — Chatflow - 文档知识库 用代码手搓了一遍

知识库构建 → 上传 PDF → FastAPI → MySQL ingestion_job
                                      ↓
                                 独立 Worker
                                      ↓
                           MinerU API → Markdown 缓存
                                      ↓
                          LangChain 切分 → DashScope Embeddings
                                      ↓
                                   Qdrant

用户问题 → DashScope Embeddings → Qdrant 检索 → 千问 → 答案与来源

FastAPI 和入库工作进程是两个独立进程。PDF 解析不会占用 API 请求,也不会因 API 重启而丢失。MinerU 返回的 ZIP 和 Markdown 会保存在 data,重新向量化时无需 再次消耗 MinerU 额度。

知识库构建

FastAPI

  1. 上传文件
  2. 生成以 document_id (UUID) 命名的目录,用于存放文件
  3. 将文件流存到 documents/document_id 目录中
  4. 计算 SHA-256 去重
  5. 验证 PDF 签名
  6. 调用 repository 保存元数据, ingestion_jobs.status = JobStatus.PENDING 供 独立Worker切片

独立 Worker

  1. 读取 .env 配置
  2. 构建 Qdrant Client、Embedding、Qwen、MinerU 等对象
  3. 创建 data 数据目录、MySQL 表结构
  4. 任务处理(将文档切分成文本块,存入向量库)
    4.1 查询 ingestion_jobs 表 status=PENDING 且 attempts < max_attempts 的待处理记录(job),按时间排序,取最早的一个进行后续处理
    4.2 根据 job.document_id 查询 documents 表,形成 JobWorkItem 对象。并将 ingestion_jobs、documents 表字段 status 标记成 PROCESSING,如果没查到将该job记录标记成 job.status = JobStatus.FAILED,
    4.3 调用 MinerU 解析 PDF → 得到 Markdown、Archive -> 存到 data/documents 目录: full.md、mineru-result.zip
    4.4 将 Markdown 通过递归字符切分(RecursiveCharacterTextSplitter)切分成文本块(Chunks)
    4.5 调用 Embedding 模型(text-embedding-v4)生成向量
    4.6 将文本块、向量,构建成 points 存入 Qdrant 向量数据库
    4.7 将 ingestion_jobs 任务数据状态标记成 JobStatus.SUCCEEDED
  5. 如果第4步处理失败,并且没有达到重试上限,将 status 设成 PENDING,如果达到重试上限,status 设成 FAILED,该任务不再继续
  6. 继续任务处理(重复第4步),如果没有任务停N秒钟

状态变化为:

pending → processing → indexing → ready
                              ↘ failed

只有状态为 ready 的文档才应视为可查询。重复上传内容完全相同的 PDF 会根据SHA-256 返回已有文档,不会再次调用 MinerU。

用户问答

  1. 问题向量化 ──► embed_query(question)
  2. 向量检索 ──► search(knowledge_base_id, query_vector, top_k)
  3. 上下文裁剪 ──► fit_context(chunks) [控制token长度]
  4. 构建提示 ──► build_context(selected)
  5. 千问生成答案 ──► generate(question, context)
  6. 返回结果 + 来源标注

数据模型

MySQL 保存 knowledge_basesdocumentsingestion_jobs。文档由知识库与SHA-256 共同标识,因此重复上传具有幂等性。文档状态在 pendingprocessingindexingreadyfailed 之间转换。任务保留供应商任务 ID、尝试次数和经过清理的错误信息。

每个 Qdrant 点包含分块文本以及 knowledge_base_iddocument_iddocument_versionfilenametitle_path、MinerU 提供时的页码信息、chunk_indexcontent_hashstatus。检索按知识库和 status=active 过滤。

组件

  • config: 验证环境配置且不暴露密钥。
  • database: 管理异步 SQLAlchemy 引擎、会话和 MySQL 模型。
  • documents: 接收 PDF、计算内容哈希、创建幂等入库任务并报告任务状态。
  • mineru: 向 MinerU 提交本地 PDF、轮询异步任务、下载并解压 Markdown 结果,
    将供应商失败映射为领域错误。
  • ingestion: 领取任务、持久化解析产物、切分 Markdown、批量生成向量、向 Qdrant
    更新或插入点,并发布文档版本。
  • retrieval: 对问题生成向量,并仅检索指定知识库中的活动分块。
  • generation: 构建受约束的医学指南提示词并调用 Qwen。
  • api: 将领域结果和失败转换为稳定的 HTTP 响应。

UV安装

忽略安装过程,Windows可参考: Windows 安装 UV

项目运行

运行 FastAPI

uv sync
uv run uvicorn app.main:app --reload

另开终端启动入库工作进程:

uv run python -m app.worker

本地直接运行时需要自行启动 MySQL 和 Qdrant,并将 .env 中的主机名从 Compose
服务名改为本机地址。

API

方法 路径 用途
GET /health/live 进程存活检查
GET /health/ready 运行时依赖已装配
POST /api/v1/knowledge-bases/{id}/documents 上传 PDF
GET /api/v1/documents/{id} 查询入库状态
POST /api/v1/answer 检索并生成回答

上传文件

{knowledge_base_id} 用户自己定义 如:cardiovascular

curl.exe -X POST "http://localhost:8000/api/v1/knowledge-bases/{knowledge_base_id}/documents" `
  -F "file=@app/resources/中国心血管病风险评估和管理指南.pdf;type=application/pdf"

image
返回:

{
    "document_id": "b86beaf7-fe81-4ed8-8492-9fb7dfafdb39",
    "knowledge_base_id": "vipsoft",
    "filename": "中国心血管病风险评估和管理指南.pdf",
    "status": "pending",
    "version": 1,
    "created": true,
    "error_message": null
}

Worker 解析文档

image
切块后入Qdrant向量库
image

查询文档状态

curl.exe "http://localhost:8000/api/v1/documents/{document_id}"

image

用户提问

curl.exe -X POST "http://localhost:8000/api/v1/answer" `
  -H "Content-Type: application/json" `
  -d '{"knowledge_base_id":"{knowledge_base_id}","question":"心血管疾病膳食营养有哪些?"}'

image

源码地址

https://gitee.com/VipSoft/VipRAG