# dataset_rag **Repository Path**: nullindex/dataset_rag ## Basic Information - **Project Name**: dataset_rag - **Description**: 掌鉴智库 (RAG) 是一款基于检索增强生成 (Retrieval-Augmented Generation) 技术的企业级知识库问答系统。本项目致力于构建一套集“私有知识库精准问答、实时联网信息补充、多维度结果优化”于一体的全流程智能客服解决方案,旨在实现核心知识的私有化管理、问答结果的高精准度以及业务场景的灵活适配。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-08-23 - **Last Updated**: 2026-08-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 掌鉴智库 RAG (Dataset RAG) 基于 RAG(检索增强生成)架构的产品知识库智能问答系统,支持文档自动导入、多路混合检索、重排序与流式答案生成。 ## 项目背景 **掌鉴智库** 是一个面向产品文档的智能问答系统。核心场景:企业将产品说明书、用户手册等 PDF 文档上传到系统,系统自动完成解析、向量化、入库;终端用户通过自然语言对话方式查询产品操作方式、故障排除等信息,系统从知识库中检索相关文档片段并生成准确答案。 典型使用场景: - 用户上传「HAK 180 烫金机使用说明书.pdf」→ 系统自动入库 - 终端提问「HAK 180 烫金机怎么调节温度?」→ 系统检索相关片段 → LLM 生成答案 ## 整体架构 ```mermaid flowchart LR subgraph Import["文档导入流水线 (端口 8000)"] A[PDF上传] --> B[MinerU解析
PDF→MD] B --> C[图片处理
上传MinIO] C --> D[文档分块
语义切割] D --> E[项目名识别
LLM提取] E --> F[BGE-M3向量化
稠密+稀疏] F --> G[Milvus入库] end subgraph Query["查询检索流水线 (端口 8001)"] H[用户提问] --> I[项目名确认
LLM提取+向量校验] I --> J1[向量检索
dense+sparse] I --> J2[HyDE检索
假设性文档] I --> J3[网络搜索
百练MCP] J1 --> K[RRF融合排序] J2 --> K J3 --> K K --> L[BGE Reranker精排
+断崖截断] L --> M[LLM答案生成
流式SSE/非流式] end G -.-> J1 ``` ## 项目结构 ``` dataset_rag/ ├── app/ │ ├── clients/ # 外部服务客户端 │ │ ├── milvus_utils.py # Milvus 向量数据库(混合搜索、chunk查询) │ │ ├── mongo_history_utils.py # MongoDB 历史对话存取 │ │ ├── minio_utils.py # MinIO 对象存储 │ │ └── neo4j_utils.py # Neo4j 图数据库 │ ├── conf/ # 配置模块(@dataclass + .env) │ │ ├── lm_config.py # LLM 模型配置 │ │ ├── embedding_config.py # BGE-M3 向量模型配置 │ │ ├── milvus_config.py # Milvus 连接配置 │ │ ├── minio_config.py # MinIO 连接配置 │ │ ├── reranker_config.py # BGE Reranker 重排序模型配置 │ │ ├── bailian_mcp_config.py # 百练 MCP 网络搜索配置 │ │ └── mineru_config.py # MinerU PDF 解析配置 │ ├── core/ # 核心工具 │ │ └── load_prompt.py # Prompt 模板加载与变量渲染 │ ├── eval/ # 评测模块(Ragas) │ │ ├── README.md # 评测使用说明 │ │ └── run_eval.py # Ragas 评测脚本 │ ├── import_process/ # 文档导入流水线(LangGraph) │ │ ├── agent/ │ │ │ ├── main_graph.py # 工作流编排 │ │ │ ├── state.py # 状态定义 │ │ │ └── nodes/ # 7个导入节点 │ │ └── api/ │ │ └── import_server.py # FastAPI 导入服务(端口 8000) │ ├── lm/ # 语言模型工具 │ │ ├── embedding_utils.py # BGE-M3 向量生成(稠密+稀疏,单例模式) │ │ ├── lm_utils.py # LLM 客户端(OpenAI 兼容接口,缓存模式) │ │ └── reranker_utils.py # BGE Reranker 重排序模型加载 │ ├── query_process/ # 查询检索流水线(LangGraph) │ │ ├── agent/ │ │ │ ├── main_graph.py # 工作流编排 │ │ │ ├── state.py # 状态定义 │ │ │ └── nodes/ # 7个查询节点 │ │ └── api/ │ │ └── query_server.py # FastAPI 查询服务(端口 8001) │ ├── test/ # 测试 │ │ └── test_import_main_graph.py # 导入全流程测试 │ ├── tool/ # 工具脚本 │ │ └── download_reranker.py # 模型下载 │ └── utils/ # 通用工具 │ ├── log_utils.py # 日志(loguru) │ ├── path_util.py # 项目路径常量 │ ├── sse_utils.py # SSE 服务端推送 │ ├── task_utils.py # 任务状态管理 │ └── ... ├── prompts/ # Prompt 模板(见下方说明) ├── output/ # 导入中间产物(按日期/任务ID组织,可定期清理) ├── .env_example # 环境变量模板 ├── pyproject.toml # 项目依赖配置 └── uv.lock # 依赖锁文件 ``` ## Prompt 模板 系统核心行为由 `prompts/` 目录下的 6 个模板驱动: | 文件 | 调用节点 | 用途 | |------|----------|------| | `rewritten_query_and_itemnames.prompt` | node_item_name_confirm | 根据历史对话提取商品名 + 重写问题 | | `hyde_prompt.prompt` | node_search_embedding_hyde | 生成假设性答案用于 HyDE 检索 | | `answer_out.prompt` | node_answer_output | 基于检索上下文 + 历史生成最终答案 | | `item_name_recognition.prompt` | node_item_name_recognition | 导入时从文档分块中提取商品名 | | `image_summary.prompt` | node_md_img | 对文档中的图片生成文字摘要 | | `product_recognition_system.prompt` | 系统级 | 商品识别系统提示词 | 模板使用 Python `str.format(**kwargs)` 渲染变量占位符,通过 `app/core/load_prompt.py` 统一加载。 ## 数据库设计 ### Milvus 向量库 Collection | Collection | 用途 | 关键字段 | |------------|------|----------| | `kb_chunks` | 文档切片存储 | `chunk_id`(INT64 PK), `dense_vector`, `sparse_vector`, `content`, `file_title`, `title`, `parent_title`, `item_name` | | `kb_item_names` | 商品名向量索引 | `item_name`, `dense_vector`, `sparse_vector` | | `kb_graph_entity_names` | 知识图谱实体名(预留) | — | ### MongoDB 对话历史 Collection 存储用户与助手的对话记录,字段包括:`session_id`, `role`(user/assistant), `text`, `rewritten_query`, `item_names`, `ts`(时间戳)。 ### MinIO 对象存储 存储从文档中提取的图片文件,按 `minio_img_dir` 配置的目录组织。 ## 核心流程 ### 文档导入流水线(7 节点) ``` PDF上传 → node_entry(校验) → node_pdf_to_md(MinerU解析) → node_md_img(图片处理→MinIO) → node_document_split(语义分块) → node_item_name_recognition(LLM提取商品名) → node_bge_embedding(稠密+稀疏向量化) → node_import_milvus(入库) ``` 分块策略: - 粗粒度:基于 Markdown 标题层级切分,保证语义完整 - 细粒度:`RecursiveCharacterTextSplitter` 二次切分,单 chunk 上限 2000 字符(约 512-1500 token),下限 500 字符(短 chunk 合并) - 无标题文档自动生成默认标题兜底 ### 查询检索流水线(7 节点) ``` 用户提问 ↓ node_item_name_confirm ── 无明确商品名 → node_answer_output(返回引导提示) ↓ 有明确商品名 三路并行召回 ─┬─ node_search_embedding (问题向量 → Milvus 混合搜索, 权重 0.8:0.2) ├─ node_search_embedding_hyde (LLM生成假设答案 → 问题+答案向量检索, 权重 0.9:0.1) └─ node_web_search_mcp (百练 MCP 联网搜索) ↓ node_rrf (同源三路 Reciprocal Rank Fusion, 权重 1.0:1.0:1.0) ↓ node_rerank (RRF+Web合并 → BGE Reranker Cross-Encoder 精排 → 断崖截断动态 Top-K) ↓ node_answer_output (组装 Prompt → LLM生成 → SSE流式推送 / 同步返回) ``` 断崖截断算法参数: - `RERANK_MAX_TOPK = 10`(硬上限) - `RERANK_MIN_TOPK = 1`(保底值) - `RERANK_GAP_RATIO = 0.25`(相对断崖阈值) - `RERANK_GAP_ABS = 0.5`(绝对断崖阈值) ## 技术栈 | 类别 | 技术 | 说明 | |------|------|------| | **框架** | FastAPI + Uvicorn | Web API 服务 | | **工作流** | LangGraph | 有状态 DAG 工作流编排 | | **向量数据库** | Milvus | 混合向量检索(稠密 COSINE + 稀疏 IP) | | **嵌入模型** | BGE-M3 (BAAI) | 稠密 1024 维 + 稀疏向量双表示,内置 L2 归一化 | | **重排序** | BGE Reranker (FlagEmbedding) | Cross-Encoder 精排,支持归一化打分 | | **LLM** | 通义千问 (兼容 OpenAI API) | 意图识别、HyDE 生成、答案润色 | | **对象存储** | MinIO | 文档图片存储 | | **历史记录** | MongoDB | 对话历史持久化 | | **PDF 解析** | MinerU (magic-pdf) | PDF → Markdown 高精度解析 | | **图数据库** | Neo4j | 知识图谱存储(可选) | | **网络搜索** | 百练 MCP (Bailian) | 联网搜索补充外部信息 | | **评测** | Ragas 0.4.3 | RAG 检索层+生成层质量评测 | ## 快速开始 ### 环境要求 - Python >= 3.12 - Milvus 向量数据库 - MongoDB - MinIO - Neo4j(可选) ### 启动依赖服务(Docker) ```bash # Milvus docker run -d --name milvus-standalone \ -p 19530:19530 -p 9091:9091 \ milvusdb/milvus:latest # MongoDB docker run -d --name mongo \ -p 27017:27017 \ mongo:7 # MinIO docker run -d --name minio \ -p 9000:9000 -p 9001:9001 \ -e MINIO_ROOT_USER=minioadmin -e MINIO_ROOT_PASSWORD=minioadmin \ minio/minio server /data --console-address ":9001" ``` ### 安装依赖 ```bash git clone cd dataset_rag # 使用 uv 管理依赖(推荐) uv sync # 或使用 pip pip install -e . ``` ### 配置环境变量 ```bash cp .env_example .env # 编辑 .env 文件,填入对应的 API Key 和服务地址 ``` 核心配置项: | 变量 | 说明 | |------|------| | `ALIBABA_API_KEY` / `ALIBABA_BASE_URL` | 通义千问 API 配置 | | `LLM_DEFAULT_MODEL` | 默认 LLM 模型名(如 `qwen3-32b`) | | `LLM_DEFAULT_TEMPERATURE` | LLM 温度参数(默认 0.1) | | `MILVUS_URL` | Milvus 服务地址(如 `http://localhost:19530`) | | `CHUNKS_COLLECTION` | 切片集合名(默认 `kb_chunks`) | | `ITEM_NAME_COLLECTION` | 商品名集合名(默认 `kb_item_names`) | | `MONGO_URL` / `MONGO_DB_NAME` | MongoDB 连接配置 | | `MINIO_ENDPOINT` / `MINIO_ACCESS_KEY` / `MINIO_SECRET_KEY` | MinIO 配置 | | `BGE_M3_PATH` | BGE-M3 模型路径(本地路径或 `BAAI/bge-m3` 自动下载) | | `BGE_DEVICE` | 运行设备(`cpu` 或 `cuda:0`) | | `BGE_FP16` | 是否开启半精度(GPU 建议 1,CPU 必须 0) | | `BGE_RERANKER_LARGE` | BGE Reranker 模型路径 | | `BGE_RERANKER_DEVICE` | Reranker 运行设备 | | `BGE_RERANKER_FP16` | Reranker 半精度开关 | | `MCP_DASHSCOPE_BASE_URL` | 百练 MCP 网络搜索地址 | | `MINERU_API_TOKEN` / `MINERU_BASE_URL` | MinerU PDF 解析服务 | ### 启动服务 ```bash # 启动文档导入服务(端口 8000) python -m app.import_process.api.import_server # 启动查询服务(端口 8001) python -m app.query_process.api.query_server ``` ### API 端点 **导入服务 (端口 8000):** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/import` | 文件上传页面 | | POST | `/upload` | 上传文件并启动异步导入流程 | | GET | `/status/{task_id}` | 轮询查询导入任务进度(返回 done_list / running_list) | **查询服务 (端口 8001):** | 方法 | 路径 | 说明 | |------|------|------| | GET | `/health` | 健康检查 | | GET | `/chat.html` | 对话页面 | | POST | `/query` | 发起提问(`is_stream=true` 开启流式) | | GET | `/stream/{session_id}` | SSE 长连接,实时接收流式答案 | | GET | `/history/{session_id}` | 查询历史对话(支持 `limit` 参数) | | DELETE | `/history/{session_id}` | 清除指定会话的历史记录 | ## 测试 ```bash # 导入全流程测试(需要 Milvus + BGE-M3 模型可用) python -m app.test.test_import_main_graph # 各节点也支持独立测试 python -m app.query_process.agent.nodes.node_item_name_confirm python -m app.query_process.agent.nodes.node_search_embedding python -m app.query_process.agent.nodes.node_search_embedding_hyde python -m app.query_process.agent.nodes.node_web_search_mcp python -m app.query_process.agent.nodes.node_rrf python -m app.query_process.agent.nodes.node_rerank python -m app.query_process.agent.nodes.node_answer_output ``` ## 评测 ```bash # 1. 编辑评测数据集 app/eval/testset.json # 2. 运行评测 python app/eval/run_eval.py # 3. 查看结果 app/eval/eval_result.json ``` 评测指标: | 指标 | 评估层 | 含义 | |------|--------|------| | `context_precision` | 检索层 | 相关文档是否排在检索结果前列 | | `context_relevance` | 检索层 | 检索结果与问题的相关性比例 | | `faithfulness` | 生成层 | 答案是否忠实于检索上下文(有无编造) | | `answer_correctness` | 生成层 | 答案与标注答案的一致性 | ## 项目特点 1. **多路召回融合**:向量检索 + HyDE 假设性检索 + 网络搜索,三路并行召回提升覆盖率 2. **混合向量检索**:BGE-M3 生成的稠密向量 + 稀疏向量,在 Milvus 中执行加权混合搜索 3. **断崖截断算法**:RRF 融合 + BGE Reranker 精排后,通过相对/绝对阈值动态确定 Top-K,避免低质文档混入 4. **流式输出**:基于 SSE(Server-Sent Events)实现答案逐字推送,支持中途断开 5. **项目名识别**:LLM 提取项目名 → Milvus 向量校验 → 评分分级(≥0.85 确认 / ≥0.6 可选 / <0.6 忽略),解决指代消歧和模糊提问 6. **完整的评测体系**:基于 Ragas 框架的检索层 + 生成层量化评估,支持自定义标注数据集 ## 开发注意事项 ### 模型加载 - **BGE-M3 模型较大(~2GB)**,首次运行时若未配置本地路径则会自动从 HuggingFace 下载 - 所有模型采用**单例模式**(`_bge_m3_ef`, `_reranker_model`, `_llm_client_cache`),避免重复加载 - LLM 客户端按 `(model, json_mode)` 元组缓存,不同配置互不影响 ### CPU vs GPU | 配置 | BGE_DEVICE | BGE_FP16 | 说明 | |------|-----------|----------|------| | GPU | `cuda:0` | `1` | 半精度加速,显存要求 ~4GB | | CPU | `cpu` | `0` | 单精度(FP32),内存要求 ~4GB | ### 目录说明 - `output/` — 导入流程中间产物(PDF→MD 转换结果、图片等),按 `日期/任务ID/` 组织,可定期清理 - `.venv/` — Python 虚拟环境(uv 管理) - `.env` — 敏感配置,**不要提交到 Git** ### 分块参数调整 在 `node_document_split.py` 中调整: - `DEFAULT_MAX_CONTENT_LENGTH = 2000` — 单 chunk 最大字符数 - `MIN_CONTENT_LENGTH = 500` — 短 chunk 合并阈值