项目总览:EduRAG智慧问答系统

传智教育 EduRAG 智慧问答系统

基于 RAG(Retrieval-Augmented Generation,检索增强生成)的 IT 教育领域智能问答系统。系统融合传统检索、向量检索与大语言模型,面向黑马程序员(传智教育)的课程咨询场景,支持多模态文档接入、流式问答与对话历史管理。

Rag的作用

i. 解决知识时效性问题
ii. 减少幻觉(Hallucination)
iii. 领域适应性更强
iv. 数据隐私与可控性
v. 成本与效率优化
vi. 可解释性提升


一、项目简介

本项目面向 IT 教育咨询场景,能够针对用户提问,按"精确匹配 → 知识库检索 → 通用大模型"的优先级给出回答,并支持流式输出、多轮对话、学科过滤与效果评估。系统同时是一个面向教学的 RAG 完整链路示例,涵盖文档加载、分层切块、混合检索、重排序、意图识别、策略路由、效果评估等关键环节。

核心特性

  • 三层问答架构:BM25 + Redis/MySQL 精确匹配 → 向量 RAG 检索 → LLM 通用知识兜底
  • 多模态文档加载:PDF(含 OCR)、PPT/PPTX、DOCX、图片(OCR)、Markdown、TXT
  • 分层切块(父子块):父块提供上下文,子块用于精准检索
  • 混合检索 + 重排序:BGE-M3 稠密 + 稀疏向量混合检索,BGE-Reranker 重排序
  • 查询意图分类:基于 BERT 微调的二分类(通用知识 / 专业咨询)
  • 多检索策略:直接检索、HyDE 假设问题、子查询拆分、回溯问题简化(由 LLM 自动选择)
  • 流式输出:基于 WebSocket 的逐 Token 流式回答
  • 对话历史:MySQL 持久化,保留最近 5 轮上下文
  • 学科过滤:支持 ai / java / test / ops / bigdata 等学科过滤
  • 效果评估:集成 RAGAS 进行忠实度、答案相关性等指标评估
  • 性能测试:基于 Locust 的 HTTP 与 WebSocket 压测

二、系统架构

用户提问
┌──────────────────────────────────────────────────────────┐
│ 第一层:日常问候识别 (正则模板匹配)                          │
│   命中 → 直接返回模板回复                                   │
└──────────────────────────────────────────────────────────┘
   │ 未命中
┌──────────────────────────────────────────────────────────┐
│ 第二层:BM25 + Redis/MySQL 精确匹配                        │
│   Redis 缓存命中 / BM25 softmax 相似度 ≥ 阈值 → 返回答案    │
└──────────────────────────────────────────────────────────┘
   │ 未找到可靠答案
┌──────────────────────────────────────────────────────────┐
│ 第三层:RAG 系统                                            │
│  1. BERT 意图分类 (通用知识 / 专业咨询)                      │
│     ├─ 通用知识 → 直接调用 LLM                              │
│     └─ 专业咨询 ↓                                          │
│  2. LLM 策略选择 (直接 / HyDE / 子查询 / 回溯)               │
│  3. BGE-M3 混合检索 (稠密 + 稀疏) → BGE-Reranker 重排序      │
│  4. 组装 Prompt (上下文 + 历史 + 问题) → LLM 流式生成         │
└──────────────────────────────────────────────────────────┘

三、项目结构

Itcast_qa_system/
├── app.py                      # FastAPI 服务入口 (HTTP + WebSocket)
├── new_main.py                 # 集成问答系统 + CLI 交互入口
├── config.ini                  # 配置文件 (MySQL/Redis/Milvus/LLM/检索参数)
├── requirements-windows.txt    # Windows 依赖
├── requirements-mac.txt        # Mac 依赖
├── locust_test.py              # Locust 性能测试脚本

├── base/                       # 基础模块
   ├── config.py               #   配置加载 (读取 config.ini)
   └── logger.py               #   日志配置

├── mysql_qa/                   # 第二层:BM25 精确匹配问答
   ├── db/mysql_client.py      #   MySQL 客户端 (问题/答案存取)
   ├── cache/redis_client.py   #   Redis 客户端 (缓存问答与分词结果)
   ├── retrieval/bm25_search.py#   BM25 检索 (softmax 归一化 + 阈值过滤)
   ├── utils/preprocess.py     #   文本预处理 (分词)
   ├── data/JP学科知识问答.csv #   学科问答原始数据
   └── sql_main.py             #   独立 MySQL 问答入口

