Skip to content

Repository files navigation

DocMind · 智心文档

基于 LangChain + LangGraph + Chainlit + FAISS 的中文 RAG 与工具调用 Agent。 一次部署, 上传任意 PDF / TXT, 即可在 Web 上问答 + 自动调用计算器。

Python 3.11+ LangGraph DeepSeek License: MIT GitHub stars


1. 项目亮点

维度 实现
混合检索 FAISS 向量召回 + BM25 关键词召回 → RRF 倒数排名融合 → BGE Reranker 精排 Top-3
智能体路由 LangGraph StateGraph + ToolNode 构建循环状态机, 工具调用完全可观测
中文优化 Embedding 选型 BAAI/bge-small-zh-v1.5 (官方 query 检索指令前缀) + Reranker 选 BAAI/bge-reranker-base
Web UI Chainlit 原生 Step 折叠, 流式输出, /trace 调试命令直接看检索流水
离线友好 模型按文件 MD5 缓存, 二次启动 10x 提速; 切换 HF_HUB_OFFLINE=1 可断网运行
生产级鲁棒 LLM 调用走 tenacity 指数退避重试 3 次, 仅对可恢复错误触发

2. 界面预览

前端演示对话

上传 PDF 后, Agent 会自主决定调用 retrieval_tool (检索知识库) 或 calculator_tool (数值计算), 并以折叠 Step 形式实时展示中间推理过程。


3. 文件目录

DocMind/
├── README.md                      # 本文件
├── LICENSE                        # MIT 协议
├── .gitignore                     # Git 忽略配置
│
├── app/                           # Web UI 入口
│   ├── __init__.py
│   └── main.py                    # Chainlit Web UI
│
├── core/                          # 核心库 (业务无关, 可单独导入复用)
│   ├── __init__.py
│   ├── data_loader.py             # PDF / TXT 加载 + RecursiveCharacterTextSplitter
│   ├── vector_store.py            # FAISS 向量库 + BGE Embedding
│   ├── hybrid_retriever.py        # 混合检索 (向量 + BM25 + RRF + Reranker)
│   ├── model_pool.py              # 模型单例 + FAISS MD5 磁盘缓存
│   └── agent_graph.py             # LangGraph 状态机 + 工具定义 + LLM 重试
│
├── scripts/                       # 工具脚本
│   ├── __init__.py
│   └── evaluate_retriever.py      # 离线评估 (Hit Rate@K / MRR)
│
├── docs/                          # 设计文档 + 截图
│   ├── PRD-1.md                   # 产品需求文档 (含 V1.1.2 变更记录)
│   ├── IMPLEMENTATION_GUIDE.md    # 实现指南 (阶段任务与验收标准)
│   ├── chainlit.md                # Chainlit 欢迎语模板 (参考)
│   └── 前端演示对话.png            # Web UI 演示截图
│
├── .env.example                   # 环境变量模板 (复制为 .env 后填入真实 Key)
├── requirements.txt               # Python 依赖列表
│
├── setup_env.bat                  # cmd.exe 一键环境变量 + PYTHONPATH
├── setup_env.ps1                  # PowerShell 一键环境变量 + PYTHONPATH
│
├── test_queries.json              # 离线评估用的 10 条测试 Q&A
├── 公司休假管理制度-示例.pdf        # 示例文档 (可删除, 运行时上传任意 PDF 即可)
│
├── hub/                           # [自动生成] HuggingFace 模型缓存 (~1.3 GB)
├── faiss_index_cache/             # [自动生成] FAISS 索引按文件 MD5 缓存
└── .chainlit/                     # [自动生成] Chainlit 运行时配置

三个带 [自动生成] 标记的目录已加入 .gitignore, 首次运行时会自动创建。


4. 快速开始

4.1 环境要求

  • Python 3.11+ (本项目在 3.11 验证)
  • 操作系统: Windows 10/11, macOS, Linux
  • 磁盘空间: 约 2 GB (主要是 Embedding + Reranker 模型)
  • 网络: 首次运行需联网下载模型; 之后可断网运行

