基于 LangChain + LangGraph + Chainlit + FAISS 的中文 RAG 与工具调用 Agent。 一次部署, 上传任意 PDF / TXT, 即可在 Web 上问答 + 自动调用计算器。
| 维度 | 实现 |
|---|---|
| 混合检索 | 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 次, 仅对可恢复错误触发 |
上传 PDF 后, Agent 会自主决定调用
retrieval_tool(检索知识库) 或calculator_tool(数值计算), 并以折叠 Step 形式实时展示中间推理过程。
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, 首次运行时会自动创建。
- Python 3.11+ (本项目在 3.11 验证)
- 操作系统: Windows 10/11, macOS, Linux
- 磁盘空间: 约 2 GB (主要是 Embedding + Reranker 模型)
- 网络: 首次运行需联网下载模型; 之后可断网运行
# 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.ps1chainlit run app\main.py -w注意:
chainlit run只接受.py文件路径, 不接受app.main这种模块路径。 Windows 也可用正斜杠app/main.py。 启动前请确保setup_env.bat/setup_env.ps1已执行, 否则core.*导入会失败。
浏览器自动打开 http://localhost:8000, 进入对话界面后:
- 点输入框的 附件按钮, 上传一份 PDF / TXT
- 等 "知识库构建完成" 提示
- 直接问问题, 例如:
- "年假可以休几天?" → 自动调用
retrieval_tool - "1+1 等于几?" → 自动调用
calculator_tool - "我有 5 天年假, 加上前后周末能休几天?" → 先
retrieval_tool取规则, 再calculator_tool计算 - "今天天气如何?" → 拒答 (知识库中未找到)
- "年假可以休几天?" → 自动调用
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.*模块而失败。
# DeepSeek API 配置
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
DEEPSEEK_API_BASE=https://api.deepseek.com
DEEPSEEK_MODEL=deepseek-v4-flash在 DeepSeek 开放平台 注册即可获取 API Key。
通过 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 警告 |
┌────────────────────────┐
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。
在 Chainlit 中输入 /trace 你的问题, 不走 LLM, 直接展示混合检索的 5 段流水:
🔍 向量召回 (top 10) → FAISS 相似度排序
🔍 BM25 召回 (top 10) → jieba 分词后关键词命中
🔀 RRF 融合 (top 8) → 双路分数融合
🎯 Reranker 精排 (top 3) → Cross-Encoder 精排
✅ 最终返回 Top-3 → 送入 LLM 的最终 Context
直接用命令行跑 4 个验收 case, 不需要启动 Web:
python -m core.agent_graph 公司休假管理制度-示例.pdf自动跑:
1+1等于几?→ calculator休假要提前几天申请?→ retrieval如果我有5天年假, 连上前后的周末, 总共能休息多少天?→ retrieval + calculator今天天气怎么样?→ 拒答 (retrieval 返回空)
# 列出已缓存的 FAISS 索引
python model_pool.py
# 清理所有缓存 (下次运行会重新构建)
# Windows:
rmdir /s /q faiss_index_cache
rmdir /s /q hub| 操作 | 首次运行 | 二次运行 (命中缓存) |
|---|---|---|
| Embedding 加载 | ~3s | ~3s (单例) |
| Reranker 加载 | ~8s | ~8s (单例) |
| FAISS 构建 (5 chunks) | ~2s | <100ms (load) |
| 端到端问答 | ~5s | ~1.5s |
- 仅支持单文档: MVP 范围内, 每次上传新文档会替换旧知识库
- 无会话持久化: Chainlit 重启后历史对话丢失
- CPU 推理: 默认
device=cpu, 有 GPU 可改hybrid_retriever.py:42为"cuda" - 多语言偏中文: 选型为 BGE 中文系列, 英文文档召回质量一般
- 多文件并发处理与文档管理
- 账号体系 / 权限管控 / 多租户
- 会话历史持久化与云端部署
- pytest 单元测试套件
在 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]修改 vector_store.py:27 和 hybrid_retriever.py:41 的常量即可。注意:
- Embedding 变更后必须删除
faiss_index_cache/, 否则向量维度不匹配 - Reranker 变更后无需清缓存, 索引结构不依赖 Reranker
修改 agent_graph.py:47 或环境变量 DEEPSEEK_MODEL。
本项目默认 deepseek-v4-flash, 也支持任何 OpenAI 兼容 API (改 DEEPSEEK_API_BASE 即可)。
本项目站在巨人的肩膀上:
- LangChain & LangGraph - Agent 编排框架
- Chainlit - LLM Agent Web UI
- FAISS - Facebook AI 向量检索
- BAAI BGE - 智源开源中文 Embedding / Reranker
- rank-bm25 - BM25 算法实现
- jieba - 中文分词
- DeepSeek - 大语言模型 API
- hf-mirror.com - HuggingFace 国内镜像源
本项目基于 MIT License 开源, 详见 LICENSE 文件。
