LangChain — RAG 知识库(实操)

目录

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 - 文档知识库 用代码手搓了一遍

text 复制代码
知识库构建 → 上传 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秒钟

状态变化为:

text 复制代码
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

powershell 复制代码
uv sync
uv run uvicorn app.main:app --reload

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

powershell 复制代码
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

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

返回:

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

Worker 解析文档

切块后入Qdrant向量库

查询文档状态

powershell 复制代码
curl.exe "http://localhost:8000/api/v1/documents/{document_id}"

用户提问

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

源码地址

https://gitee.com/VipSoft/VipRAG

相关推荐
云烟成雨TD6 小时前
LlamaIndex 系列【31】检索增强策略:命名实体识别(NER)
ai·agent·rag·llamaindex
染指111011 小时前
119.Agent-LangChain核心组件-Runtime运行时
人工智能·langchain·agent
Experience-摆渡11 小时前
开源RAG知识库WeKnora深度调研:让知识自己长成体系
爬虫·docker·开源·rag
用户31346721435414 小时前
Agent 开发学习笔记(六):LCEL:把组件串成链
langchain·agent
艾醒(AiXing-w)15 小时前
LangChain 1.0 智能体开发(三):Agent 记忆管理——从短期对话到跨会话长期记忆
数据库·人工智能·langchain
东莞市云毅网络有限公司17 小时前
用 SQLite FTS5 给企业文档建本地全文索引:中文分词与权重调优
python·数据清洗·rag·企业知识库·文档解析
霸道流氓气质18 小时前
RAG检索增强:12种Chunking策略深度对比
rag
云烟成雨TD18 小时前
LlamaIndex 系列【29】检索增强策略:路由(Routing)机制
ai·agent·rag·llamaindex
KimLiu19 小时前
LCODER之AI Agent开发实战一 :问数项目智能体搭建(3)元数据知识库的构建
langchain·llm·agent
烛之武19 小时前
LangChain笔记
langchain·大模型·agent·mcp