4.2 安装步骤

# 1) 克隆项目到本地
git clone https://github.com/cckais/DocMind.git
cd DocMind

# 2) 创建并激活 conda 环境 (推荐)
conda create -n docmind python=3.11
conda activate docmind

# 3) 安装依赖
pip install -r requirements.txt

# 4) 配置环境变量
#    Windows cmd:
copy .env.example .env
#    然后编辑 .env, 填入你的 DEEPSEEK_API_KEY

# 5) 设置 HuggingFace 缓存 (国内用户必做, 海外用户可跳过)
#    Windows cmd:
setup_env.bat
#    PowerShell:
#    . .\setup_env.ps1

4.3 启动 Web UI

chainlit run app\main.py -w

注意: chainlit run 只接受 .py 文件路径, 不接受 app.main 这种模块路径。 Windows 也可用正斜杠 app/main.py。 启动前请确保 setup_env.bat / setup_env.ps1 已执行, 否则 core.* 导入会失败。

浏览器自动打开 http://localhost:8000, 进入对话界面后:

  1. 点输入框的 附件按钮, 上传一份 PDF / TXT
  2. 等 "知识库构建完成" 提示
  3. 直接问问题, 例如:
    • "年假可以休几天?" → 自动调用 retrieval_tool
    • "1+1 等于几?" → 自动调用 calculator_tool
    • "我有 5 天年假, 加上前后周末能休几天?" → 先 retrieval_tool 取规则, 再 calculator_tool 计算
    • "今天天气如何?" → 拒答 (知识库中未找到)

4.4 跑离线评估

python -m scripts.evaluate_retriever 公司休假管理制度-示例.pdf

期望看到:

================================================================
  检索器离线评估对比 (Hit Rate@K / MRR)
================================================================
指标                  纯向量 (FAISS)    混合 (+BM25+RRF+Rerank)   提升
Hit Rate@1                30.0%                  40.0%       +10.0pp
Hit Rate@3                60.0%                  60.0%        +0.0pp
MRR                       0.433                  0.483        +5.0pp
平均耗时 (ms)               13.0                 1210.9      +1197.9
================================================================

跑命令前必须先执行 setup_env.bat / setup_env.ps1, 否则会因找不到 core.* 模块而失败。


5. 配置说明

5.1 .env 文件 (必填)

# DeepSeek API 配置
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
DEEPSEEK_API_BASE=https://api.deepseek.com
DEEPSEEK_MODEL=deepseek-v4-flash

DeepSeek 开放平台 注册即可获取 API Key。

5.2 HuggingFace 环境变量 (推荐)

通过 setup_env.bat / setup_env.ps1 一键设置。详见 PRD §7

变量 推荐值 作用
HF_HOME 项目根目录 模型缓存位置
HF_ENDPOINT https://hf-mirror.com 国内镜像源
HF_HUB_OFFLINE 1 强制离线 (模型已下完时)
HF_HUB_DISABLE_SYMLINKS_WARNING 1 关闭 Windows symlink 警告

6. 项目架构

                   ┌────────────────────────┐
   User Input ──▶ │  Chainlit Web UI       │
                   │  (main.py)             │
                   └──────────┬─────────────┘
                              │
                              ▼
                   ┌────────────────────────┐
                   │  LangGraph StateGraph  │
                   │  (agent_graph.py)      │
                   │  ┌──────────────────┐  │
                   │  │   Agent Node     │  │
                   │  │  (LLM 决策)      │◀─┐
                   │  └────────┬─────────┘  │
                   │           │ tool_calls  │
                   │           ▼             │
                   │  ┌──────────────────┐  │
                   │  │   ToolNode       │──┘
                   │  │  ├ retrieval     │
                   │  │  └ calculator    │
                   │  └──────────────────┘
                   └──────────┬─────────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
       ┌──────────┐    ┌──────────┐    ┌──────────┐
       │   RAG    │    │Embedding │    │ FAISS    │
       │ Retriever│    │   BGE    │    │  Index   │
       │ (混合)   │    │  zh-v1.5 │    │ (本地)   │
       └────┬─────┘    └──────────┘    └──────────┘
            │
            ├─▶ 向量召回 (FAISS, top_k=10)
            ├─▶ BM25 召回 (jieba + rank-bm25, top_k=10)
            ├─▶ RRF 融合 (top 8)
            └─▶ BGE Reranker 精排 (top 3)

