fix(boundary): 修复多库边界问题、版本管理及删除清理
多库检索与存储修复: - 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 - 更新多篇现有文档
This commit is contained in:
305
docs/架构与部署方案.md
305
docs/架构与部署方案.md
@@ -106,7 +106,6 @@ X-User-Department: 部门(可选)
|
||||
|------|------|------|
|
||||
| `/chat` | POST | 普通聊天 |
|
||||
| `/rag` | POST | 知识库问答 |
|
||||
| `/rag/stream` | POST | 流式问答 |
|
||||
| `/search` | POST | 混合检索 |
|
||||
|
||||
#### 向量库管理
|
||||
@@ -175,7 +174,8 @@ GET /api/users/{user_id}
|
||||
- [x] 更新 API 文档
|
||||
- [ ] 清理测试数据和临时文件
|
||||
- [ ] 整理依赖列表 (requirements.txt)
|
||||
- [ ] 准备环境变量配置模板
|
||||
- [ ] 准备环境变量配置模板 (`deploy/.env.production`)
|
||||
- [ ] 编写 Dockerfile.prod 和 docker-compose.prod.yml
|
||||
|
||||
### 4.2 后端组需完成
|
||||
|
||||
@@ -195,155 +195,193 @@ GET /api/users/{user_id}
|
||||
|
||||
---
|
||||
|
||||
## 五、Linux 部署方案
|
||||
## 五、Linux 部署方案(Docker)
|
||||
|
||||
### 5.1 部署架构
|
||||
### 5.1 服务器规格
|
||||
|
||||
| 项目 | 配置 |
|
||||
|------|------|
|
||||
| 操作系统 | Ubuntu 22.04 LTS |
|
||||
| CPU | 4 vCPU |
|
||||
| 内存 | 8 GB |
|
||||
| 部署路径 | `/opt/rag-agent` |
|
||||
| 容器运行时 | Docker + Docker Compose |
|
||||
|
||||
### 5.2 部署架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Linux 服务器 │
|
||||
│ Linux 服务器 (Ubuntu 22.04) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
|
||||
│ │ Nginx │ │ 后端服务 │ │ RAG 服务 │ │
|
||||
│ │ :80/443 │───▶│ :8080 │ │ :5001 │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ ▼ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ │ MySQL/PG │ │ ChromaDB │ │
|
||||
│ │ └─────────────┘ └─────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ documents/ │ ◀── 文档存储目录 │
|
||||
│ └─────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ Docker (rag-service 容器) │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ Gunicorn (gthread worker) │ │ │
|
||||
│ │ │ └── Flask App :5001 │ │ │
|
||||
│ │ └──────────────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ 数据卷挂载: │ │
|
||||
│ │ • vector_store/ → 向量库持久化 │ │
|
||||
│ │ • documents/ → 原始文档 │ │
|
||||
│ │ • models/ → 本地模型文件 │ │
|
||||
│ │ • .data/ → 运行时缓存 │ │
|
||||
│ │ • data/ → SQLite 同步状态 │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ ▲ │
|
||||
│ │ :5001 │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ 后端网关 │ (Nginx / Spring Cloud Gateway) │
|
||||
│ │ :80/443 │ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.2 环境准备
|
||||
### 5.3 项目目录结构
|
||||
|
||||
```bash
|
||||
# 1. 系统依赖
|
||||
sudo apt update
|
||||
sudo apt install -y python3.10 python3.10-venv python3-pip
|
||||
|
||||
# 2. 创建部署用户
|
||||
sudo useradd -m -s /bin/bash rag
|
||||
sudo su - rag
|
||||
|
||||
# 3. 创建目录结构
|
||||
mkdir -p /home/rag/rag-service/{app,documents,vector_store,logs}
|
||||
```
|
||||
/opt/rag-agent/
|
||||
├── deploy/
|
||||
│ ├── Dockerfile.prod # 生产镜像定义
|
||||
│ ├── docker-compose.prod.yml # 编排文件
|
||||
│ └── .env.production # 生产环境变量
|
||||
├── app/ # 应用源码
|
||||
├── vector_store/ # ChromaDB 向量库(持久化)
|
||||
├── documents/ # 原始文档(持久化)
|
||||
├── models/ # 本地模型文件(持久化)
|
||||
├── .data/ # 运行时缓存
|
||||
└── data/ # SQLite 同步状态
|
||||
```
|
||||
|
||||
### 5.3 RAG 服务部署
|
||||
### 5.4 Dockerfile.prod
|
||||
|
||||
```dockerfile
|
||||
# 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
|
||||
|
||||
```yaml
|
||||
# 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` 文件注入,不在代码中硬编码:
|
||||
|
||||
```bash
|
||||
# 1. 上传代码
|
||||
cd /home/rag/rag-service
|
||||
# 将项目代码上传到 app/ 目录
|
||||
# deploy/.env.production
|
||||
|
||||
# 2. 创建虚拟环境
|
||||
python3.10 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 3. 安装依赖
|
||||
pip install -r app/requirements.txt
|
||||
|
||||
# 4. 配置环境变量
|
||||
cat > .env << EOF
|
||||
# 生产环境配置
|
||||
# 运行模式
|
||||
DEV_MODE=false
|
||||
DOCUMENTS_PATH=/home/rag/rag-service/documents
|
||||
VECTOR_STORE_PATH=/home/rag/rag-service/vector_store
|
||||
|
||||
# API 配置(如果需要)
|
||||
DASHSCOPE_API_KEY=your_api_key
|
||||
EOF
|
||||
# 路径配置
|
||||
DOCUMENTS_PATH=/app/documents
|
||||
VECTOR_STORE_PATH=/app/vector_store
|
||||
|
||||
# 5. 初始化向量库
|
||||
python -c "from knowledge.manager import get_kb_manager; get_kb_manager()"
|
||||
# API 密钥
|
||||
DASHSCOPE_API_KEY=your_api_key_here
|
||||
|
||||
# 6. 测试启动
|
||||
cd app && python main.py --port 5001
|
||||
# 其他配置项按需添加...
|
||||
```
|
||||
|
||||
### 5.4 Systemd 服务配置
|
||||
### 5.7 首次部署
|
||||
|
||||
```bash
|
||||
# 创建服务文件
|
||||
sudo cat > /etc/systemd/system/rag-service.service << 'EOF'
|
||||
[Unit]
|
||||
Description=RAG Knowledge Service
|
||||
After=network.target
|
||||
# 1. 在服务器上创建部署目录
|
||||
sudo mkdir -p /opt/rag-agent
|
||||
sudo chown $USER:$USER /opt/rag-agent
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=rag
|
||||
Group=rag
|
||||
WorkingDirectory=/home/rag/rag-service/app
|
||||
Environment="PATH=/home/rag/rag-service/venv/bin"
|
||||
EnvironmentFile=/home/rag/rag-service/.env
|
||||
ExecStart=/home/rag/rag-service/venv/bin/python main.py --port 5001
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
# 2. 上传项目代码到 /opt/rag-agent
|
||||
scp -r ./rag-agent/* server:/opt/rag-agent/
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
# 3. 配置环境变量
|
||||
cd /opt/rag-agent/deploy
|
||||
cp .env.production.example .env.production
|
||||
vim .env.production # 填入实际的 API Key 等配置
|
||||
|
||||
# 启动服务
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable rag-service
|
||||
sudo systemctl start rag-service
|
||||
# 4. 构建并启动容器
|
||||
docker compose -f docker-compose.prod.yml up -d --build
|
||||
|
||||
# 查看状态
|
||||
sudo systemctl status rag-service
|
||||
# 5. 验证服务状态
|
||||
docker ps
|
||||
docker logs rag-service
|
||||
curl -f http://localhost:5001/health
|
||||
```
|
||||
|
||||
### 5.5 Nginx 配置
|
||||
### 5.8 热更新流程
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/sites-available/rag-service
|
||||
upstream rag_backend {
|
||||
server 127.0.0.1:5001;
|
||||
}
|
||||
#### 小改动(配置文件、Prompt 模板等)
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
# 请求体大小限制(文件上传)
|
||||
client_max_body_size 50M;
|
||||
|
||||
# RAG API 代理
|
||||
location /rag-api/ {
|
||||
proxy_pass http://rag_backend/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# 注入用户信息(由认证模块设置)
|
||||
proxy_set_header X-User-ID $http_x_user_id;
|
||||
proxy_set_header X-User-Name $http_x_user_name;
|
||||
proxy_set_header X-User-Role $http_x_user_role;
|
||||
proxy_set_header X-User-Department $http_x_user_department;
|
||||
|
||||
# SSE 支持
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
# 图片文件
|
||||
location /images/ {
|
||||
alias /home/rag/rag-service/documents/images/;
|
||||
}
|
||||
}
|
||||
```bash
|
||||
# 直接复制文件进容器并重启
|
||||
docker cp ./app/config.py rag-service:/app/config.py
|
||||
docker restart rag-service
|
||||
```
|
||||
|
||||
### 5.6 网关 Header 注入示例
|
||||
#### 大改动(代码逻辑、依赖变更等)
|
||||
|
||||
```bash
|
||||
# 重新构建镜像并启动(数据卷不受影响)
|
||||
cd /opt/rag-agent/deploy
|
||||
docker compose -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
### 5.9 网关 Header 注入示例
|
||||
|
||||
后端网关在转发请求到 RAG 服务时注入 Header:
|
||||
|
||||
@@ -410,31 +448,41 @@ curl -X POST http://localhost:5001/documents/upload \
|
||||
### 7.1 日志管理
|
||||
|
||||
```bash
|
||||
# RAG 服务日志
|
||||
tail -f /home/rag/rag-service/logs/rag.log
|
||||
# 查看容器实时日志
|
||||
docker logs -f rag-service
|
||||
|
||||
# Systemd 日志
|
||||
journalctl -u rag-service -f
|
||||
# 查看最近 100 行日志
|
||||
docker logs --tail 100 rag-service
|
||||
|
||||
# 导出日志到文件
|
||||
docker logs rag-service > /var/log/rag-service.log 2>&1
|
||||
```
|
||||
|
||||
### 7.2 健康检查
|
||||
|
||||
```bash
|
||||
# 添加到监控脚本
|
||||
curl -f http://localhost:5001/health || alert "RAG service down"
|
||||
# 手动检查
|
||||
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 备份策略
|
||||
|
||||
```bash
|
||||
# 备份向量库
|
||||
tar -czf backup_$(date +%Y%m%d).tar.gz vector_store/
|
||||
tar -czf backup_vector_$(date +%Y%m%d).tar.gz /opt/rag-agent/vector_store/
|
||||
|
||||
# 备份文档
|
||||
rsync -av documents/ backup/documents/
|
||||
rsync -av /opt/rag-agent/documents/ backup/documents/
|
||||
|
||||
# 备份同步状态
|
||||
sqlite3 data/knowledge.db ".backup backup/knowledge.db"
|
||||
cp /opt/rag-agent/data/knowledge.db backup/knowledge_$(date +%Y%m%d).db
|
||||
```
|
||||
|
||||
---
|
||||
@@ -446,5 +494,8 @@ sqlite3 data/knowledge.db ".backup backup/knowledge.db"
|
||||
| 401 未认证 | 缺少 X-User-ID | 检查网关 Header 注入 |
|
||||
| 向量检索失败 | ChromaDB 损坏 | 重建向量库 |
|
||||
| 文件上传失败 | 权限/空间问题 | 检查目录权限和磁盘空间 |
|
||||
| 内存不足 | 向量模型占用 | 增加 swap 或内存 |
|
||||
| 内存不足 | 向量模型占用 | 调整 docker-compose 内存限制或增加服务器内存 |
|
||||
| 服务启动慢 | 模型加载 | 预热模型或使用更小模型 |
|
||||
| 容器启动失败 | 镜像构建问题 | `docker logs rag-service` 查看错误 |
|
||||
| 容器 OOM Killed | 内存超限 | 增大 `deploy.resources.limits.memory` 或加 swap |
|
||||
| 数据卷未挂载 | 路径配置错误 | `docker inspect rag-service` 检查 Mounts |
|
||||
|
||||
Reference in New Issue
Block a user