多库检索与存储修复: - 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 - 更新多篇现有文档
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. 克隆仓库
git clone https://git.njtobaccosales.top/jhzhang/rag.git
cd rag
2. 创建虚拟环境
python -m venv venv
# Windows
venv\Scripts\activate
# Linux / macOS
source venv/bin/activate
3. 安装依赖
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 时不需要) |
mkdir models
huggingface-cli download BAAI/bge-base-zh-v1.5 --local-dir ./models/bge-base-zh-v1.5
5. 配置环境变量
cp config.example.py config.py
# 编辑 config.py 或创建 .env 文件
关键配置项(通过环境变量或 .env 文件设置):
# ---- 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. 启动服务
# 开发模式
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/ 目录下。
构建与启动
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 快速更新:
# 复制修改后的文件到容器
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 数组包含引用定位信息:
{
"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 引用跳转-前端实现说明。
其他接口
| 接口 | 方法 | 说明 |
|---|---|---|
/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 优先使用在线解析(效果更好)。
文档
License
MIT