Files
rag/README.md

465 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RAG Agent - 模块化知识库问答系统
基于本地向量模型 + Chroma 向量数据库 + 云端 Reranker + Qwen API 的智能知识库问答系统,支持 Agentic RAG 多源检索、意图分析、混合检索与多样性去重。
> **最新版本**: v7.0.0(云端 Reranker、性能优化、Agentic 引擎拆分、Docker 生产部署)
## 功能特性
### v7.0.0(当前版本)
- **云端 Reranker**:接入 DashScope qwen3-rerank API 替代本地 CrossEncoderCPU 服务器上重排序耗时从 ~8s 降至 <1s
- **MMR 双模式去重**:支持语义向量(高精度)和文本 Jaccard 相似度(轻量)两种模式,轻量模式在 CPU 环境节省 ~36s
- **意图分析加速**:独立 INTENT_MODEL 配置,使用 qwen-turbo 将意图分析从 ~12s 降至 ~2s
- **VLM 图片理解**:集成 qwen-vl-plus 视觉语言模型,支持文档内图片的语义描述与上下文融合
- **Agentic 引擎模块化拆分**:从单一 agentic.py 拆分为 search / answer / citation / context / query / media / quality / meta 八个子模块
- **Docker 生产部署**:完整的 Dockerfile + docker-compose + Gunicorn + nginx 配置,支持一键部署
- **多模型协同配置**LLM / 意图分析 / VLM / Reranker 分别配置独立模型,按场景选择最优性价比
### 核心能力
- **混合检索**:向量检索 + BM25 关键词检索RRF 融合排序
- **云端重排序**DashScope qwen3-rerank 或本地 BGE-rerankerONNX 加速),可切换
- **MMR 多样性去重**:最大边际相关性算法,防止同一文档片段重复占位
- **意图分析器**:自动识别查询类型(直接回答 / 知识库检索 / 枚举查询),优化检索策略
- **查询扩展与分解**:同义词扩展、复杂查询自动分解
- **自适应 TopK**:根据置信度动态调整返回结果数
- **上下文扩展**:枚举 / 条款类问题自动扩展相邻切片,保证上下文连贯
- **语义缓存**:相似查询复用结果,减少重复 LLM 调用
- **多向量库隔离**:按部门 / 权限隔离的独立向量库,支持物理阻断
- **文档生命周期管理**MD5 哈希差异引擎,文档更新时自动分析影响
- **引用溯源**:返回结果包含 chunk_index、来源文件、页码、bbox 等定位信息,支持前端跳转
### 支持的文档格式
PDF、Word.docx、Excel.xlsx、TXT、图片提取MinerU 解析器)
## 项目结构
```
rag-agent/
├── main.py # 统一启动入口
├── config.py # 全局配置(环境变量驱动)
├── config.example.py # 配置模板
├── requirements.txt # 开发依赖
├── requirements-prod.txt # 生产环境精简依赖
├── core/ # RAG 核心引擎
│ ├── engine.py # 检索引擎模型加载、混合检索、Rerank
│ ├── agentic.py # Agentic RAG 入口
│ ├── agentic_base.py # 基类与公共逻辑
│ ├── agentic_search.py # 检索策略(知识库 / 网络 / 图谱)
│ ├── agentic_answer.py # 回答生成
│ ├── agentic_citation.py # 引用构建与溯源
│ ├── agentic_context.py # 上下文构建
│ ├── agentic_query.py # 查询预处理
│ ├── agentic_media.py # 多媒体(图片)处理
│ ├── agentic_quality.py # 质量评估
│ ├── agentic_meta.py # 元数据管理
│ ├── intent_analyzer.py # 意图分析器
│ ├── query_classifier.py # 查询分类器
│ ├── query_expansion.py # 查询扩展
│ ├── query_decomposer.py # 查询分解
│ ├── bm25_index.py # BM25 索引
│ ├── mmr.py # MMR 多样性去重
│ ├── chunker.py # 语义分块器
│ ├── adaptive_topk.py # 自适应 TopK
│ ├── cache.py # 查询结果缓存
│ ├── semantic_cache.py # 语义缓存
│ ├── confidence_gate.py # 置信度门控
│ ├── quality_assessor.py # 质量评估器
│ ├── reasoning_reflector.py # 推理反思器
│ ├── loop_guard.py # 循环防护
│ ├── llm_budget.py # LLM 调用预算管理
│ ├── llm_utils.py # LLM 调用工具
│ ├── status_codes.py # 统一状态码
│ └── constants.py # 常量定义
├── api/ # API 路由层
│ ├── __init__.py # Flask 应用工厂
│ ├── chat_routes.py # 聊天与 RAG 问答
│ ├── document_routes.py # 文档管理与预览
│ ├── kb_routes.py # 知识库管理
│ ├── sync_routes.py # 文档同步
│ ├── session_routes.py # 会话管理
│ ├── feedback_routes.py # 反馈闭环
│ ├── image_routes.py # 图片处理
│ ├── audit_routes.py # 审计日志
│ ├── auth_routes.py # 认证
│ └── response_utils.py # 响应工具函数
├── knowledge/ # 知识库管理
│ ├── manager.py # 多向量库管理器
│ ├── router.py # 知识库路由(权限匹配)
│ ├── document.py # 文档切片操作
│ ├── collection.py # Collection 管理
│ ├── search.py # 向量检索
│ ├── permission.py # 权限控制
│ ├── sync.py # 文件同步
│ ├── processing.py # 文档处理管线
│ ├── chunk.py # 切片数据结构
│ ├── index.py # 索引管理
│ ├── document_versions.py # 文档版本差异
│ ├── cleanup.py # 清理服务
│ ├── lazy_enhance.py # 懒加载增强
│ └── vector_store/ # 向量存储目录
├── parsers/ # 文档解析器
│ ├── mineru_parser.py # MinerU 统一解析PDF/DOCX/PPTX/图片)
│ ├── pdf_mineru.py # MinerU PDF 兼容别名
│ ├── excel_parser.py # Excel 解析Pandas 管道)
│ ├── txt_parser.py # TXT 文本解析
│ └── image_extractor.py # 图片提取器
├── repositories/ # 数据仓储层
│ ├── session_repo.py # 会话仓储接口
│ ├── sqlite_session_repo.py # SQLite 实现
│ └── stateless_session_repo.py # 无状态实现
├── services/ # 业务服务
│ ├── session.py # 会话管理
│ ├── feedback.py # 反馈质量闭环
│ └── outline.py # 纲要生成与推荐
├── auth/ # 认证与安全
│ ├── gateway.py # 网关认证
│ └── security.py # 输入 / 输出安全
├── exam_pkg/ # 出题系统
│ ├── manager.py # 出题管理
│ ├── generator.py # 试卷生成器
│ ├── grader.py # 自动批阅
│ ├── api.py # Flask Blueprint
│ └── local_db.py # 本地题库
├── tools/ # 分析与运维工具
│ ├── chunk_analyzer.py # 切片质量分析
│ ├── chunk_metrics.py # 切片度量指标
│ ├── chunk_report.py # 切片报告生成
│ ├── llm_evaluator.py # LLM 评估器
│ └── export_chunks.py # 切片导出
├── deploy/ # 部署配置
│ ├── Dockerfile.prod # 生产环境 Dockerfile
│ ├── docker-compose.prod.yml # 生产环境 compose
│ ├── gunicorn.conf.py # Gunicorn 配置
│ ├── nginx.conf # Nginx 反向代理
│ └── wsgi.py # WSGI 入口
├── scripts/ # 工具脚本
│ ├── evaluate_rag.py # RAG 效果评估
│ ├── rebuild_multi_kb.py # 重建多向量库
│ ├── migrate_*.py # 数据迁移脚本
│ └── test_*.sh / test_*.py # 测试脚本
├── docs/ # 项目文档
├── documents/ # 知识库文档目录
├── models/ # 本地模型目录
├── data/ # SQLite 数据库
├── chat-ui/ # 生产前端(静态 HTML
├── dev-ui/ # 开发前端Vue3 + Naive UI
└── tests/ # 单元测试
```
## 快速开始
### 1. 克隆仓库
```bash
git clone https://git.njtobaccosales.top/jhzhang/rag.git
cd rag
```
### 2. 创建虚拟环境
```bash
python -m venv venv
# Windows
venv\Scripts\activate
# Linux / macOS
source venv/bin/activate
```
### 3. 安装依赖
```bash
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
```
### 4. 下载向量模型
| 模型 | 用途 | 大小 | 是否必需 |
|------|------|------|----------|
| BGE-base-zh-v1.5 | 向量编码 | ~400MB | 必需 |
| BGE-reranker-base | 本地重排序 | ~280MB | 可选(使用云端 Reranker 时不需要) |
```bash
mkdir models
huggingface-cli download BAAI/bge-base-zh-v1.5 --local-dir ./models/bge-base-zh-v1.5
```
### 5. 配置环境变量
```bash
cp config.example.py config.py
# 编辑 config.py 或创建 .env 文件
```
关键配置项(通过环境变量或 `.env` 文件设置):
```bash
# ---- LLM 模型 ----
DASHSCOPE_API_KEY=sk-your-api-key
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
DASHSCOPE_MODEL=qwen3.6-flash # 文本生成模型
RAG_CHAT_MODEL=qwen3.6-flash # RAG 对话模型(可与上面相同)
INTENT_MODEL=qwen-turbo # 意图分析模型(轻量快速)
VLM_MODEL=qwen-vl-plus # 视觉语言模型
# ---- 云端 Reranker推荐----
RERANK_BACKEND=cloud # local / cloud / fallback
RERANK_CLOUD_API_KEY=sk-your-api-key
RERANK_CLOUD_MODEL=qwen3-rerank
RERANK_CLOUD_BASE_URL=https://dashscope.aliyuncs.com/compatible-api/v1/reranks
# ---- 性能调优 ----
MMR_USE_EMBEDDING=false # CPU 环境建议 false文本相似度
RERANK_USE_ONNX=true # 本地 Reranker 时启用 ONNX 加速
# ---- MinerU 解析 ----
MINERU_API_TOKEN=your-token # MinerU 在线 API Token
```
### 6. 准备知识库文档
将文档放入 `documents/` 目录,支持 PDF、Word.docx、Excel.xlsx、TXT 格式。
### 7. 启动服务
```bash
# 开发模式
python main.py # 默认端口 5001
python main.py --port 8080 # 指定端口
# 生产模式(通过 Gunicorn
gunicorn -c deploy/gunicorn.conf.py deploy.wsgi:app
```
服务启动后访问 `http://localhost:5001`
## Docker 部署
生产环境推荐使用 Docker 部署,完整配置在 `deploy/` 目录下。
### 构建与启动
```bash
cd /opt/rag-agent
# 构建并启动(首次或配置变更时)
docker-compose -f deploy/docker-compose.prod.yml up -d --build
# 仅重启(不重建镜像)
docker-compose -f deploy/docker-compose.prod.yml restart
# 查看日志
docker-compose -f deploy/docker-compose.prod.yml logs -f rag-service
```
### 环境变量管理
生产环境通过 `deploy/.env.production` 文件注入环境变量docker-compose 使用 `env_file` 加载。修改配置后需执行 `up -d`(不是 `restart`)才能重新读取环境变量。
### 数据卷挂载
容器内代码在镜像中,以下目录通过挂载持久化:
- `knowledge/vector_store` — 向量数据库
- `documents/` — 知识库文档
- `models/` — 本地模型文件
- `data/` — SQLite 数据库
- `.data/` — 运行时缓存
### 热更新代码(不重建镜像)
对于小幅代码修改,可以通过 `docker cp` + `restart` 快速更新:
```bash
# 复制修改后的文件到容器
docker cp ./core/engine.py rag-service:/app/core/engine.py
# 重启容器使生效
docker-compose -f deploy/docker-compose.prod.yml restart
```
注意:`up -d --build` 会重建镜像,覆盖所有 docker cp 的修改。
## 配置管理
所有配置项在 `config.py` 中定义,通过环境变量注入。以下是生产环境推荐配置:
### 模型选型建议
| 组件 | 推荐模型 | 选型理由 |
|------|----------|----------|
| 文本生成 | qwen3.6-flash | 速度快(~24s 生成、1024K 上下文、性价比高 |
| 意图分析 | qwen-turbo | 轻量快速(~2s任务简单不需要强模型 |
| 视觉语言 | qwen-vl-plus | 图片描述质量足够,支持缓存 |
| 重排序 | qwen3-rerank云端 | 替代本地 CrossEncoderCPU 环境显著提升 |
| 向量编码 | BGE-base-zh-v1.5(本地) | 中文语义质量高,~400MB |
### 性能参考
典型 RAG 查询耗时分解4vCPU / 8GB 内存服务器):
| 阶段 | 耗时 |
|------|------|
| 意图分析 | ~2s |
| 向量 + BM25 检索 | ~1s |
| 云端 Reranker | ~0.5s |
| VLM 图片描述(缓存命中) | ~0.1s |
| LLM 生成回答 | ~24s |
| **总计** | **~28s** |
## API 接口
### 核心接口
| 接口 | 方法 | 说明 |
|------|------|------|
| `/rag` | POST | 知识库问答(多源检索 + 引用溯源) |
| `/chat` | POST | 智能聊天(支持网络搜索) |
| `/search` | POST | 混合检索(供外部系统调用) |
| `/health` | GET | 健康检查 |
### 文档管理
| 接口 | 方法 | 说明 |
|------|------|------|
| `/documents/upload` | POST | 上传文件到知识库 |
| `/documents/list` | GET | 获取文档列表 |
| `/documents/<path>` | DELETE | 删除文档 |
| `/documents/<collection>/<source>/preview` | GET | 文档预览与切片定位 |
### 引用跳转数据流
`/rag` 返回的 `citations` 数组包含引用定位信息:
```json
{
"answer": "...",
"citations": [
{
"chunk_index": 5,
"source": "规章制度.pdf",
"collection": "public_kb",
"page": 12,
"bbox": [100, 200, 500, 300],
"content": "切片内容预览最多300字..."
}
]
}
```
前端可通过 `GET /documents/{collection}/{source}/preview?chunk_index=N&context=3` 获取完整切片文本用于高亮定位。详细说明参见 [RAG 引用跳转-前端实现说明](docs/RAG引用跳转-前端实现说明.md)。
### 其他接口
| 接口 | 方法 | 说明 |
|------|------|------|
| `/sessions` | GET | 获取会话列表 |
| `/history/<id>` | GET | 获取会话历史 |
| `/session/<id>` | DELETE | 删除会话 |
| `/kb/list` | GET | 获取知识库列表 |
| `/kb/sync` | POST | 触发文档同步 |
| `/feedback` | POST | 提交反馈(点赞 / 点踩) |
## 技术架构
```
┌──────────────────────────────────────────────────────────────┐
│ 前端 (chat-ui / dev-ui) │
│ HTML + CSS + JS | Vue3 + Naive UI │
└────────────────────────────┬─────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ API 路由层 (api/) │
│ chat | document | kb | sync | session | feedback │
└────────────────────────────┬─────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Agentic RAG 引擎 (core/) │
│ │
│ 意图分析 ──→ 查询预处理 ──→ 混合检索 ──→ 云端Rerank │
│ │ │ │ │
│ │ 向量检索 ──┐ │ MMR去重 ──┘ │
│ │ BM25检索 ──┤ RRF │
│ │ ┘ 融合 │
│ │ │
│ └──→ 上下文构建 ──→ 自适应TopK ──→ LLM生成 ──→ 引用溯源 │
└────────────────────────────┬─────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ChromaDB | BM25索引 | FAISS(语义缓存) | SQLite │
│ │
│ 文档解析器 (parsers/) │
│ MinerU: PDF / DOCX / PPTX / 图片 │
│ Excel: Pandas 管道 | TXT: 纯文本 │
└──────────────────────────────────────────────────────────────┘
```
## 依赖库
| 库名 | 用途 |
|------|------|
| flask / gunicorn | Web 框架与 WSGI 服务器 |
| chromadb | 向量数据库 |
| sentence-transformers | 向量编码BGE-base-zh-v1.5 |
| rank-bm25 / jieba | BM25 关键词检索与中文分词 |
| faiss-cpu | FAISS 向量索引(语义缓存) |
| openai | LLM API 客户端(兼容 DashScope |
| optimum[onnxruntime] | 本地 Reranker ONNX 加速 |
| mineru | 文档解析PDF / DOCX / PPTX / 图片) |
| pandas / openpyxl | Excel 解析 |
| langchain-text-splitters | 语义分块 |
| watchdog | 文档变更监控 |
| python-dotenv | 环境变量管理 |
## 常见问题
**Q: docker-compose restart 后新环境变量不生效?**
`restart` 只是重启现有容器,不会重新读取 `.env.production`。修改环境变量后必须使用 `docker-compose up -d` 重建容器。
**Q: 云端 Reranker 超时或报错?**
检查 `RERANK_CLOUD_API_KEY``RERANK_CLOUD_BASE_URL` 配置,确认 DashScope API 可用。可设置 `RERANK_BACKEND=fallback` 实现云端优先、失败回退本地。
**Q: MMR 去重很慢?**
CPU 环境下设置 `MMR_USE_EMBEDDING=false`,使用文本 Jaccard 相似度替代语义向量计算,速度提升显著。
**Q: MinerU 解析失败?**
配置 `MINERU_API_TOKEN` 使用 MinerU 在线 API 作为备选。设置 `MINERU_PREFER_ONLINE=true` 优先使用在线解析(效果更好)。
## 文档
- [API 与后端对接规范](docs/API与后端对接规范.md)
- [RAG 引用跳转-前端实现说明](docs/RAG引用跳转-前端实现说明.md)
- [RAG 数据流程详解](docs/RAG数据流程详解.md)
- [MinerU 模型部署指南](docs/MinerU模型部署指南.md)
- [多向量库权限划分](docs/多向量库实现权限划分.md)
- [数据库设计文档](docs/数据库设计文档.md)
- [认证与权限配置指南](docs/认证与权限配置指南.md)
## License
MIT