详细架构说明见 PRD §6.2


7. 调试技巧

7.1 /trace 斜杠命令

在 Chainlit 中输入 /trace 你的问题, 不走 LLM, 直接展示混合检索的 5 段流水:

🔍 向量召回 (top 10)        →  FAISS 相似度排序
🔍 BM25 召回 (top 10)       →  jieba 分词后关键词命中
🔀 RRF 融合 (top 8)         →  双路分数融合
🎯 Reranker 精排 (top 3)    →  Cross-Encoder 精排
✅ 最终返回 Top-3           →  送入 LLM 的最终 Context

7.2 CLI 验收

直接用命令行跑 4 个验收 case, 不需要启动 Web:

python -m core.agent_graph 公司休假管理制度-示例.pdf

自动跑:

  1. 1+1等于几? → calculator
  2. 休假要提前几天申请? → retrieval
  3. 如果我有5天年假, 连上前后的周末, 总共能休息多少天? → retrieval + calculator
  4. 今天天气怎么样? → 拒答 (retrieval 返回空)

7.3 模型缓存管理

# 列出已缓存的 FAISS 索引
python model_pool.py

# 清理所有缓存 (下次运行会重新构建)
# Windows:
rmdir /s /q faiss_index_cache
rmdir /s /q hub

8. 性能与限制

8.1 性能指标 (基于 Intel i5 CPU)

操作 首次运行 二次运行 (命中缓存)
Embedding 加载 ~3s ~3s (单例)
Reranker 加载 ~8s ~8s (单例)
FAISS 构建 (5 chunks) ~2s <100ms (load)
端到端问答 ~5s ~1.5s

8.2 已知限制

  • 仅支持单文档: MVP 范围内, 每次上传新文档会替换旧知识库
  • 无会话持久化: Chainlit 重启后历史对话丢失
  • CPU 推理: 默认 device=cpu, 有 GPU 可改 hybrid_retriever.py:42"cuda"
  • 多语言偏中文: 选型为 BGE 中文系列, 英文文档召回质量一般

8.3 Out-of-Scope (本期不做)

  • 多文件并发处理与文档管理
  • 账号体系 / 权限管控 / 多租户
  • 会话历史持久化与云端部署
  • pytest 单元测试套件

9. 开发与扩展

9.1 新增工具

agent_graph.py 里加:

@tool
def my_new_tool(param: str) -> str:
    """工具描述 (LLM 据此决定何时调用)."""
    # 实现逻辑
    return result

# 在 create_agent_graph() 的 tools 列表里追加
tools = [_make_retrieval_tool(hybrid_retriever), calculator_tool, my_new_tool]

9.2 切换 Embedding / Reranker

修改 vector_store.py:27hybrid_retriever.py:41 的常量即可。注意:

  • Embedding 变更后必须删除 faiss_index_cache/, 否则向量维度不匹配
  • Reranker 变更后无需清缓存, 索引结构不依赖 Reranker

9.3 切换 LLM

修改 agent_graph.py:47 或环境变量 DEEPSEEK_MODEL。 本项目默认 deepseek-v4-flash, 也支持任何 OpenAI 兼容 API (改 DEEPSEEK_API_BASE 即可)。


10. 致谢

本项目站在巨人的肩膀上:


11. License

本项目基于 MIT License 开源, 详见 LICENSE 文件。

About

基于 LangChain + LangGraph + Chainlit 的中文 RAG 智能文档问答 Agent。上传 PDF/TXT 即可在 Web 端进行问答,并支持自动调用计算器等工具。

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages