RAG01-项目概述
项目概述
1 项目简介
1.1 项目背景
近年来,ChatGPT 等大模型(LLM)快速普及,AI大模型 已成为企业数字化升级的重点方向。
但 AI大模型 在真实业务中有两个常见问题:
知识更新慢:模型主要依赖训练时的数据,无法自动掌握最新信息。
不了解企业私有数据:如公司制度、产品文档、内部 FAQ 等。
这会导致回答“看起来合理但实际不对”,即常说的幻觉问题。
为解决这些问题,企业常用两种方案:
方案一:模型微调
用企业数据继续训练模型,让模型更懂行业术语和业务场景。需要继续训练模型,成本高,难度高。
方案二:RAG(Retrieval-Augmented Generation,检索增强生成)
先从企业知识库检索相关内容,再交给大模型生成答案。
该方案上线快、成本相对低、更新方便,是目前落地最广的方案之一。
本项目采用 LangChain + Qwen 构建学科在线答疑系统-简称EduRAG,核心目标是:
提升回答准确率与时效性
降低人工答疑压力
形成可复用的企业级问答方案
通过本课程,你将掌握:
如何构建一个RAG系统:本地知识库构建 → 向量检索 → RAG 问答链路搭建 → 项目部署与验证
如何在其他行业及通用企业场景中实现一个类似的RAG系统
1.2 RAG原理

