多库检索与存储修复: - RRF 融合去重改用 (collection, chunk_id) 复合键,修复同名文件结果被吞 - DocStore 存储路径加 collection 前缀,修复跨库同名切片数据覆盖 - search_multiple 去重改用复合键 - chunk_id 解析改用 rsplit 兼容下划线文件名 上传与版本管理修复: - 同名文件上传改为覆盖模式,自动清理旧切片 - 修复首次上传不创建版本记录 - 修复覆盖上传版本号回退到 v1 - sync ADDED 分支改用动态版本号生成 - _generate_version_id 改为基于全部版本递增 - 废止/恢复操作同步 SQLite 版本记录 - mark_document_as_superseded 改为仅更新 SQLite 删除清理修复: - 删除文档时同步清理 SQLite 版本记录和变更日志 - 删除向量库时同步清理该库所有版本记录 - cleanup 改为清理 SQLite 记录而非 ChromaDB 测试: - test_version_management.py: 27 条版本管理单元测试 - test_edge_cases.py: 28 条边界用例测试 - test_upload_dedup.py: 5 条上传去重测试 - e2e_risk_test.py: 27 条端到端风险测试 文档: - 新增风险边界问题修复注意事项.md(面向后端的对接文档) - 新增向量库边界风险分析.md - 更新多篇现有文档
18 KiB
18 KiB
RAG 服务架构与部署方案
一、系统架构概览
┌─────────────────────────────────────────────────────────────────────────────┐
│ 前端应用 │
│ (Vue/React Web/App) │
└─────────────────────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 后端网关 │
│ (Nginx / API Gateway / Spring Cloud) │
│ │
│ 职责: │
│ • 用户认证 (登录/Token验证) │
│ • 权限控制 (角色/部门/接口权限) │
│ • Header 注入 (X-User-ID, X-User-Role, X-User-Department) │
│ • 请求路由与负载均衡 │
└─────────────────────────────────────┬───────────────────────────────────────┘
│
┌─────────────────┴─────────────────┐
│ │
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────────────┐
│ 后端业务服务 │ │ RAG 服务 │
│ (Java/Spring Boot/Go) │ │ (Python/Flask) │
│ │ │ │
│ 职责: │ │ 职责: │
│ • 用户账户管理 │ │ • 向量存储 (ChromaDB) │
│ • 组织架构/角色权限 │ │ • BM25 索引 │
│ • 会话管理 (对话历史) │ │ • 文档解析与分块 │
│ • 审计日志 │ │ • 知识库问答 (RAG) │
│ • 反馈记录 │ │ • 文档同步与向量化 │
│ • 业务主数据 (学生/课程等) │ │ • 出题能力 │
│ • 题库/试卷管理 │ │ │
│ │ │ │
│ 数据库: │ │ 数据存储: │
│ • MySQL/PostgreSQL │ │ • ChromaDB (向量库) │
│ │ │ • 文件系统 (documents/) │
│ │ │ • SQLite (同步状态哈希) │
└───────────────────────────────┘ └───────────────────────────────────────┘
二、职责分工详解
2.1 RAG 组(本项目)负责
| 模块 | 功能 | 数据存储 |
|---|---|---|
| 向量存储 | ChromaDB 向量库管理 | vector_store/chroma/ |
| BM25 索引 | 关键词检索 | 内存/文件 |
| 文档解析 | PDF/Word/Excel 解析与分块 | 临时处理 |
| 知识库问答 | Agentic RAG 问答引擎 | - |
| 文档同步 | 文件变更检测与向量化 | SQLite (哈希记录) |
| 出题能力 | 基于知识库生成题目 | 无状态 |
2.2 后端组负责
| 模块 | 功能 | 数据存储 |
|---|---|---|
| 用户认证 | 登录/注册/Token 管理 | MySQL/PostgreSQL |
| 权限控制 | 角色/部门/接口权限 | MySQL/PostgreSQL |
| 会话管理 | 对话历史记录 | MySQL/PostgreSQL |
| 审计日志 | 操作日志记录 | MySQL/PostgreSQL |
| 反馈系统 | 用户反馈收集 | MySQL/PostgreSQL |
| 业务主数据 | 学生/课程/组织架构 | MySQL/PostgreSQL |
| 题库管理 | 题目存储/试卷管理 | MySQL/PostgreSQL |
| 网关路由 | 请求路由/Header 注入 | - |
2.3 数据归属对照表
| 数据类型 | 存储位置 | 管理方 | 说明 |
|---|---|---|---|
| 向量数据 | ChromaDB | RAG 组 | 文档 embedding |
| 文档哈希 | SQLite | RAG 组 | 同步状态检测 |
| 原始文档 | 文件系统 | RAG 组 | documents/ 目录 |
| 用户账户 | MySQL/PG | 后端组 | 账号密码信息 |
| 会话历史 | MySQL/PG | 后端组 | 对话记录 |
| 审计日志 | MySQL/PG | 后端组 | 操作日志 |
| 反馈记录 | MySQL/PG | 后端组 | 用户反馈 |
| 题库数据 | MySQL/PG | 后端组 | 题目/试卷 |
三、接口协作规范
3.1 后端调用 RAG 服务
后端通过 HTTP 调用 RAG API,需注入 Header:
X-User-ID: 用户唯一标识
X-User-Name: 用户名(可选)
X-User-Role: 用户角色(可选)
X-User-Department: 部门(可选)
3.2 RAG 服务提供的接口
问答接口
| 接口 | 方法 | 说明 |
|---|---|---|
/chat |
POST | 普通聊天 |
/rag |
POST | 知识库问答 |
/search |
POST | 混合检索 |
向量库管理
| 接口 | 方法 | 说明 |
|---|---|---|
/collections |
GET | 向量库列表 |
/collections |
POST | 创建向量库 |
/collections/<name> |
PUT | 修改向量库 |
/collections/<name> |
DELETE | 删除向量库 |
文档管理
| 接口 | 方法 | 说明 |
|---|---|---|
/documents/upload |
POST | 上传文件 |
/documents/batch-upload |
POST | 批量上传 |
/documents/list |
GET | 文档列表 |
/documents/<path> |
DELETE | 删除文档 |
/documents/<path>/status |
GET | 处理状态 |
切片管理
| 接口 | 方法 | 说明 |
|---|---|---|
/documents/<path>/chunks |
GET | 查看切片 |
/chunks |
POST | 新增切片 |
/chunks/<id> |
PUT | 修改切片 |
/chunks/<id> |
DELETE | 删除切片 |
同步服务
| 接口 | 方法 | 说明 |
|---|---|---|
/sync |
POST | 触发同步 |
/sync/status |
GET | 同步状态 |
出题接口
| 接口 | 方法 | 说明 |
|---|---|---|
/exam/generate |
POST | 生成题目 |
/exam/grade |
POST | 批改答案 |
3.3 后端需要提供的接口
RAG 服务可能需要调用后端获取用户信息:
GET /api/users/{user_id}
响应:
{
"user_id": "xxx",
"username": "用户名",
"name": "真实姓名",
"role": "admin/manager/user",
"department": "部门名称"
}
四、合并前准备工作
4.1 RAG 组需完成
- 权限控制简化(依赖后端网关)
- 移除会话管理依赖
- 移除审计日志依赖
- 更新 API 文档
- 清理测试数据和临时文件
- 整理依赖列表 (requirements.txt)
- 准备环境变量配置模板 (
deploy/.env.production) - 编写 Dockerfile.prod 和 docker-compose.prod.yml
4.2 后端组需完成
- 设计数据库表结构
- 实现用户认证接口
- 实现会话管理接口
- 实现审计日志接口
- 配置网关路由和 Header 注入
- 提供 RAG 服务调用的接口
4.3 双方需确认
- 接口协议和字段格式
- 错误码规范
- 部署环境和网络配置
- 文件存储方案(本地/NFS/OSS)
五、Linux 部署方案(Docker)
5.1 服务器规格
| 项目 | 配置 |
|---|---|
| 操作系统 | Ubuntu 22.04 LTS |
| CPU | 4 vCPU |
| 内存 | 8 GB |
| 部署路径 | /opt/rag-agent |
| 容器运行时 | Docker + Docker Compose |
5.2 部署架构
┌─────────────────────────────────────────────────────────────────┐
│ Linux 服务器 (Ubuntu 22.04) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Docker (rag-service 容器) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ Gunicorn (gthread worker) │ │ │
│ │ │ └── Flask App :5001 │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 数据卷挂载: │ │
│ │ • vector_store/ → 向量库持久化 │ │
│ │ • documents/ → 原始文档 │ │
│ │ • models/ → 本地模型文件 │ │
│ │ • .data/ → 运行时缓存 │ │
│ │ • data/ → SQLite 同步状态 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ :5001 │
│ ┌──────┴──────┐ │
│ │ 后端网关 │ (Nginx / Spring Cloud Gateway) │
│ │ :80/443 │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
5.3 项目目录结构
/opt/rag-agent/
├── deploy/
│ ├── Dockerfile.prod # 生产镜像定义
│ ├── docker-compose.prod.yml # 编排文件
│ └── .env.production # 生产环境变量
├── app/ # 应用源码
├── vector_store/ # ChromaDB 向量库(持久化)
├── documents/ # 原始文档(持久化)
├── models/ # 本地模型文件(持久化)
├── .data/ # 运行时缓存
└── data/ # SQLite 同步状态
5.4 Dockerfile.prod
# deploy/Dockerfile.prod
FROM python:3.10-slim
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# 安装 CPU-only PyTorch(减小镜像体积)
RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu
# 安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
EXPOSE 5001
# 使用 Gunicorn gthread 模式启动
CMD ["gunicorn", \
"--bind", "0.0.0.0:5001", \
"--workers", "2", \
"--threads", "4", \
"--worker-class", "gthread", \
"--timeout", "300", \
"main:app"]
5.5 docker-compose.prod.yml
# deploy/docker-compose.prod.yml
version: "3.8"
services:
rag-service:
build:
context: ..
dockerfile: deploy/Dockerfile.prod
container_name: rag-service
ports:
- "5001:5001"
env_file:
- .env.production
volumes:
- ../vector_store:/app/vector_store
- ../documents:/app/documents
- ../models:/app/models
- ../.data:/app/.data
- ../data:/app/data
restart: unless-stopped
deploy:
resources:
limits:
memory: 6G
5.6 环境变量配置
所有环境变量通过 deploy/.env.production 文件注入,不在代码中硬编码:
# deploy/.env.production
# 运行模式
DEV_MODE=false
# 路径配置
DOCUMENTS_PATH=/app/documents
VECTOR_STORE_PATH=/app/vector_store
# API 密钥
DASHSCOPE_API_KEY=your_api_key_here
# 其他配置项按需添加...
5.7 首次部署
# 1. 在服务器上创建部署目录
sudo mkdir -p /opt/rag-agent
sudo chown $USER:$USER /opt/rag-agent
# 2. 上传项目代码到 /opt/rag-agent
scp -r ./rag-agent/* server:/opt/rag-agent/
# 3. 配置环境变量
cd /opt/rag-agent/deploy
cp .env.production.example .env.production
vim .env.production # 填入实际的 API Key 等配置
# 4. 构建并启动容器
docker compose -f docker-compose.prod.yml up -d --build
# 5. 验证服务状态
docker ps
docker logs rag-service
curl -f http://localhost:5001/health
5.8 热更新流程
小改动(配置文件、Prompt 模板等)
# 直接复制文件进容器并重启
docker cp ./app/config.py rag-service:/app/config.py
docker restart rag-service
大改动(代码逻辑、依赖变更等)
# 重新构建镜像并启动(数据卷不受影响)
cd /opt/rag-agent/deploy
docker compose -f docker-compose.prod.yml up -d --build
5.9 网关 Header 注入示例
后端网关在转发请求到 RAG 服务时注入 Header:
// Spring Cloud Gateway 示例
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("rag-service", r -> r.path("/rag-api/**")
.filters(f -> f
.stripPrefix(1)
.addRequestHeader("X-User-ID", "#{request.getAttribute('userId')}")
.addRequestHeader("X-User-Role", "#{request.getAttribute('userRole')}")
.addRequestHeader("X-User-Department", "#{request.getAttribute('userDept')}")
)
.uri("http://127.0.0.1:5001"))
.build();
}
六、联调测试清单
6.1 后端接口测试
- 用户认证接口可用
- 网关正确注入 Header
- 会话管理接口可用
6.2 RAG 接口测试
# 测试 RAG 服务(带 Header)
curl -X POST http://localhost:5001/rag \
-H "Content-Type: application/json" \
-H "X-User-ID: test-user" \
-H "X-User-Role: admin" \
-d '{"message": "测试问题"}'
# 测试向量库列表
curl -X GET http://localhost:5001/collections \
-H "X-User-ID: test-user"
# 测试文件上传
curl -X POST http://localhost:5001/documents/upload \
-H "X-User-ID: test-user" \
-F "file=@test.pdf" \
-F "collection=public_kb"
6.3 端到端测试
- 前端 → 后端 → RAG 请求链路通
- 用户认证正确传递
- 权限控制生效
- 文件上传下载正常
- 问答功能正常
七、运维监控
7.1 日志管理
# 查看容器实时日志
docker logs -f rag-service
# 查看最近 100 行日志
docker logs --tail 100 rag-service
# 导出日志到文件
docker logs rag-service > /var/log/rag-service.log 2>&1
7.2 健康检查
# 手动检查
curl -f http://localhost:5001/health || echo "RAG service down"
# 可通过 docker-compose 配置自动健康检查(添加到 docker-compose.prod.yml)
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost:5001/health"]
# interval: 30s
# timeout: 10s
# retries: 3
7.3 备份策略
# 备份向量库
tar -czf backup_vector_$(date +%Y%m%d).tar.gz /opt/rag-agent/vector_store/
# 备份文档
rsync -av /opt/rag-agent/documents/ backup/documents/
# 备份同步状态
cp /opt/rag-agent/data/knowledge.db backup/knowledge_$(date +%Y%m%d).db
八、故障排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 401 未认证 | 缺少 X-User-ID | 检查网关 Header 注入 |
| 向量检索失败 | ChromaDB 损坏 | 重建向量库 |
| 文件上传失败 | 权限/空间问题 | 检查目录权限和磁盘空间 |
| 内存不足 | 向量模型占用 | 调整 docker-compose 内存限制或增加服务器内存 |
| 服务启动慢 | 模型加载 | 预热模型或使用更小模型 |
| 容器启动失败 | 镜像构建问题 | docker logs rag-service 查看错误 |
| 容器 OOM Killed | 内存超限 | 增大 deploy.resources.limits.memory 或加 swap |
| 数据卷未挂载 | 路径配置错误 | docker inspect rag-service 检查 Mounts |