# RagPro_3
**Repository Path**: ipoter/rag-pro_3
## Basic Information
- **Project Name**: RagPro_3
- **Description**: 国内 IT 教育头部企业 RAG 教学项目
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 34
- **Created**: 2026-10-19
- **Last Updated**: 2026-10-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# EduRAG 智能学科答疑系统
EduRAG 是一套面向学科答疑场景的智能问答系统。系统采用「本地问答库 + RAG 知识库」双层架构:优先通过 Redis 缓存与 BM25 从 MySQL FAQ 库中快速命中标准答案;当本地问答未命中或置信度不足时,自动降级到 RAG 链路,结合意图分类、检索策略路由、混合检索与重排序,调用大语言模型生成答案,从而兼顾**回答速度、准确性与知识覆盖面**。
> **项目状态**
>
> | 模块 | 状态 | 说明 |
> | --- | --- | --- |
> | 本地问答(Redis + MySQL + BM25) | ✅ 已完成 | 支持缓存命中、相似问题匹配与阈值降级 |
> | RAG 知识库问答 | ✅ 已完成 | 意图分类、策略路由、混合检索、重排、流式生成 |
> | QA + RAG 一体化 | ✅ 已完成 | 命令行入口 `main.py` |
> | FastAPI 服务化 | 🚧 规划中 | 将现有能力封装为 RESTful API 与 SSE 流式接口 |
> | Web 前端页面 | 🚧 规划中 | 流式对话、来源标注、会话历史 |
>
> 当前可直接运行的是命令行版本;[API 设计](#api-设计规划中)与[前端规划](#web-前端规划中)章节描述的是后续部署形态,相关文件尚未创建。
---
## 目录
- [核心特性](#核心特性)
- [系统架构](#系统架构)
- [技术栈](#技术栈)
- [目录结构](#目录结构)
- [快速开始](#快速开始)
- [配置说明](#配置说明)
- [API 设计(规划中)](#api-设计规划中)
- [Web 前端(规划中)](#web-前端规划中)
- [部署规划](#部署规划)
- [开发路线图](#开发路线图)
- [常见问题](#常见问题)
---
## 核心特性
### 1. 双层问答路由,快慢结合
- **第一层:本地问答库**
- 用户问题先查 Redis 精确缓存,命中即返回。
- 未命中时使用 BM25 在 MySQL `faq` 表中检索最相似的预设问题。
- 相似度得分达到阈值(默认 `8.0`)时返回标准答案,并回写缓存。
- **第二层:RAG 知识库**
- 本地问答未命中或低分时自动降级到 RAG。
- RAG 答案同样支持 Redis 缓存,避免重复推理。
- **异常兜底**:RAG 初始化或生成失败时返回人工客服提示,不会导致整个服务不可用。
### 2. 面向业务的检索增强策略
RAG 链路不是简单的「向量检索 + 拼接」,而是包含多层决策:
1. **意图分类**:基于微调后的 BERT 模型,将问题划分为「通用知识」与「专业咨询」。
- 通用知识:不检索知识库,直接由大模型回答。
- 专业咨询:进入检索链路。
2. **检索策略路由**:由大模型在四种策略中选择最合适的一种。
- 直接检索(Direct)
- 假设性文档嵌入检索(HyDE)
- 子查询拆分检索(Sub-query)
- 回溯问题简化检索(Backtracking)
3. **混合检索与重排**:
- BGE-M3 稠密向量 + 稀疏向量混合检索(Milvus `WeightedRanker`)。
- BGE Reranker 对候选文档进行精排。
- 父文档—子文档切分:以子块检索、以父块作为上下文,兼顾召回精度与上下文完整性。
- 命中子块在父文档中高亮定位,提升答案可解释性。
4. **自动降级**:高级策略未检索到结果时,回退到直接检索。
### 3. 流式输出与会话上下文
- 支持逐字流式生成答案,降低首字等待时间。
- 会话历史按 `session_id` 存储在 Redis 中,默认保留最近 5 轮对话。
- 流式异常时不会缓存不完整答案。
### 4. 多格式文档接入
文档加载器工厂支持:
| 格式 | Loader | 说明 |
| --- | --- | --- |
| `.txt` | `UTF8TextLoader` | 自动尝试多种编码 |
| `.md` | `FastMarkdownLoader` | Markdown 结构化加载 |
| `.pdf` | `OCRPDFLoader` | 文本提取 + OCR 兜底 |
| `.docx` | `OCRDocxLoader` | 段落 + 图片 OCR |
| `.pptx` | `OCRPPTLoader` | 幻灯片文本 + 图片 OCR |
| `.jpg/.jpeg/.png/.bmp` | `OCRImageLoader` | RapidOCR 识别 |
配合语义切分器 `BgeSemanticSplitter`,按语义边界切分文档。
---
## 系统架构
```mermaid
flowchart TD
U[用户] --> CLI[CLI 入口 main.py]
CLI --> IQ[IntegratedQASystem]
IQ --> QA[本地问答层]
QA --> RC[(Redis 缓存)]
QA --> MY[(MySQL faq 表)]
QA -->|"命中 / 分数 ≥ 阈值"| ANS[返回答案]
QA -->|"未命中 / 低分"| RAG[RAGPipeline]
RAG --> CLS[BERT 意图分类]
CLS -->|通用知识| LLM[大语言模型
DeepSeek]
CLS -->|专业咨询| SS[检索策略选择]
SS --> VS[(Milvus
BGE-M3 混合检索 + 重排)]
VS --> LLM
LLM --> ANS
subgraph FUTURE["规划中的服务化形态"]
WEB[Web 前端] --> API[FastAPI
REST + SSE]
API --> IQ
end
```
### 一次问答的完整流程
1. 接收用户问题,生成或复用 `session_id`。
2. 查询 Redis 精确缓存;命中则直接返回。
3. 使用 BM25 在 MySQL FAQ 库中检索相似问题;得分达到阈值则返回标准答案。
4. 查询 RAG 答案缓存;命中则直接返回。
5. 进入 RAG 链路:
- BERT 判断问题类型;
- 通用知识直接调用大模型;
- 专业咨询选择检索策略,执行混合检索与重排;
- 组装上下文并调用大模型生成答案。
6. 流式输出答案,写入会话历史与答案缓存。
7. 任一步骤异常时返回人工客服兜底提示。
---
## 技术栈
| 层次 | 技术 |
| --- | --- |
| 语言与配置 | Python 3.10+、Pydantic Settings、python-dotenv |
| 本地问答 | Redis、MySQL、`rank-bm25`、`jieba` |
| RAG 框架 | LangChain |
| 向量数据库 | Milvus 2.4(etcd + MinIO) |
| 嵌入与重排 | BGE-M3、BGE Reranker v2-m3 |
| 意图分类 | HuggingFace Transformers + 微调 BERT |
| 大模型 | DeepSeek(OpenAI 兼容协议) |
| 文档处理 | PyMuPDF、python-docx、python-pptx、RapidOCR |
| 服务化(规划) | FastAPI、Uvicorn、SSE / WebSocket |
| 前端(规划) | 单页应用、原生 JavaScript、Tailwind CSS、Markdown 渲染 |
---
## 目录结构
```text
RagPro/
├── main.py # 当前入口:QA + RAG 一体化命令行程序
├── base/
│ ├── config.py # Pydantic Settings 配置中心
│ └── logger.py # 日志配置
├── qa_system/
│ ├── qa_search.py # BM25 相似问题检索
│ ├── qa_cache.py # Redis 缓存、会话历史
│ ├── qa_db.py # MySQL 连接池与 FAQ 读写
│ ├── qa_utils.py # jieba 分词、停用词与文本预处理
│ ├── res/ # 停用词表等资源文件
│ ├── data/ # 本地 FAQ 数据(已 gitignore)
│ └── main.py # 独立 QA 命令行程序
├── rag_system/
│ ├── main.py # 独立 RAG 命令行程序
│ ├── core/
│ │ ├── rag_pipeline.py # RAG 主流程、缓存、流式生成
│ │ ├── query_classifier.py # BERT 意图分类推理
│ │ ├── strategy_selector.py # 检索策略选择
│ │ ├── vector_store.py # Milvus 混合检索与重排
│ │ ├── document_processor.py # 文档加载、切分、父块组装
│ │ ├── prompts_manager.py # Prompt 模板管理
│ │ └── train_pipeline.py # 意图分类模型离线训练与评估
│ ├── document_loaders/ # 多格式文档加载器与 OCR
│ ├── text_splitters/ # 语义切分器
│ ├── data/ # 本地数据(已 gitignore)
│ ├── docs/ # 知识库原始文档(已 gitignore)
│ └── models/ # 本地模型权重(已 gitignore)
├── docker/
│ └── docker-compose.yml # Milvus / MySQL / Redis 等基础服务
├── logs/ # 运行日志
├── requirements.txt
├── config.ini # 旧版配置样例(当前代码不读取)
└── .env # 本地环境变量(已 gitignore)
```
> 规划中的服务化代码建议放在 `api/`,前端静态资源放在 `static/`,详见 [API 设计](#api-设计规划中)。
---
## 快速开始
### 1. 环境要求
- Python 3.10+
- Docker / Docker Compose(用于启动 MySQL、Redis、Milvus)
- 可用的 DeepSeek API Key
- 本地模型权重(见 [准备模型](#5-准备模型与知识库))
### 2. 启动基础服务
项目已提供 `docker/docker-compose.yml`,包含 MySQL、Redis、Milvus(etcd + MinIO)以及 Milvus 可视化管理工具 Attu:
```bash
cd docker
docker compose up -d
```
启动后可访问:
| 服务 | 地址 |
| --- | --- |
| Milvus | `localhost:19530` |
| Attu(Milvus 管理界面) | http://localhost:3000 |
| MinIO 控制台 | http://localhost:9001 |
| MySQL | `localhost:3306` |
| Redis | `localhost:6379` |
> `docker-compose.yml` 中的 MySQL root 密码与 Redis 密码仅为演示默认值(`123456` / `1234`),生产环境务必修改,并与 `.env` 保持一致。
### 3. 创建虚拟环境并安装依赖
```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
> 首次安装 `torch`、`sentence-transformers`、`FlagEmbedding` 等依赖体积较大,请耐心等待。
### 4. 配置环境变量
在项目根目录创建 `.env`(该文件已被 `.gitignore` 忽略):
```dotenv
# ---------- MySQL ----------
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=123456
MYSQL_DATABASE=itcast
# ---------- Redis ----------
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=1234
REDIS_DB=0
# ---------- Milvus ----------
MILVUS_HOST=localhost
MILVUS_PORT=19530
MILVUS_DATABASE_NAME=itcast
MILVUS_COLLECTION_NAME=edurag
# ---------- 大模型(DeepSeek,使用 OpenAI 兼容协议)----------
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
LLM_MODEL_PROVIDER=openai
LLM_BASE_URL=https://api.deepseek.com
LLM_QA_MODEL_NAME=deepseek-flash
LLM_RS_MODEL_NAME=deepseek-v4-pro
# ---------- 业务参数 ----------
QA_MIN_SCORE_THRESHOLD=8.0
RETRIEVAL_K=8
CANDIDATE_M=2
RAG_CACHE_ENABLED=true
```
> 由于使用 OpenAI 兼容协议,DeepSeek 的 Key 通过 `OPENAI_API_KEY` 传入。环境变量优先级高于代码默认值;完整配置项见 [base/config.py](base/config.py)。
### 5. 准备模型与知识库
模型权重不纳入 Git,请将以下目录放到 `rag_system/models/`:
```text
rag_system/models/
├── BAAI/
│ ├── bge-m3/ # 稠密 + 稀疏嵌入模型
│ └── bge-reranker-v2-m3/ # 重排序模型
├── bert-intent-recognition-model/ # 微调后的意图分类模型
└── google-bert/
└── bert-base-chinese/ # BERT 基座(训练/调试用)
```
将业务文档放入 `rag_system/docs/`,然后执行一次知识库构建。该命令会加载文档、按父子结构切分、生成 BGE-M3 向量并写入 Milvus:
```bash
python -m rag_system.core.vector_store
```
> 向量主键由「文件路径 + 内容摘要」确定性生成,重复执行会覆盖更新同一条记录,不会产生重复数据。更换嵌入模型或调整切分参数后,建议删除并重建 Milvus 集合。
### 6. 初始化 FAQ 问答库
本地问答依赖 MySQL 中的 `faq` 表:
```sql
CREATE TABLE IF NOT EXISTS faq (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
subject_name VARCHAR(20) NOT NULL,
question VARCHAR(1000) NOT NULL,
answer VARCHAR(10000) NOT NULL
);
```
也可以通过项目内置的 `MySQLClient` 建表并批量导入 CSV:
```python
from qa_system.qa_db import MySQLClient
client = MySQLClient()
client.create_table()
# CSV 需包含三列:学科名称、问题、答案
client.insert_data('path/to/faq.csv')
```
### 7. 启动系统
```bash
python main.py
```
按提示输入问题;输入 `exit` 或 `quit` 退出。
命令行会在答案下方标注来源:
- `[本地问答库]`:命中 Redis / BM25 / MySQL 标准答案
- `[RAG知识库]`:由 RAG 链路生成
- `[Python程序]`:无效问题或系统异常时的兜底提示
---
## 配置说明
配置集中在 [base/config.py](base/config.py),通过环境变量或 `.env` 覆盖。常用配置项如下:
| 配置项 | 默认值 | 说明 |
| --- | --- | --- |
| `MYSQL_HOST` / `MYSQL_PORT` | `localhost` / `3306` | MySQL 连接地址 |
| `MYSQL_USER` / `MYSQL_PASSWORD` | `root` / 空 | MySQL 账号 |
| `MYSQL_DATABASE` | `itcast` | 问答库数据库名 |
| `REDIS_HOST` / `REDIS_PORT` | `localhost` / `6379` | Redis 连接地址 |
| `REDIS_PASSWORD` | 空 | Redis 密码 |
| `MILVUS_HOST` / `MILVUS_PORT` | `localhost` / `19530` | Milvus 连接地址 |
| `MILVUS_COLLECTION_NAME` | `edurag` | 向量集合名 |
| `OPENAI_API_KEY` | 空 | 大模型 API Key |
| `LLM_BASE_URL` | `https://api.deepseek.com` | OpenAI 兼容接口地址 |
| `LLM_QA_MODEL_NAME` | `deepseek-flash` | 问答模型 |
| `LLM_RS_MODEL_NAME` | `deepseek-v4-pro` | 策略选择等推理模型 |
| `QA_MIN_SCORE_THRESHOLD` | `8.0` | BM25 命中阈值,低于该值降级到 RAG |
| `RETRIEVAL_K` | `8` | 每次检索返回的候选数量 |
| `CANDIDATE_M` | `2` | 最终送入大模型的上下文文档数量 |
| `PARENT_CHUNK_SIZE` / `CHILD_CHUNK_SIZE` | `1200` / `300` | 父/子文档切分大小 |
| `RAG_CACHE_ENABLED` | `true` | 是否启用 RAG 答案缓存 |
| `HISTORY_MAX_TURNS` | `5` | 会话保留的最大轮数 |
| `CONTACT_TEL` | `400-888-6666` | 异常兜底时展示的客服电话 |
| `LOG_FILE` | `logs/app.log` | 日志文件路径 |
> 根目录的 `config.ini` 是旧版配置样例,当前代码不再读取,保留仅作参考。
---
## API 设计(规划中)
> 以下接口为后续 FastAPI 服务化的目标设计,**当前尚未实现**。现有业务逻辑将直接复用 `IntegratedQASystem`,避免在 API 层重复实现问答流程。
### 服务结构(建议)
```text
api/
├── __init__.py
├── app.py # FastAPI 实例、生命周期、CORS、静态文件挂载
├── schemas.py # Pydantic 请求 / 响应模型
├── dependencies.py # IntegratedQASystem 单例与依赖注入
└── routers/
├── chat.py # 同步问答、SSE 流式问答
├── health.py # 健康检查
└── sessions.py # 会话历史
static/
├── index.html # 前端页面
├── app.js
└── styles.css
```
启动方式(规划):
```bash
uvicorn api.app:app --reload --port 8000
```
### 接口一览
| 方法 | 路径 | 说明 | 返回类型 |
| --- | --- | --- | --- |
| `GET` | `/api/health` | 服务健康状态与依赖探测 | JSON |
| `POST` | `/api/v1/chat` | 同步问答,一次性返回完整答案 | JSON |
| `POST` | `/api/v1/chat/stream` | 流式问答,SSE 逐块推送 | `text/event-stream` |
| `GET` | `/api/v1/sessions/{session_id}/history` | 获取会话历史 | JSON |
| `DELETE` | `/api/v1/sessions/{session_id}/history` | 清空会话历史 | JSON |
| `GET` | `/` | Web 前端页面 | HTML |
### 统一响应结构
非流式接口统一使用以下结构:
```json
{
"code": 0,
"message": "ok",
"data": {}
}
```
`source` 建议使用稳定的机器可读编码,而不是直接返回中文文案:
| 编码 | 对应现有枚举 | 前端展示 |
| --- | --- | --- |
| `qa` | `AnswerSource.SOURCE_QA` | 本地问答库 |
| `rag` | `AnswerSource.SOURCE_RAG` | RAG 知识库 |
| `system` | `AnswerSource.SOURCE_NONE` | 系统提示 / 人工客服 |
### 同步问答
`POST /api/v1/chat`
请求:
```json
{
"question": "AI 大模型课程的学费是多少?",
"session_id": "optional-session-id"
}
```
- `question`:必填,非空字符串。
- `session_id`:可选;不传时由服务端生成,并通过响应返回。
响应:
```json
{
"code": 0,
"message": "ok",
"data": {
"answer": "AI 大模型课程的学费为……",
"source": "qa",
"session_id": "8f1c2d3e4a5b6c7d",
"latency_ms": 12.3,
"cached": true
}
}
```
### 流式问答(SSE)
`POST /api/v1/chat/stream`
请求体同上。建议使用 `StreamingResponse` + `text/event-stream`,事件格式如下:
```text
event: meta
data: {"session_id":"8f1c2d3e4a5b6c7d","source":"rag"}
event: delta
data: {"content":"AI"}
event: delta
data: {"content":" 大模型课程"}
event: done
data: {"latency_ms":1234,"cached":false}
```
事件说明:
| 事件 | 时机 | 内容 |
| --- | --- | --- |
| `meta` | 检索完成、开始生成前 | 会话 ID、答案来源 |
| `delta` | 每生成一个文本块 | 增量内容 |
| `done` | 正常结束 | 总耗时、是否命中缓存 |
| `error` | 发生异常 | 错误码与兜底提示 |
> 浏览器原生 `EventSource` 只支持 GET,因此前端应使用 `fetch` 读取 `ReadableStream`,或改用 WebSocket。若选择 WebSocket,可增加 `GET /ws/chat`,消息体与 SSE 事件保持同构。
### 健康检查
`GET /api/health`
```json
{
"code": 0,
"message": "ok",
"data": {
"status": "up",
"version": "1.0.0",
"uptime_seconds": 3600,
"dependencies": {
"mysql": "up",
"redis": "up",
"milvus": "up"
}
}
}
```
> 健康检查建议只做轻量探测(如 ping),不要在每次请求中触发大模型调用或 RAG 初始化。
### 错误码(建议)
| code | HTTP 状态 | 含义 |
| --- | --- | --- |
| `0` | `200` | 成功 |
| `1001` | `400` | 请求参数不合法 |
| `1002` | `404` | 会话不存在 |
| `2001` | `503` | MySQL / Redis / Milvus 不可用 |
| `3001` | `429` | 请求过于频繁 |
| `4001` | `401` | 未认证(启用鉴权后) |
| `5000` | `500` | 服务内部错误 |
### API 层实现要点
- **复用业务逻辑**:API 层只负责参数校验、会话管理与响应封装,问答仍由 `IntegratedQASystem.query()` 完成。
- **避免阻塞事件循环**:BM25 检索、模型推理与 LLM 调用均为同步阻塞操作,应在 `async` 路由中使用 `asyncio.to_thread()` 或 `run_in_threadpool()`。
- **RAG 延迟初始化**:保持现有懒加载机制;如需降低首个专业问题的延迟,可在启动阶段通过配置项预热模型。
- **会话管理**:`session_id` 透传给 `IntegratedQASystem`,历史记录继续使用 Redis,无需新增存储。
- **统一的异常兜底**:保留人工客服提示逻辑,避免将堆栈信息返回给客户端。
- **CORS 与静态资源**:开发阶段允许前端跨域;生产环境由 FastAPI 挂载 `static/`,或交给 Nginx 托管。
- **SSE 代理配置**:使用 Nginx 时需关闭响应缓冲(`proxy_buffering off;`),并适当延长超时时间。
---
## Web 前端(规划中)
前端定位为**单页对话式答疑界面**,由 FastAPI 直接托管,无需单独构建流程。
### 页面功能
- 对话框式交互,支持多轮会话。
- SSE 流式渲染,逐字展示答案。
- 答案来源徽标:`本地问答库` / `RAG 知识库` / `系统提示`。
- 新建会话、清空上下文、切换历史会话。
- Markdown 渲染、代码块高亮、复制答案。
- 加载状态、超时重试、异常兜底提示。
- 响应式布局,适配桌面与移动端。
- 可选深色模式。
### 技术选型(建议)
- 原生 HTML + CSS + ES Modules,降低部署复杂度。
- Tailwind CSS 负责样式。
- `marked` + `DOMPurify` 渲染并净化 Markdown。
- `highlight.js` 高亮代码块。
- 使用 `fetch` + `ReadableStream` 消费 SSE(因为流式接口为 POST)。
### 目录约定
```text
static/
├── index.html
├── app.js
└── styles.css
```
FastAPI 中挂载:
```python
from fastapi.staticfiles import StaticFiles
app.mount('/static', StaticFiles(directory='static'), name='static')
```
访问 `http://127.0.0.1:8000/` 即可使用对话页面。
---
## 部署规划
> 以下内容为后续服务化部署目标,当前尚未提供 `Dockerfile` 与生产启动脚本。
### 开发环境
```bash
uvicorn api.app:app --reload --host 127.0.0.1 --port 8000
```
### 生产环境建议
```bash
uvicorn api.app:app --host 0.0.0.0 --port 8000 --workers 1
```
注意事项:
- **建议单 Worker 运行**:BGE-M3、Reranker、BERT 等模型会占用较多内存,多进程会重复加载模型;如需横向扩展,应将模型推理拆分为独立服务。
- **基础服务外置**:MySQL、Redis、Milvus 使用独立容器或托管服务,应用容器只负责 API 与前端。
- **反向代理**:Nginx 负责 TLS、静态资源与 SSE 转发;SSE 需关闭缓冲。
- **健康检查**:容器编排使用 `/api/health` 作为存活/就绪探针。
- **密钥管理**:`.env` 不进入镜像,通过环境变量或密钥管理服务注入。
- **日志与监控**:保留 `logs/app.log`;API 层建议增加请求 ID、耗时与错误率指标。
---
## 开发路线图
- [x] Redis + MySQL + BM25 本地问答
- [x] RAG 意图分类与检索策略路由
- [x] BGE-M3 混合检索与 BGE Reranker 重排
- [x] 父文档—子文档切分与命中高亮
- [x] QA → RAG 自动降级与异常兜底
- [x] 答案缓存、会话历史与流式输出
- [x] 多格式文档加载与 OCR
- [ ] FastAPI 应用骨架(`api/app.py`、Routers、Schemas)
- [ ] 同步问答接口 `POST /api/v1/chat`
- [ ] SSE 流式接口 `POST /api/v1/chat/stream`
- [ ] 健康检查与会话历史接口
- [ ] Web 对话前端
- [ ] RAG 模型预热与启动自检
- [ ] Dockerfile 与一键部署脚本
- [ ] 单元测试与接口测试
- [ ] 鉴权、限流与可观测性
---
## 常见问题
### 1. 启动时报 Redis / MySQL 连接失败
确认基础服务已启动:
```bash
docker ps
```
并检查 `.env` 中的地址、端口、密码是否与 `docker-compose.yml` 一致。
### 2. Milvus 连接失败
Milvus 依赖 etcd 与 MinIO,首次启动需要一定时间。可通过以下方式确认:
```bash
docker compose -f docker/docker-compose.yml ps
```
并访问 Attu(http://localhost:3000)查看 Milvus 是否就绪。
### 3. 第一次专业问题响应很慢
RAG 采用延迟初始化:只有在本地问答未命中时才会加载 BGE-M3、Reranker 与 BERT 模型。首次加载耗时属于正常现象,后续查询会显著加快。`main.py` 启动时不会等待模型加载。
### 4. 调用大模型返回 401 或鉴权失败
- 检查 `OPENAI_API_KEY` 是否为有效的 DeepSeek Key。
- 确认 `LLM_BASE_URL` 为 `https://api.deepseek.com`。
- 确认 `LLM_MODEL_PROVIDER=openai`(使用 OpenAI 兼容协议)。
### 5. 提示找不到模型或向量维度不匹配
- 确认 `rag_system/models/` 下的模型目录完整。
- 模型权重已被 `.gitignore` 忽略,从 Git 拉取代码后需要单独下载。
- 更换嵌入模型后,需要重建 Milvus 集合,否则会出现维度不匹配。
### 6. 修改知识库后答案没有更新
答案会被写入 Redis 缓存。知识库或 Prompt 更新后,可分别调用 `RedisClient.for_qas().clear_cache()` 与 `RedisClient.for_rag().clear_cache()` 按业务前缀清理缓存,或在 Redis 中删除对应键。
### 7. 多进程部署后内存占用过高
每个进程都会独立加载 BGE-M3、Reranker 与 BERT。建议 API 服务使用单 Worker;需要扩容时将模型推理拆分为独立服务。
---
## 作者
**骆昊**
本项目用于智能答疑系统的教学与实践,涵盖 BM25 本地问答、RAG 检索增强、重排序、意图识别与服务化改造等完整链路。