1.3 项目架构 ¶
在线答疑系统RAG主要步骤:
第一步:将已有的FQA数据集存储到Mysql数据库中
第二步:基于query检索Mysql数据库:将query和现有问题匹配(做相似度计算),如果阈值>=[0.85, 10.0],就认为问题比较明确,直接返回对应的答案;否则,进入RAG检索系统
第三步:搭建本地知识库:加载本地文档 -> 文档分割 -> 文档向量化 -> 存储向量数据库(Milvus)
第四步:基于query检索Milvus数据库:将query进行向量表示,并从Milvus数据库中检索出相似的top-k个文档片段。
第五步:将query和检索出的top-k文档片段拼接,送入大模型,生成答案。
flowchart LR;
%% =========================
%% 主数据流
%% =========================
Query([用户问题query]) --> FQA系统
FQA系统 -->|不超过阈值| RAG系统
RAG系统 --> FinalAnswer([最终答案])
FQA系统 -->|超过阈值| FinalAnswer([最终答案])
FQA系统
flowchart LR;
%% =========================
%% 离线阶段
%% =========================
subgraph 数据准备-离线阶段
A[1.结构化FQA数据]
B[(2.MySQL数据库)]
C[3.jieba分词]
E[4.构建BM25检索器]
A --> B
B --> C
C --> E
end
style 数据准备-离线阶段 fill:none,stroke:#000000
%% =========================
%% 在线阶段
%% =========================
subgraph 问题检索-在线阶段
U[1.用户问题]
V[2.jieba分词]
W[3.BM25相似度检索]
X{4.双重阈值判断}
Y[5.1 Redis查询FQA答案]
Z[6.返回FQA答案]
N[5.2 调用RAG系统]
U --> V
V --> W
W --> X
X -- 是 --> Y
Y --> Z
X -- 否 --> N
end
style 问题检索-在线阶段 fill:none,stroke:#000000
%% =========================
%% 共享组件
%% =========================
R[(Redis缓存FQA)]
%% 在线读缓存
Y --> R
%% Redis未命中查MySQL
R -.未命中.-> B
%% 离线BM25提供在线检索
E -.BM25索引.-> W
RAG系统
flowchart LR;
%%{init:{"themeVariables":{"fontSize":"18px","nodeSpacing":15,"rankSpacing":15}}}%%
%% =========================
%% 在线阶段
%% =========================
subgraph 用户提问阶段-在线
direction TB
Start([用户查询]) --> Classify{查询分类<br/>bert意图识别模型}
Classify -->|通用知识| DirectLLM["直接调用LLM<br/>生成回答"]
Classify -->|专业咨询| Strategy{选择检索策略<br/>LLM}
Strategy -->|明确查询| DirectRetrieval["直接检索"]
Strategy -->|抽象问题| HyDERetrieval["假设问题检索<br/>生成假设答案"]
Strategy -->|复杂查询| SubQuery["子查询检索"]
Strategy -->|啰嗦问题| BacktrackRetrieval["回溯问题检索"]
DirectRetrieval --> OptimizeQuery["LLM优化query"]
HyDERetrieval --> OptimizeQuery
SubQuery --> OptimizeQuery
BacktrackRetrieval --> OptimizeQuery
OptimizeQuery --> Search["检索向量库<br/>得到上下文context"]
Search --> BuildPrompt["拼接Prompt<br/>优化query+context+history"]
BuildPrompt --> Generate["LLM生成回答"]
DirectLLM --> Output([返回回答])
Generate --> HasAnswer["是否有答案<br/>无答案则引导人工支持"]
HasAnswer --> Output
end
style 用户提问阶段-在线 fill:none,stroke:#000000
%% =========================
%% 离线阶段
%% =========================
subgraph 文档向量存储阶段-离线
direction TB
StartDoc([本地知识文档])
StartDoc --> PDFLoader["PDF加载器"]
StartDoc --> DOCLoader["DOC加载器"]
StartDoc --> TXTLoader["TXT加载器"]
StartDoc --> PPTLoader["PPT加载器"]
PDFLoader --> Document["文档对象"]
DOCLoader --> Document
TXTLoader --> Document
PPTLoader --> Document
Document --> ParentChunk["父块分块"]
ParentChunk --> SubChunk["子块分块"]
SubChunk --> SubChunkList["子块集合"]
SubChunkList --> Embed["文档向量化<br/>(bge-m3本地模型)"]
Embed --> Milvus[(Milvus)]
classDef milvusLarge font-size:32px,stroke-width:5px;
class Milvus milvusLarge;
end
style 文档向量存储阶段-离线 fill:none,stroke:#000000
%% =========================
%% 在线检索连接离线向量库
%% =========================
Milvus --> Search
1.4 项目结构 ¶
integrated_qa_system/
├── base/
│ ├── config.py # 配置管理,加载 config.ini
│ ├── logger.py # 日志设置
├── rag_qa/
│ ├── core/
│ │ ├── document_processor.py # 文档处理模块
│ │ ├── prompts.py # RAG 提示模板
│ │ ├── query_classifier.py # 查询分类器
│ │ ├── strategy_selector.py # 检索策略选择器
│ │ ├── vector_store.py # 向量存储与检索
│ │ ├── rag_system.py # RAG 系统核心逻辑
│ ├── edu_document_loaders/ # 文档加载模块
│ ├── edu_text_spliter/ # 文本分割模块
│ ├── models/ # 模型模块
│ ├── rag_assesment/ # RAGAS评估模块
│ ├── main.py # RAG 系统独立入口,支持存储和查询
├── mysql_qa/
│ ├── db/
│ │ ├── mysql_client.py # MySQL 数据库操作
│ ├── cache/
│ │ ├── redis_client.py # Redis 缓存操作
│ ├── retrieval/
│ │ ├── bm25_search.py # BM25 搜索
│ ├── utils/
│ │ ├── preprocess.py # 文本预处理
│ ├── main.py # MySQL 系统独立入口,支持查询
├── config.ini # 配置文件,包含所有模块的配置
├── main.py # 集成系统入口,结合 RAG 和 MySQL
├── app.py # FastAPI主服务入口
├── requirements.txt # 依赖文件
└── logs/
└── app.log # 日志文件
2 项目环境(window)
2.1 前置说明 ¶
本教程介绍如何在 Windows 11 和 M1 芯片的 macOS 系统上使用 Docker 同时部署和运行单机版 Milvus(向量数据库)和 Redis(键值存储数据库)。教程分为两部分,分别针对不同操作系统提供详细步骤。
操作系统
- Windows 11
硬件要求
至少 8GB 内存(建议 16GB 或更高)。
至少 20GB 可用磁盘空间(Milvus 和 Redis 数据存储)。
网络要求
- 稳定的互联网连接,用于拉取 Docker 镜像。
软件版本
Milvus:2.4.4(最新稳定版)。
Redis:7.2(最新稳定版)。
端口要求
Milvus:19530(gRPC)、9091(RESTful API)。
Redis:6379(默认端口)。
确保以上端口未被占用。
2.2 python虚拟环境 ¶
1 创建虚拟环境 ¶
# 创建虚拟环境, 安装3.10及以上的python解析器 (比如3.10.18)
conda create -n edu_rag python=3.10.18
# 切换虚拟环境
conda activate edu_rag
2 找到依赖文件 ¶
requirements.txt文件
3 安装项目依赖包 ¶
# 安装依赖包, 在requirements.txt对应路径下执行以下命令
pip install -r requirements.txt

