基于 RAG(检索增强生成)的知识库问答系统,上传 PDF/Word 文档后,可以针对文档内容提问,答案附带引用溯源。
- 完整 RAG 流水线:文档解析 → 按标题分块 → 向量化 → 混合检索 → 重排序 → 生成
- 混合检索:BM25(关键词)+ 向量(语义)双路召回,RRF 融合排名
- Rerank 重排序:召回 top10 候选,LLM 精排 top3,提升答案精度
- 引用溯源:每个答案标注引用了哪些文档片段
- 本地 embedding:sentence-transformers 本地模型,免费、离线可用
| 上传文档 | 提问 | 答案 + 引用来源 |
|---|---|---|
| PDF/Word/TXT/Markdown | 自然语言提问 | 答案 + 命中的文档片段 |
# 1. 安装依赖
pip install -r requirements.txt
# 2. 配置 .env(填入 DeepSeek API Key)
cp .env.example .env
# 编辑 .env,填入 DEEPSEEK_API_KEY=sk-xxx
# 3. 运行
python app.py
# 打开 http://127.0.0.1:5001上传文档
↓ 解析(pypdf / python-docx)
↓ 分块(按 markdown 标题分块)
↓ 向量化(sentence-transformers 本地 embedding)
↓ 存入向量库(Chroma)
提问
↓ 第一轮:粗筛(混合检索:BM25 + 向量 + RRF 融合,召回 top10)
↓ 第二轮:精排(LLM Rerank,挑出最相关的 top3)
↓ 第三轮:生成(LLM 基于 3 个片段回答)
↓ 输出:答案 + 引用溯源
doc-qa/
├── rag/
│ ├── doc_loader.py # 文档解析 + 按标题分块
│ ├── vector_store.py # 向量化 + BM25 + 混合检索(RRF)
│ └── qa_chain.py # 检索 + Rerank + 生成(RAG 核心)
├── app.py # Flask 后端(端口 5001)
├── frontend/ # Element UI 界面
├── test_docs/ # 测试文档
└── requirements.txt
| 层 | 技术 |
|---|---|
| 文档解析 | pypdf / python-docx |
| 分块 | 按 markdown 标题分块 |
| Embedding | sentence-transformers(本地) |
| 向量库 | Chroma |
| 关键词检索 | BM25(rank-bm25 + jieba 分词) |
| 融合 | RRF(Reciprocal Rank Fusion) |
| 重排序 | LLM-as-Reranker |
| 生成 | DeepSeek LLM |
| 后端 | Flask |
- 为什么按标题分块? 结构化文档(制度/手册)每个章节是独立主题,按标题分块让每块语义清晰,检索精度远高于固定长度分块。
- 为什么要混合检索? 向量检索擅长"意思相近"(年假≈休假),BM25 擅长"精确匹配"(数字"5000"),两者取长补短。
- 为什么要 Rerank? 第一轮检索是"双塔"粗筛(问题和文档各自编码),Rerank 让 LLM 同时看问题和候选做精细比较,提升精度。
内置测试文档 test_docs/公司制度大全.md(8 章员工制度),可以测试:
- "报销超过多少钱需要双重审批" → 超过 5000 元需要双重审批
- "入职满五年有几天年假" → 15 天带薪年假
- "离职要提前多久通知" → 正式员工 30 天,试用期 3 天
