LangChain — RAG 构建知识库(实操)

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

LangChain — RAG 构建知识库(理论)
Python 项目部署(Linux)
各大向量数据库对比(Vector Database)

环境要求

  • 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

初始项目

D:\OpenSource\Python\VipRAG>uv --version
uv 0.9.18 (0cee76417 2025-12-16)

D:\OpenSource\Python\VipRAG>uv python install 3.12
Python 3.12 is already installed

D:\OpenSource\Python\VipRAG>uv init -p 3.12
Initialized project `deploydemo`

D:\OpenSource\Python\VipRAG>uv run main.py
Using CPython 3.12.12
Creating virtual environment at: .venv
Hello from viprag!

D:\OpenSource\Python\VipRAG>

本地开发

uv sync
uv run pytest -q
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

posted @ 2026-08-06 15:47  VipSoft  阅读(5)  评论(0)    收藏  举报