如果安装过程不顺利,可以按需逐个安装:
# conda create -n edu_rag python==3.10.18
# conda activate edu_rag
# Python版本:3.10.18
# 使用方法:先安装python 3.10.18或者创建一个conda的3.10.18的环境,并激活。然后运行以下命令
pip install ollama==0.4.4
pip install requests==2.32.3
pip install numexpr==2.11.0
pip install unstructured==0.11.0
pip install langchain-core==1.2.16
pip install langchain_community==0.4.1
pip install langchain-ollama==1.0.1
pip install langchain_unstructured==1.0.1
pip install langchain_experimental==0.4.1
pip install langchain_chroma==1.1.0
pip install langchain-text-splitters==1.1.1
pip install langgraph==1.0.8
pip install nltk==3.9.1
pip install chromadb==1.3.5
pip install wikipedia==1.4.0
pip install faiss-cpu
pip install pymilvus==2.5.4
pip install pandas==2.3.1
pip install jieba
pip install rank_bm25==0.2.2
pip install redis==5.3.1
pip install pymysql==1.1.1
pip install opencv-python==4.10.0.84
pip install PyMuPDF==1.23.16
pip install python-docx==1.1.2
pip install pillow==10.4.0
pip install rapidocr-onnxruntime==1.3.8
pip install python-pptx==0.6.23
pip install transformers==4.45.0
pip install modelscope==1.23.0
pip install addict==2.4.0
pip install datasets==3.3.1
pip install simplejson==3.19.2
pip install sortedcontainers==2.4.0
pip install markdown==3.6
pip install sentence-transformers==3.0.1
pip install milvus-model==0.2.5
pip install tiktoken==0.7.0
pip install sentencepiece==0.2.0
pip install ragas==0.2.6
pip install starlette==0.46.2
pip install fastapi==0.115.12
pip install FlagEmbedding==1.3.5
pip install peft==0.18.1
2.3 安装DockerDesktop ¶
1 安装WSL ¶
参考 https://learn.microsoft.com/zh-cn/windows/wsl/install
- 启用WSL 打开具有管理员权限的PowerShell,运行以下命令以安装WSL
wsl --install


输入命令后效果如下

安装完后自动跳转页面,关闭即可

安装完成后,重启电脑
2 安装docker ¶
下载并安装Docker Desktop
- 访问 Docker官方网站,下载适用于Windows/Mac的Docker Desktop安装包。(可以直接下载共享文件中的安装包)

安装Docker Desktop
双击下载的安装文件(老师发的资料中有),按照提示一路下一步完成安装
安装完成后,点击 close and restart 重启电脑以完成配置

验证Docker安装
- 打开PowerShell或命令提示符,运行以下命令,验证是否成功安装
docker --version
docker compose version

2.4 配置DockerCompose文件 ¶
1 创建项目目录 ¶
- 在本地磁盘(例如:C盘)创建文件夹milvus_redis,用于存放Milvus和Redis的配置文件和数据:

2 创建docker-compose文件 ¶
先创建docker-compose.txt格式文件, 然后修改为docker-compose.yml格式

3 添加内容 ¶
把以下内容复制粘贴到你创建的docker-compose.yml文件:
# version: '3.5'
# Windows/x86_64 Version
# Redis Password set to: 1234
services:
etcd:
container_name: milvus-etcd
image: quay.io/coreos/etcd:v3.5.5
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_ENABLE_V2=true
volumes:
- ./volumes/etcd:/etcd/data
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd/data
minio:
container_name: milvus-minio
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
volumes:
- ./volumes/minio:/minio/data
command: minio server /minio/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
standalone:
container_name: milvus-standalone
# 使用多架构镜像,Docker on Windows 会自动拉取 x86_64 版本
image: milvusdb/milvus:v2.4.4
command: ["milvus", "run", "standalone"]
environment:
- ETCD_ENDPOINTS=etcd:2379
- MINIO_ADDRESS=minio:9000
volumes:
- ./volumes/milvus:/var/lib/milvus
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- "etcd"
- "minio"
redis:
container_name: milvus-redis
image: redis:latest
restart: always
ports:
- "6379:6379"
volumes:
- ./volumes/redis:/data
# 设置 Redis 密码为 1234
command: redis-server --requirepass 1234
# ==================== MySQL ====================
mysql:
container_name: mysql
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: subjects_kg
MYSQL_CHARSET: utf8mb4
MYSQL_COLLATION: utf8mb4_unicode_ci
TZ: Asia/Shanghai
ports:
- "3307:3306"
volumes:
- ./volumes/mysql/data:/var/lib/mysql
- ./volumes/mysql/conf:/etc/mysql/conf.d
- ./volumes/mysql/init:/docker-entrypoint-initdb.d
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --lower-case-table-names=1
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123456"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
default:
name: milvus-network
说明
Milvus 服务
image : 使用 Milvus 官方镜像 milvusdb/milvus:v2.4.10 。
ports : 映射 gRPC(19530)和 RESTful API(9091)端口。
volumes : 数据持久化存储到本地 ./volumes/milvus 目录。
environment : 配置日志级别和 Etcd 参数。
command : 启动 Milvus 单机模式。
Redis 服务
image : 使用 Redis 官方镜像 redis:7.2 。
ports : 映射默认端口 6379 。
volumes : 数据持久化存储到本地 ./volumes/redis 目录。
command : 启用 AOF(Append Only File)持久化模式。
volumes : 定义持久化存储卷。
mysql 服务
image : 使用 MySQL 官方镜像
mysql:8.0。ports : 映射端口
3307:3306,宿主机通过3307访问容器内 MySQL。environment : 配置
MYSQL_ROOT_PASSWORD、MYSQL_DATABASE、字符集与时区(Asia/Shanghai)。volumes : 挂载数据目录
./volumes/mysql/data、配置目录./volumes/mysql/conf、初始化脚本目录./volumes/mysql/init,确保数据与初始化SQL持久化。command : 指定
mysql_native_password认证方式,并设置utf8mb4字符集、排序规则及表名大小写策略。healthcheck : 通过
mysqladmin ping做健康检查,确保服务启动后可用。
2.5 启动Milvus和Redis ¶
1 拉取镜像并启动容器 ¶
- 进入上述创建的milvus_redis目录下,打开具有管理员权限的PowerShell终端,运行:
# -d 表示后台运行容器
docker compose up -d

