465 lines
20 KiB
Markdown
465 lines
20 KiB
Markdown
# RAG Agent - 模块化知识库问答系统
|
||
|
||
基于本地向量模型 + Chroma 向量数据库 + 云端 Reranker + Qwen API 的智能知识库问答系统,支持 Agentic RAG 多源检索、意图分析、混合检索与多样性去重。
|
||
|
||
> **最新版本**: v7.0.0(云端 Reranker、性能优化、Agentic 引擎拆分、Docker 生产部署)
|
||
|
||
## 功能特性
|
||
|
||
### v7.0.0(当前版本)
|
||
|
||
- **云端 Reranker**:接入 DashScope qwen3-rerank API 替代本地 CrossEncoder,CPU 服务器上重排序耗时从 ~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-reranker(ONNX 加速),可切换
|
||
- **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(云端) | 替代本地 CrossEncoder,CPU 环境显著提升 |
|
||
| 向量编码 | 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
|