基于 RAG 技术的智能问答系统实战项目
演示成果
ai_robot
一、项目概述
1.1 背景介绍
在工业机器人技术培训领域,学员在学习过程中会遇到大量专业技术问题,如 PLC 通讯配置、EtherCat 总线调试等。传统的人工答疑方式效率低下,无法满足学员的即时需求。
本项目基于 RAG(检索增强生成)技术,构建了一个智能问答系统,能够理解用户问题的语义,从知识库中检索相关内容,并生成准确、专业的回答。
1.2 核心功能
- 多路检索:向量检索 + BM25 关键词检索 + MySQL 知识图谱
- 语义理解:基于 BGE-M3 的向量嵌入,精准理解用户意图
- 流式响应:WebSocket 实时输出,回答更快、更流畅
- 一键部署:Docker 容器化,5 分钟内完成部署
二、技术架构
2.1 整体架构图
┌─────────────────────────────────────────────────────────────┐
│ 用户层 │
│ Web 浏览器 ←→ WebSocket ←→ FastAPI │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 应用层 │
│ 意图分类 → 多路检索 → 重排序 → LLM 生成 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 检索层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Milvus │ │ BM25 │ │ MySQL │ │
│ │ 向量检索 │ │ 关键词检索 │ │ 知识图谱 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 数据层 │
│ MySQL + Redis + Milvus + 本地文件系统 │
└─────────────────────────────────────────────────────────────┘
2.2 技术栈
| 后端框架 | FastAPI | 异步支持好,自动生成 API 文档 |
| 向量数据库 | Milvus | 开源、高性能、支持混合检索 |
| 文本嵌入 | BGE-M3 | 中文效果好、多粒度检索 |
| 重排序 | BGE-Reranker | 提升检索结果相关性 |
| 搜索引擎 | Rank-BM25 | 关键词检索补充 |
| 知识图谱 | MySQL | 存储结构化 QA 数据 |
| 缓存 | Redis | 对话历史缓存 |
| LLM | 通义千问 (DashScope) | 云端 LLM 接口 |
| 部署 | Docker | 一键部署 |
三、核心模块实现
3.1 向量检索模块
向量检索是 RAG 系统的核心,负责将文本转换为向量,并在向量空间中查找相似文档。
from milvus_model.hybrid import BGEM3EmbeddingFunction
class VectorStore:
def __init__(self, collection_name, host, port, database):
self.client = MilvusClient(uri=f"http://{host}:{port}")
self.client.use_database(database)
self._embedding_function = None
@property
def embedding_function(self):
# 延迟加载,减少启动内存占用
if self._embedding_function is None:
self._embedding_function = BGEM3EmbeddingFunction(
use_fp16=False,
device="cpu",
cache_dir="./model_cache"
)
return self._embedding_function
设计亮点:
- 延迟加载:模型仅在首次使用时加载,减少启动时间
- 统一缓存:所有模型文件统一管理,避免重复下载
3.2 多路检索融合
单一检索方式难以覆盖所有场景,本项目实现了向量检索 + BM25 的融合:
def retrieve(self, query, top_k=5):
# 1. 向量检索 – 语义理解
vector_results = self.vector_search(query, top_k * 2)
# 2. BM25 检索 – 关键词匹配
bm25_results = self.bm25_search(query, top_k * 2)
# 3. RRF 融合排序
merged = self.rrf_fusion(vector_results, bm25_results)
# 4. CrossEncoder 重排序
reranked = self.rerank(query, merged[:top_k * 2])
return reranked[:top_k]
RRF(Reciprocal Rank Fusion)公式:
R
R
F
(
d
)
=
∑
i
=
1
k
1
r
i
(
d
)
+
k
RRF(d) = \\sum_{i=1}^{k} \\frac{1}{r_i(d) + k}
RRF(d)=i=1∑kri(d)+k1
其中
r
i
(
d
)
r_i(d)
ri(d) 是文档
d
d
d 在第
i
i
i 个检索结果中的排名。
3.3 流式响应
使用 WebSocket 实现实时流式输出,提升用户体验:
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
# 流式生成回答
for chunk in response_generator(query):
await websocket.send_text(json.dumps({
"type": "content",
"content": chunk
}))
except Exception as e:
await websocket.send_text(json.dumps({
"type": "error",
"message": str(e)
}))
四、关键问题解决
4.1 Windows 符号链接权限问题
问题:在 Windows 环境下运行项目时,HuggingFace 模型下载报 symlink 错误。
解决:
# 在应用启动前设置环境变量
os.environ['HF_HUB_DISABLE_SYMLINKS_WARNING'] = '1'
os.environ['HF_HUB_DISABLE_SYMLINKS'] = '1'
4.2 模型加载内存溢出
问题:多个模型同时加载导致内存不足。
解决:采用延迟加载策略,仅在首次使用时加载模型:
@property
def embedding_function(self):
if self._embedding_function is None:
self._embedding_function = BGEM3EmbeddingFunction(...)
return self._embedding_function
4.3 检索结果不相关
问题:用户提问后返回的文档不匹配。
解决:
五、项目结构
Itcast_qa_system/
├── app.py # FastAPI 主应用
├── new_main.py # QA 系统核心逻辑
├── config.ini # 配置文件
├── docker-compose.yml # Docker 编排
├── start_auto.bat # 一键部署脚本
├── pdf_qa_generator.py # PDF QA 生成工具
├── base/
│ ├── config.py # 配置解析
│ └── logger.py # 日志模块
├── rag_qa/
│ ├── rag_main.py # RAG 主入口
│ └── core/
│ ├── vector_store.py # 向量存储
│ ├── rag_system.py # RAG 系统
│ └── query_classifier.py # 意图分类
├── mysql_qa/
│ └── db/
│ └── mysql_client.py # MySQL 客户端
└── static/
└── index.html # 前端页面
六、一键部署
6.1 环境要求
- Windows 10/11 或 Linux
- Docker Desktop
- 16GB+ 内存
- Python 3.10+
6.2 部署步骤
# 1. 克隆项目
git clone <project-url>
cd Itcast_qa_system
# 2. 一键启动
start_auto.bat tengxun_data
部署脚本会自动完成:
- 停止现有服务
- 启动 Docker 容器(MySQL、Redis、Milvus)
- 导入知识库数据
- 启动应用服务
6.3 访问
部署完成后,访问 http://localhost:8004
七、知识库构建
7.1 PDF 处理流程
PDF 文件 → pdfplumber 提取文本 → LangChain 分块
→ BGE-M3 向量化 → Milvus 向量存储
7.2 QA 对生成
使用 Ollama 本地模型自动生成问答对:
def generate_qa_with_ollama(chunk):
prompt = f"""根据以下文本生成 3 个问答对:
{chunk}
返回 JSON 格式:
[
{{"question": "问题1", "answer": "答案1"}},
{{"question": "问题2", "answer": "答案2"}},
{{"question": "问题3", "answer": "答案3"}}
]"""
response = ollama.generate(model="qwen2.5:7b", prompt=prompt)
return parse_json_response(response)
八、性能优化
8.1 优化措施
| 模型延迟加载 | 启动时间减少 50% |
| Redis 缓存对话历史 | 响应时间减少 30% |
| GPU 加速(可选) | 向量计算提升 10 倍 |
| 连接池复用 | 数据库连接减少 80% |
8.2 性能指标
| 检索准确率 | 85%+ |
| 平均响应时间 | < 3 秒 |
| 并发支持 | 10+ 用户 |
| 知识库容量 | 1000+ QA 对 |
九、总结与展望
9.1 项目亮点
9.2 未来优化方向
- 本地部署开源 LLM(如 Qwen-7B),降低 API 成本
- 引入用户反馈机制,持续优化检索质量
- 添加监控告警,及时发现系统异常
- 微服务化拆分,支持更大规模部署
十、参考资源
- Milvus 向量数据库
- BGE-M3 嵌入模型
- LangChain RAG 教程
- FastAPI 文档
项目源码:https://gitee.com/mr_yan_123/rag_ 在线演示:http://localhost:8004



