# DocMind **Repository Path**: likai179/DocMind ## Basic Information - **Project Name**: DocMind - **Description**: DocMind是一个基于大语言模型(LLM)和检索增强生成(RAG)技术的智能文档分析工具,能够帮助用户快速分析和理解各种类型的文档内容,提供精准的问答服务。 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2025-05-21 - **Last Updated**: 2026-04-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 智能文档分析助手 ## 项目概述 智能文档分析助手是一个基于大语言模型(LLM)和检索增强生成(RAG)技术的智能文档分析工具,能够帮助用户快速分析和理解各种类型的文档内容,提供精准的问答服务。 ### 核心功能 - **多格式文档支持**:支持 PDF、Word(.doc/.docx)、CSV、TXT、Markdown 等多种文件格式 - **智能问答**:基于文档内容进行精准问答,提供引用来源 - **知识库管理**:支持上传、管理多个知识库文档 - **混合检索**:MMR 向量检索 + BM25Plus 关键词检索,提升召回效果 - **MMR + Sentence Window 组合检索**:结合最大边际相关性与句子窗口展开,兼顾相关性与上下文完整性 - **本地重排序**:使用 BGE-Reranker-Large 模型对检索结果进行语义评分 - **混合评分重排序**:将语义相似度分数与 BM25Plus 关键词匹配分数归一化后混合,再排序返回 Top-N - **动态权重**:根据查询类型(FACTUAL / OPINION / LIST)自动调整语义检索与关键词检索的权重 - **查询类型分类**:自动识别查询类型,匹配关键词驱动分类 - **查询扩展**:支持多查询扩展(MultiQueryRetriever),丰富检索表达 - **流式输出**:实时显示回答内容,带 `` 思考过程过滤 - **参数调节**:可调节生成长度、温度等参数,控制回答风格 - **配置热更新**:修改 `.env` 文件后,无需重启即可生效 - **自动化评估**:内置 RAG 评估 Pipeline,支持 Hit@K、MRR、NDCG 等指标 - **现代化界面**:双栏布局(左侧聊天 / 右侧参数设置),支持头像显示 - **自动深色模式**:跟随系统设置自动切换深色 / 浅色模式 - **结构化日志**:JSON 格式日志输出,支持 trace_id 全链路追踪和性能计时 ## 技术架构 ### 系统架构图 ``` ┌──────────────────────────────────────────────────────────────┐ │ 用户界面层 │ │ Gradio Web Interface (http://127.0.0.1:7002) │ │ doc_mind.py → View → gr.Blocks 双栏布局 │ ├──────────────────────────────────────────────────────────────┤ │ LLM 对话层 │ │ llm/chat.py: MyLLM (对话历史管理、流式响应) │ ├──────────────────────────────────────────────────────────────┤ │ 知识库 & 检索层 │ │ llm/knowledge.py: MyKnowledge │ │ ├── create_indexes(): 文档索引创建(Chroma + 父文档存储) │ │ ├── get_retrievers(): 获取检索器(含 MMR+SentenceWindow) │ │ ├── BatchedLocalEmbeddings: 批量嵌入封装 │ │ │ │ core/retriever/ │ │ ├── bm25_plus.py: BM25Plus 检索器(倒排索引 + IDF 评分) │ │ └── sentence_window.py: │ │ ├── SentenceWindowRetriever: 句子窗口检索器 │ │ ├── SentenceWindowStorage: 父文档持久化 + .npy 缓存 │ │ └── SentenceWindowExpander: 子文档→父文档批量展开 │ │ │ │ core/ranker/local_reranker.py: LocalReranker (bi-encoder) │ │ │ │ core/normalize/score_normalizer.py: │ │ ├── ScoreNormalizer: Min-Max 归一化 + 语义/关键词混合评分 │ │ └── QueryClassifier: 查询类型分类(FACTUAL/OPINION/LIST) │ │ │ │ core/loader/document_loader.py: DocumentLoader (多格式加载) │ ├──────────────────────────────────────────────────────────────┤ │ 配置热更新层 │ │ config/settings.py: Config (单例, 支持热更新) │ │ config/config_watcher.py: 文件轮询监听 (.env 变更检测) │ │ config/config_observer.py: 观察者发布-订阅模式 │ ├──────────────────────────────────────────────────────────────┤ │ 存储层 │ │ Chroma 向量数据库 → ./chroma/{collection_name}/ │ │ 父文档 JSON → ./chroma/parent_docs/{collection_name}_*.json │ │ 预计算 embedding → ./chroma/parent_docs/{collection_name}_*.npy│ │ 用户上传文档 → ./chroma/knowledge/ │ │ 评估报告 → ./evaluation/reports/ │ ├──────────────────────────────────────────────────────────────┤ │ 模型层 │ │ DeepSeek LLM (API 调用) │ │ BGE-Large-ZH-v1.5 (本地 Embedding, 512 tokens) │ │ BGE-Reranker-Large (本地 Cross-Encoder 重排序) │ └──────────────────────────────────────────────────────────────┘ ``` ### 检索流程详解 当用户发起一次查询时,系统按以下顺序处理: ``` 用户查询 │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 1. MMR 向量检索 (Chroma) │ │ - fetch_k=30 个候选文档 │ │ - lambda_mult 控制相关性/多样性平衡 │ └────────────────────────┬────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 2. Sentence Window 展开 │ │ - 加载预计算的 .npy 父文档 embedding │ │ - 批量计算余弦相似度,找最相似父文档 │ │ - 无 .npy 时自动回退到子文档 │ │ - 无父文档时回退到纯 MMR 模式 │ └────────────────────────┬────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 3. BM25Plus 关键词检索 │ │ - 倒排索引 + Robertson-Sparck Jones IDF │ │ - BM25Plus: +δ*log((|D|+1)/(freq+1)) 补偿短文档惩罚 │ └────────────────────────┬────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 4. Interleaved 合并去重 │ │ - 按排名交替插入向量文档和 BM25 文档 │ │ - 去除重复页面内容 │ │ - 返回 mmr_k 个文档 │ └────────────────────────┬────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 5. LocalReranker 压缩(可选) │ │ - Bi-encoder 计算 (query, doc) 语义分数 │ │ - BM25Plus 风格关键词匹配分数 │ │ - QueryClassifier 识别查询类型 │ │ - 动态权重(若启用)或固定权重归一化混合 │ │ - 按混合分数排序,返回 rerank_top_n 个 │ └────────────────────────┬────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 6. MultiQueryRetriever 查询扩展(可选) │ │ - 使用 LLM 生成多个子查询 │ │ - 分别检索后合并结果 │ └────────────────────────┬────────────────────────────────┘ │ ▼ LLM 最终回答 ``` ### 技术栈 | 技术 / 库 | 用途 | 版本 | |------------------------|-------------------------------|--------| | Python | 编程语言 | 3.12+ | | LangChain | LLM 应用开发框架 | 0.2+ | | LangChain-OpenAI | DeepSeek LLM 集成 | | | LangChain-HuggingFace | 本地 Embedding 集成 | | | LangChain-Chroma | 向量数据库集成 | | | Gradio | Web 界面框架 | 6.x | | Chroma | 向量数据库 | 0.5+ | | BGE-Large-ZH-v1.5 | 中文文本嵌入模型(本地) | 1.5 | | BGE-Reranker-Large | 文档重排序模型(本地) | | | DeepSeek | 大语言模型(API 调用) | | ## 快速开始 ### 环境要求 - Python 3.12 或更高版本 - Windows、macOS 或 Linux 操作系统 - 至少 8GB 内存 - DeepSeek API Key(从 https://platform.deepseek.com/ 获取) - 本地 Embedding 和 Reranker 模型(需手动下载) > 由于国内网络访问 HuggingFace 存在障碍,建议使用 ModelScope(魔搭社区)下载模型。 ### 安装步骤 1. **克隆项目** ```bash git clone <项目地址> cd doc_mind ``` 2. **创建并激活虚拟环境** ```bash # Windows python -m venv .venv .venv\Scripts\activate # macOS / Linux python3 -m venv .venv source .venv/bin/activate ``` 3. **安装依赖** ```bash pip install -r requirements.txt ``` 4. **下载模型** ```bash # Embedding 模型(BAAI/bge-large-zh-v1.5) python download/download_embedding.py # Reranker 模型(BAAI/bge-reranker-large) python download/download_reranker.py ``` 默认下载到 `C:/sft/model/`。如需修改,编辑对应脚本中的 `local_dir` 参数。 5. **配置环境变量** 复制 `.env.example` 为 `.env`: ```bash # 必需 deepseek_api_key=your_api_key_here deepseek_base_url=https://api.deepseek.com deepseek_model=deepseek-chat # 本地模型路径 local_embedding_model_path=C:/sft/model/BAAI/bge-large-zh-v1___5 local_reranker_model_path=C:/sft/model/BAAI/bge-reranker-large # 日志 LOG_TO_FILE=true ``` 6. **启动应用** ```bash python doc_mind.py ``` 浏览器访问 `http://127.0.0.1:7002` 即可使用。 ## 使用指南 ### 基本操作 1. 打开浏览器,进入 `http://127.0.0.1:7002` 2. **上传文档**:点击右侧 "📤 上传文档" 区域上传文件(支持 .pdf/.doc/.docx/.csv/.txt/.md) 3. **选择知识库**:上传后在下拉菜单中选择对应文档 4. **输入问题**:在底部文本框输入问题,按 Enter 发送 5. **查看回答**:AI 回复实时显示,自动过滤 `` 思考过程 6. **调整参数**:滑动条调节最大生成长度和温度 7. **清空对话**:点击 "🗑️ 清空对话" 清除聊天历史 8. **深色模式**:自动跟随系统主题切换 ### 日志查看 日志默认输出到控制台和 `./logs/app.log`,支持 JSON 结构化格式: ```json { "timestamp": "2026-04-02T10:30:00.000Z", "level": "INFO", "logger": "llm.knowledge", "message": "检索完成", "trace_id": "abc123", "context": {"retrieval_time_ms": 1523, "query_type": "FACTUAL"} } ``` ### 运行评估 ```bash # 快速评估(使用默认数据集) python evaluation/run_eval.py # 详细参数 python -m evaluation.evaluator --dataset guo_bin_handover --collection "文档名" --top-k 5 ``` 评估报告自动生成在 `evaluation/reports/` 目录下。 ## 项目结构 ``` doc_mind/ ├── doc_mind.py # 应用入口,全局日志 & 异常处理 │ ├── config/ # 配置管理 │ ├── __init__.py │ ├── settings.py # Config 单例类,.env 加载,支持热更新 │ ├── config_observer.py # 配置发布-订阅(观察者)接口 │ └── config_watcher.py # .env 文件轮询监听器 │ ├── core/ # RAG 核心组件 │ ├── __init__.py │ ├── retriever/ │ │ ├── bm25_plus.py # BM25Plus 检索器(倒排索引 + BM25Plus 评分) │ │ └── sentence_window.py # 句子窗口:Retriever / Storage / Expander │ ├── ranker/ │ │ └── local_reranker.py # 本地 BGE-Reranker 封装 │ ├── normalize/ │ │ └── score_normalizer.py # 分数归一化 + 查询类型分类器 │ └── loader/ │ └── document_loader.py # 多格式文档加载器 │ ├── llm/ # LLM 对话与知识库 │ ├── __init__.py │ ├── chat.py # MyLLM(对话历史、流式响应、LLM Chain 组装) │ └── knowledge.py # MyKnowledge(知识库管理、索引创建、检索器获取) │ # + MMRWithSentenceWindowRetriever + BatchedLocalEmbeddings │ ├── ui/ # UI 组件 │ ├── __init__.py │ ├── view.py # View 类,Gradio Blocks 构建 │ └── css.py # CSS 样式(双栏布局 + 深色模式) │ ├── utils/ # 工具模块 │ ├── __init__.py │ ├── logger.py # 结构化日志(ColoredFormatter / JSONFormatter / LogTimer) │ └── tracer.py # trace_id 上下文管理 │ ├── evaluation/ # 自动化评估 │ ├── dataset.py # 测试数据集管理(TestCase / EvaluationDataset) │ ├── evaluator.py # 评估执行器(RAGEvaluator / EvalConfig)+ CLI 入口 │ ├── metrics.py # 评估指标(Hit@K / MRR / NDCG / QueryType) │ ├── reporter.py # 报告生成器(JSON / HTML / 历史趋势) │ ├── run_eval.py # 评估快速启动脚本 │ ├── reports/ # 评估报告输出目录(不提交) │ └── test_data/ # 测试数据集 │ └── guo_bin_handover.json │ ├── download/ # 模型下载脚本 │ ├── download_embedding.py │ └── download_reranker.py │ ├── chroma/ # 数据存储(不提交) │ ├── knowledge/ # 用户上传的原始文档 │ ├── {collection_name}/ # Chroma 向量数据库(按文档名 MD5 命名) │ └── parent_docs/ # 父文档 JSON + 预计算 .npy embedding │ ├── .env.example # 环境变量模板 ├── .env # 环境变量(不提交) ├── requirements.txt ├── CLAUDE.md # Claude Code 项目指南 └── README.md # 本文档 ``` ### 向后兼容 所有旧文件保留为兼容层,可继续使用旧导入路径: | 旧导入路径 | 新导入路径 | 状态 | |-------------------------------------|-------------------------------------|------| | `from bm25_plus_retriever import` | `from core.retriever import` | 兼容 | | `from local_reranker import` | `from core.ranker import` | 兼容 | | `from score_normalizer import` | `from core.normalize import` | 兼容 | | `from llm import DocumentLoader` | `from core.loader import` | 兼容 | | `from config import Config` | `from config.settings import` | 兼容 | | `from ui_components import View` | `from ui import View` | 兼容 | ## 配置说明 ### 环境变量配置(`.env`) | 环境变量 | 说明 | 默认值 | |---------------------------|------------------------|-------------------------------------| | `deepseek_api_key` | DeepSeek API 密钥 | (必填) | | `deepseek_base_url` | DeepSeek API 地址 | `https://api.deepseek.com` | | `deepseek_model` | DeepSeek 模型名称 | `deepseek-chat` | | `local_embedding_model_path` | Embedding 模型路径 | `C:/sft/model/BAAI/bge-large-zh-v1___5` | | `local_reranker_model_path` | Reranker 模型路径 | `C:/sft/model/BAAI/bge-reranker-large` | | `LOG_TO_FILE` | 是否输出日志到文件 | `true` / `false` | ### RAG 检索配置 > **说明**:默认值列中,"代码默认值"指用户未在 `.env` 中配置时代码实际使用的值;"推荐配置值"指 `.env.example` 中给出的示例值(对应本项目已启用该功能的实际配置)。 | 配置项 | 说明 | 代码默认值 | 推荐配置值 | |---------------------------|---------------------------|---------|---------| | `use_sentence_window` | 是否启用句子窗口检索 | `false` | `true` | | `child_chunk_size` | 句子窗口子文档大小(字符) | `200` | `200` | | `parent_chunk_size` | 句子窗口父文档大小(字符) | `800` | `800` | | `parent_chunk_overlap` | 父文档重叠大小(字符) | `150` | `150` | | `query_expansion_enabled` | 是否启用查询扩展(MultiQuery) | `false` | `true` | | `query_expansion_num` | 查询扩展子查询数量 | `3` | `3` | | `dynamic_weight_enabled` | 是否启用动态权重(按查询类型) | `false` | `true` | | `default_vector_weight` | 默认向量检索权重 | `0.5` | `0.5` | | `default_bm25_weight` | 默认 BM25 权重 | `0.5` | `0.5` | | `bm25_k1` | BM25Plus k1 参数 | `1.5` | `1.5` | | `bm25_b` | BM25Plus b 参数 | `0.75` | `0.75` | | `bm25_delta` | BM25Plus delta 参数(短文档补偿)| `1.0` | `1.0` | | `semantic_weight` | Reranker 语义分数权重 | `0.7` | `0.7` | | `keyword_weight` | Reranker 关键词分数权重 | `0.3` | `0.3` | | `mmr_k` | MMR 返回文档数 | `10` | `10` | | `mmr_fetch_k` | MMR 候选文档数 | `30` | `30` | | `mmr_lambda_mult` | MMR 多样性参数(0=高多样,1=高相关)| `0.75` | `0.75` | | `rerank_top_n` | 重排序返回文档数 | `5` | `5` | | `embedding_batch_size` | Embedding 批量处理大小 | `32` | `32` | | `index_doc_batch_size` | 索引文档批量处理大小(Chroma 写入)| `32` | `32` | ### 查询类型与动态权重 启用 `dynamic_weight_enabled=true` 后,系统自动识别查询类型并应用对应权重: | 查询类型 | 特征关键词示例 | 向量权重 | BM25 权重 | MMR λ | |---------|-----------------------------------|---------|---------|--------| | FACTUAL | 是什么、如何、为什么、方法、步骤 | 0.3 | 0.7 | 0.85 | | OPINION | 认为、比较、优缺点、推荐、好不好 | 0.7 | 0.3 | 0.75 | | LIST | 有哪些、列举、包括、种类 | 0.5 | 0.5 | 0.50 | | UNKNOWN | (无匹配关键词) | 0.5 | 0.5 | 0.75 | ### 配置热更新 支持的配置项修改 `.env` 后自动生效(1 秒轮询间隔),无需重启应用: ``` embedding_batch_size, index_doc_batch_size, semantic_weight, keyword_weight, dynamic_weight_enabled, use_sentence_window, query_expansion_enabled, query_expansion_num, bm25_k1, bm25_b, bm25_delta, default_vector_weight, default_bm25_weight, child_chunk_size, parent_chunk_size, parent_chunk_overlap, mmr_k, mmr_fetch_k, mmr_lambda_mult, rerank_top_n ``` ## 自动化评估 ### 评估指标 | 指标 | 说明 | |------------------|----------------------------------------| | Hit@K | Top-K 检索结果命中率(存在期望文档即命中) | | MRR | 平均倒数排名(Mean Reciprocal Rank) | | NDCG@K | 归一化折损累计增益(考虑排名顺序的加权命中) | | 查询类型分类准确率 | QueryClassifier 预测准确率 | ### 数据集格式 测试数据集为 JSON 文件,位于 `evaluation/test_data/`: ```json { "name": "guo_bin_handover", "description": "郭彬交接文档测试数据集", "test_cases": [ { "id": "handover_001", "query": "交接文档主要包含哪些工作内容?", "expected_sources": ["./chroma/knowledge/郭彬交接文档.pdf"], "query_type": "LIST" } ] } ``` ### 评估结果示例 基于 `guo_bin_handover.json` 数据集(10 个测试用例): | 指标 | 结果 | |---------|----------| | Hit@1 | 100.00% | | Hit@3 | 100.00% | | Hit@5 | 100.00% | | MRR | 1.0000 | | NDCG@3 | 1.0000 | | NDCG@5 | 1.0000 | ## 常见问题 ### 1. 上传文档后知识库中看不到 - 确认文档已上传到 `chroma/knowledge/` 目录 - 确认文档格式受支持(.pdf/.doc/.docx/.csv/.txt/.md) - 刷新页面或重启应用 ### 2. 回答质量不佳 - 确认已选择正确的知识库 - 降低温度参数(temperature)以提高准确性 - 确认 DeepSeek API 正常工作 - 检查文档内容是否清晰可辨 ### 3. 启动失败 - 检查 `.env` 中 `deepseek_api_key` 是否正确 - 检查 Embedding / Reranker 模型路径是否正确 - 确认模型文件已下载(检查 `C:/sft/model/BAAI/` 目录) - 检查端口 7002 是否被占用 ### 4. 模型下载失败 - 使用 ModelScope(魔搭社区)代替 HuggingFace - 运行 `python download/download_embedding.py` 下载 Embedding 模型 - 运行 `python download/download_reranker.py` 下载 Reranker 模型 ### 5. 检索速度慢 - 确认已预计算 .npy 父文档 embedding(首次检索后自动生成) - 调整 `embedding_batch_size` 和 `index_doc_batch_size` 提高吞吐量 - 减少文档大小或拆分大型文档 - 使用 GPU 加速 Embedding / Reranker 模型 ## 扩展与定制 ### 添加新文件格式 1. 在 `config/settings.py` 的 `__FILE_TYPES` 列表添加新扩展名(如 `.xlsx`) 2. 在 `core/loader/document_loader.py` 添加对应加载器 ### 自定义检索策略 | 修改目标 | 配置文件 | |-------------------------------|--------------------------| | MMR 参数、权重配比 | `.env` | | 重排序逻辑、语义/关键词混合方式 | `core/ranker/local_reranker.py` | | 查询类型关键词、动态权重映射 | `core/normalize/score_normalizer.py` | | 句子窗口大小 | `.env` | ### 自定义日志 - 修改 `utils/logger.py` 调整日志格式和输出位置 - 设置 `LOG_TO_FILE=true` 输出到 `./logs/app.log` - 生产环境设置 `json_format=True` 输出 JSON 格式 ## 依赖管理 项目依赖详见 `requirements.txt`,核心依赖包括: - **LangChain** + **LangChain-Core**:LLM 应用框架 - **LangChain-OpenAI**:DeepSeek 模型集成 - **LangChain-HuggingFace**:本地 Embedding 模型集成 - **LangChain-Chroma**:向量数据库集成 - **Gradio**:Web 界面框架 - **Chroma**:向量数据库 - **Transformers**:模型推理框架 - **Sentence-Transformers**:文本嵌入模型 ## 安全注意事项 1. **API Key 保护**:不要将 `.env` 提交到版本控制系统 2. **文档安全**:仅上传和处理可信文档,敏感文档使用后及时清理 3. **网络安全**:默认仅本地访问(127.0.0.1:7002),远程访问需确保网络安全 --- **版本**:5.0.0 **最后更新**:2026-04-02