├── rag_qa/                     # 第三层:RAG 检索增强生成
   ├── rag_main.py             #   RAG 独立入口 (数据处理/查询模式)
   ├── core/                   #   RAG 核心逻辑
      ├── rag_system.py       #     RAG 系统 (非流式版本)
      ├── new_rag_system.py   #     RAG 系统 (流式 + 对话历史版本)
      ├── vector_store.py     #     向量存储 (Milvus 混合检索 + 重排序)
      ├── document_loader.py  #     文档加载入口 (按扩展名分发)
      ├── document_processor.py#    文档分层切块 (父块/子块)
      ├── query_classifier.py #     BERT 查询意图分类器 (含训练)
      ├── strategy_selector.py#     LLM 检索策略选择器
      ├── prompts.py          #     Prompt 模板 (RAG/HyDE/子查询/回溯)
      ├── train_bert.py       #     BERT 分类模型训练脚本
      ├── bert_query_classifier/ #  微调后的 BERT 意图分类模型
      └── output/             #     训练 checkpoint
   ├── edu_document_loaders/   #   多模态文档加载器
      ├── edu_pdfloader.py    #     PDF 加载 (PyMuPDF + OCR)
      ├── edu_pptloader.py    #     PPT/PPTX 加载
      ├── edu_docloader.py    #     DOCX 加载 + OCR 工具
      └── edu_imgloader.py    #     图片加载 (OCR)
   ├── edu_text_spliter/       #   文本切分器
      ├── edu_chinese_recursive_text_splitter.py  # 中文递归切分
      └── edu_model_text_spliter.py               # 模型切分 (BERT 文档分割)
   ├── models/                 #   预训练模型
      ├── bge-m3/             #     BGE-M3 嵌入模型 (稠密+稀疏)
      ├── bge-reranker-large/ #     BGE-Reranker 重排序模型
      └── nlp_bert_document-segmentation_chinese-base/  # 文档分割模型
   ├── classify_data/          #   意图分类训练数据 (大模型生成)
   ├── rag_assesment/          #   RAGAS 效果评估
      ├── ragas_evaluate.py   #     RAGAS 评估脚本
      └── rag_evaluate_data.json
   └── data/                   #   RAG 知识库源文档
       ├── ai_data/            #     AI 学科资料 (PDF/MD)
       └── samples/            #     多模态样本 (PDF/PPTX/DOCX/PNG/ZIP)

├── static/                     # 前端页面
   ├── index.html              #   问答 Web 界面
   └── src/App.jsx             #   React 组件

├── docker/                     # Docker 编排
   ├── milvus_redis/docker-compose.yml  # Milvus + etcd + minio + Redis
   └── mysql/docker-compose.yml         # MySQL

├── logs/                       # 运行日志
├── demo/                       # 教学示例 (FastAPI/Logging/Redis)
└── notebooks/                  # Jupyter 笔记本 (模型/工具探索)

四、技术栈

类别 技术 / 模型
Web 框架 FastAPI + Uvicorn + WebSocket
大语言模型 阿里云 DashScope(通义千问 Qwen 系列,OpenAI 兼容接口)
向量数据库 Milvus 2.4
嵌入模型 BGE-M3(稠密 + 稀疏 + ColBERT,1024 维)
重排序模型 BGE-Reranker-Large(CrossEncoder)
意图分类 BERT(bert-base-chinese 微调,2 分类)
文档分割 nlp_bert_document-segmentation_chinese-base
关系数据库 MySQL(问答库 + 对话历史)
缓存 Redis(问答缓存 + 分词缓存)
OCR RapidOCR(onnxruntime / paddle)
文档解析 PyMuPDF、python-pptx、python-docx
检索算法 rank-bm25(BM25Okapi)
效果评估 RAGAS
性能测试 Locust
前端 HTML + React(App.jsx)

五、环境准备

1. Python 依赖

# Windows
pip install -r requirements-windows.txt

# macOS
pip install -r requirements-mac.txt

2. 基础服务部署

使用 Docker Compose 启动 Milvus、Redis、etcd、MinIO:

cd docker/milvus_redis
docker-compose up -d

MySQL 可使用本地实例或自行通过 docker/mysql/docker-compose.yml 启动。

3. 配置文件