- 注意: 拉取镜像时报错: Get “https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
以下为解决方法, 添加镜像源:
window方案: 直接复制以下内容去docker软件中粘贴即可:
"registry-mirrors": [
"https://docker.211678.top",
"https://docker.1panel.live",
"https://hub.rat.dev",
"https://docker.m.daocloud.io",
"https://do.nark.eu.org",
"https://dockerpull.com",
"https://dockerproxy.cn",
"https://docker.awsl9527.cn"
]


重启docker生效
然后再次去milvus_redis 目录下,打开 PowerShell,运行:
# -d 表示后台运行容器
docker compose up -d
2 docker查看是否成功 ¶
启动成功后去docker看看是否正常启动

2.6 验证Milvus和Redis ¶
1 测试Milvus连接 ¶
from pymilvus import connections, utility
# 连接到 Milvus
connections.connect(host="localhost", port="19530")
# 检查版本
print(f"Milvus version: {utility.get_server_version()}")
e:\conda_envs\edu_rag\lib\site-packages\pymilvus\client\__init__.py:6: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
from pkg_resources import DistributionNotFound, get_distribution
Milvus version: v2.4.4
- 在edu_rag虚拟环境下运行脚本 # cmd终端执行命令 # 输出类似Milvus version: 2.4.10 表示Milvus部署成功 python test_milvus.py
2 测试Redis连接 ¶
import redis
# 连接到 Redis
client = redis.Redis(host="localhost", port=6379, password=1234, decode_responses=True)
# 测试读写
client.set("test_key", "Hello, Redis!")
value = client.get("test_key")
print(f"Redis value: {value}")
Redis value: Hello, Redis!
- 在edu_rag虚拟环境下运行脚本 # cmd终端执行命令 # 输出类似Redis value: Hello, Redis! 表示Redis部署成功
3 测试mysql连接 ¶
import pymysql
try:
conn = pymysql.connect(
host="localhost",
port=3307, # 对应 docker-compose: 3307:3306
user="root",
password="123456",
database="subjects_kg",
charset="utf8mb4"
)
with conn.cursor() as cursor:
cursor.execute("SELECT VERSION();")
version = cursor.fetchone()[0]
print(f"MySQL 连接成功,版本: {version}")
except Exception as e:
print(f"MySQL 连接失败: {e}")
finally:
try:
conn.close()
except:
pass
MySQL 连接成功,版本: 8.0.46
2.7 安装Milvus可视化工具Attu ¶
1 安装 ¶
拉取可视化组件attu
docker pull zilliz/attu
运行可视化组件
# 启动容器,宿主机 30000 映射到容器 3000,并加入到 milvus-network 网络中,使得能通过容器名访问milvus
# docker run: 启动容器
# -d: 后台运行
# -p: 端口映射 宿主机端口:容器端口
# --network: 加入到 指定网络,需要和docker-compose.yml中的 milvus网络名称 一致
# --name: 容器名
docker run -d -p 30000:3000 --network milvus-network --name attu zilliz/attu
2 连接 ¶
在 Attu 页面的 Milvus Address 输入框中填写:
milvus-standalone:19530


版权声明
本文为 程序员青阳 原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文链接及本声明。