编辑根目录 config.ini,按需修改:

  • [mysql]:主机、账号、密码、数据库(默认库 subjects_kg
  • [redis]:主机、端口、密码
  • [milvus]:主机、端口、数据库名、集合名
  • [llm]:模型名(如 qwen3-max)、dashscope_api_keydashscope_base_url
  • [retrieval]:父块大小、子块大小、重叠、retrieval_kcandidate_m
  • [app]valid_sources(学科列表)、客服电话

注意:DASHSCOPE_API_KEY 优先从环境变量 API_KEY 读取(见 base/config.py)。建议通过 set API_KEY=sk-xxxxx(Windows)或 export API_KEY=sk-xxxxx(Mac/Linux)注入,避免硬编码。


六、数据准备

1. 初始化 MySQL 问答库

将学科问答数据导入 jpkb 表(字段:学科名称、问题、答案):

from mysql_qa.db.mysql_client import MySQLClient

client = MySQLClient()
client.create_table()
client.insert_data('mysql_qa/data/JP学科知识问答.csv')

2. 构建向量知识库

rag_qa/data/<学科>_data/ 下的文档加载、切块、编码并写入 Milvus:

from rag_qa.core.vector_store import VectorStore
from rag_qa.core.document_processor import process_documents

vs = VectorStore()                              # 建表/加载集合
docs = process_documents('rag_qa/data/ai_data') # 文档读取 + 父子块切分
vs.add_documents(docs)                          # BGE-M3 编码 + 写入 Milvus

或通过 rag_qa/rag_main.py 的数据处理模式批量处理所有学科:

from rag_qa.rag_main import main
main(query_mode=False, directory_path='rag_qa/data')

七、启动方式

方式一:Web 服务(推荐)

启动 FastAPI 服务,提供 HTTP 与 WebSocket 接口及前端页面:

python app.py
  • 服务地址:http://localhost:8003
  • 前端页面:浏览器访问 http://localhost:8003/
  • API 文档:http://localhost:8003/docs

方式二:CLI 交互模式

python new_main.py

在终端中输入问题进行交互式问答,支持学科过滤与对话历史查看。

方式三:独立 RAG 模式

python rag_qa/rag_main.py

仅使用 RAG 系统进行查询(不经过 BM25 层)。


八、API 接口

方法 路径 说明
GET / 前端问答页面
POST /api/create_session 创建新会话,返回 session_id
POST /api/query 非流式查询(问候/BM25 命中直接返回;需 RAG 时提示走 WebSocket)
WS /api/stream WebSocket 流式查询,逐 Token 返回
GET /api/history/{session_id} 获取指定会话历史
DELETE /api/history/{session_id} 清除指定会话历史
GET /api/sources 获取支持的学科类别
GET /health 健康检查

WebSocket 消息格式

客户端发送:

{"query": "AI学科学费是多少?", "source_filter": "ai", "session_id": "xxx"}

服务端返回(按序):

{"type": "start", "session_id": "xxx"}
{"type": "token", "token": "片段...", "session_id": "xxx"}
{"type": "end", "session_id": "xxx", "is_complete": true, "processing_time": 1.23}

九、模型训练

1. BERT 意图分类模型

意图分类用于区分"通用知识"与"专业咨询",决定是否触发 RAG 检索。

  • 训练数据:rag_qa/classify_data/(由大模型生成的 JSONL/JSON)
  • 训练脚本:rag_qa/core/query_classifier.pyrag_qa/core/train_bert.py
  • 模型输出:rag_qa/core/bert_query_classifier/
from rag_qa.core.query_classifier import QueryClassifier

clf = QueryClassifier(model_path='bert-base-chinese')
clf.train_model(data_file='rag_qa/classify_data/training_data_1000.json')

训练数据生成流程可参考 rag_qa/classify_data/数据生成与效果评估.md(可借助 Coze / Dify 智能体生成 + 质量过滤 + 自动评估)。


十、效果评估与性能测试

1. RAGAS 评估

使用 RAGAS 从忠实度(faithfulness)、答案相关性(answer_relevancy)、上下文相关性(context_precision)、上下文召回率(context_recall)四个维度评估 RAG 效果:

cd rag_qa/rag_assesment
python ragas_evaluate.py

评估数据:rag_evaluate_data.json,结果输出:ragas_evaluation_results.csv

2. Locust 性能测试

模拟并发用户,压测 HTTP /api/query 与 WebSocket /api/stream,并记录首 Token 响应时间、Token 间隔与总耗时:

locust -f locust_test.py

访问 http://localhost:8089 配置并发数并启动测试,结果保存至 token_response_times.csv


十一、关键参数说明

参数 配置项 默认值 说明
BM25 相似度阈值 bm25_search.search(threshold) 0.85 softmax 归一化后得分 ≥ 阈值才采纳
父块大小 retrieval.parent_chunk_size 1200 父块字符数(提供上下文)
子块大小 retrieval.child_chunk_size 300 子块字符数(用于检索)
块重叠 retrieval.chunk_overlap 50 切块重叠字符数
检索数量 retrieval.retrieval_k 3 混合检索 Top-K
最终候选 retrieval.candidate_m 2 重排序后最终上下文数量
对话历史轮数 new_main.py 5 MySQL 保留最近 5 轮
最大 Prompt 长度 new_rag_system.py 4096 超长截断

十二、注意事项

  1. 模型文件较大rag_qa/models/ 下的 BGE-M3、BGE-Reranker 等模型体积较大,需单独下载放置。
  2. GPU 加速:支持 CUDA / MPS 自动检测,无 GPU 时回退 CPU(编码与推理较慢)。
  3. OCR 依赖:PDF/图片 OCR 依赖 RapidOCR,首次加载模型需要一定时间。
  4. 配置安全:生产环境请勿将真实密钥写入 config.ini,建议统一通过环境变量注入。
  5. 学科扩展:新增学科需在 config.inivalid_sources 中添加,并在 rag_qa/data/ 下创建 <学科>_data 目录放入文档后重新构建向量库。