# langchain-study **Repository Path**: mkee/langchain-study ## Basic Information - **Project Name**: langchain-study - **Description**: LangChain + LangGraph 开发本地知识库 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-03-03 - **Last Updated**: 2026-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LangChain RAG 系统 基于 LangGraph + LangChain 集成阿里云通义千问(Qwen)的检索增强生成(RAG)系统,向量数据库采用 Chroma。 ## 功能特性 - **文档管理**:创建/加载本地知识库,添加、查看、删除文档 - **智能检索**:混合检索(稠密向量 + BM25 稀疏检索),重排序优化 - **RAG 问答**:基于检索结果生成回答(RAG 链),多轮检索反思机制 - **纯检索**:无需 LLM,仅返回检索结果 - **上下文压缩**:过滤低相关文档,压缩过长内容 - **RAG 评估**:忠实度、答案相关性、上下文召回率三维评估 - **短期记忆**:对话窗口管理,超出窗口自动摘要压缩 - **长期记忆**:自动提取用户偏好和实体信息,持久化存储 - **本地调试**:工作流执行追踪器,可视化节点执行过程 ## 系统架构 ```mermaid flowchart TB subgraph User["用户层"] UI[Web 页面] Q[查询输入] end subgraph Memory["记忆系统"] STM[短期记忆
对话窗口管理] LTM[长期记忆
偏好/实体提取] MEM_STORE[(记忆存储)] end subgraph Retrieval["检索层"] DR[稠密检索
Chroma 向量] SR[稀疏检索
BM25] HR[混合检索
加权融合] RR[重排序
Cross-encoder] CC[上下文压缩] end subgraph Workflow["RAG 工作流 (LangGraph)"] RET[检索文档] FMT[格式化文档] RFL[反思] DEC{should_continue} GEN[生成答案] end subgraph Eval["评估层"] EVAL[RAG 评估
忠实度/相关性/召回率] end subgraph Storage["数据层"] CHROMA[(Chroma
向量数据库)] MEM_STORE2[(长期记忆
向量存储)] PROMPTS[(提示词模板
prompts.yaml)] end Q --> UI UI -->|用户问题| STM UI -->|用户问题| LTM STM -->|对话历史上下文| RET LTM -->|偏好/实体上下文| RET RET -->|查询| HR DR --> CHROMA HR --> DR HR --> SR HR -->|融合结果| RR RR -->|重排序结果| CC CC -->|压缩后文档| RET RET --> FMT FMT --> RFL RFL --> DEC DEC -->|继续检索| RET DEC -->|生成答案| GEN GEN --> EVAL EVAL -->|评估结果| UI GEN -->|回答| UI GEN -->|提取信息| LTM LTM --> MEM_STORE2 PROMPTS --> RFL PROMPTS --> GEN PROMPTS --> EVAL ``` ### 查询流程 ```mermaid sequenceDiagram participant U as 用户 participant UI as Web 页面 participant M as 记忆系统 participant R as 检索层 participant W as RAG 工作流 participant E as 评估层 participant S as 存储层 U->>UI: 输入问题 UI->>M: 获取记忆上下文 M-->>UI: 返回短期/长期记忆 UI->>R: 执行混合检索 R->>S: 稠密检索 + BM25 S-->>R: 返回文档 R->>R: 重排序 R->>R: 上下文压缩 R-->>UI: 返回相关文档 UI->>W: 启动 RAG 工作流 W->>W: 检索 → 格式化 → 反思 alt 需要继续检索 W->>R: 改进查询再检索 else 生成答案 W->>W: 生成最终回答 W->>E: 自动评估 E-->>UI: 评估结果 W-->>UI: 返回回答 UI->>M: 存储对话记忆 UI->>M: 提取长期记忆 end UI-->>U: 显示结果 ``` ## 技术栈 - **LLM**: 阿里云通义千问 (Qwen) - **工作流引擎**: LangGraph - **向量数据库**: Chroma - **框架**: LangChain, FastAPI - **前端**: HTML + Jinja2 模板 - **检索增强**: rank_bm25 (稀疏检索), sentence-transformers (重排序) ## 环境配置 ### 1. 安装依赖 ```bash pip install -r requirements.txt ``` ### 2. 配置 API 密钥 **推荐方式:使用 .env 文件**(更安全,不会提交到 Git) 1. 复制环境变量模板 ```bash copy env_template.txt .env ``` 2. 编辑 `.env` 文件,填入真实的 API 密钥: ``` DASHSCOPE_API_KEY=your-api-key-here ``` 获取 API 密钥:https://dashscope.console.aliyun.com/ ### 3. 启动服务 ```bash python main.py ``` 或使用 uvicorn: ```bash uvicorn app:app --host 0.0.0.0 --port 8000 --reload ``` 服务启动后访问:http://localhost:8000 ## 项目结构 ``` . ├── app.py # FastAPI 应用入口 ├── config.py # 配置文件 ├── main.py # 服务启动入口 ├── core/ # 核心模块 │ ├── __init__.py │ ├── clients.py # LLM、Embedding、向量库客户端 │ └── prompt_manager.py # 提示词管理器 ├── services/ # 业务服务 │ ├── __init__.py │ ├── rag_service.py # RAG 工作流服务(LangGraph) │ ├── document_service.py # 文档管理服务 │ ├── retrieval.py # 检索后处理模块(混合检索、重排序、压缩) │ ├── evaluator.py # RAG 评估模块(忠实度、相关性、召回率) │ ├── memory.py # 短期记忆模块(对话窗口、摘要压缩) │ ├── long_term_memory.py # 长期记忆模块(偏好、实体提取与存储) │ ├── debug_tracer.py # 本地调试追踪器 │ └── debug_run.py # 调试运行脚本 ├── api/ # API 路由 │ ├── __init__.py │ └── routes.py ├── templates/ # HTML 模板 │ ├── index.html │ ├── document_detail.html │ └── prompts/ │ └── prompts.yaml # 提示词模板配置 ├── .env # 环境变量(API 密钥) ├── env_template.txt # 环境变量模板 ├── requirements.txt # 依赖列表 └── .gitignore # Git 忽略配置 ``` ## 配置说明 在 `.env` 文件中可以配置以下选项: | 配置项 | 说明 | 默认值 | |--------|------|--------| | `DASHSCOPE_API_KEY` | 阿里云通义千问 API 密钥 | - | | `CHUNK_SIZE` | 文档分块大小 | 1000 | | `CHUNK_OVERLAP` | 文档分块重叠大小 | 200 | | `DEFAULT_RETRIEVAL_K` | 默认检索数量 | 4 | | `VECTORSTORE_PATH` | 向量数据库存储路径 | chroma_db | | `HOST` | 服务器地址 | 0.0.0.0 | | `PORT` | 服务器端口 | 8000 | | `DEBUG` | 开发模式(禁用字节码缓存) | true | | `HYBRID_RETRIEVAL_ENABLED` | 开启混合检索 | true | | `HYBRID_DENSE_WEIGHT` | 稠密检索权重 | 0.5 | | `RERANK_ENABLED` | 开启重排序 | true | | `COMPRESS_ENABLED` | 开启上下文压缩 | true | | `EVAL_ENABLED` | 开启 RAG 评估 | true | | `MEMORY_ENABLED` | 开启短期记忆 | true | | `MEMORY_MAX_TURNS` | 短期记忆最大轮数 | 5 | | `LONG_TERM_MEMORY_ENABLED` | 开启长期记忆 | true | ## 使用指南 ### 1. 添加文档 在页面 "添加文档到知识库" 部分: - 输入文档内容 - 输入分类标签 - 点击 "添加文档" ### 2. 查询知识库 在页面 "知识库查询" 部分: - 输入查询问题 - 选择查询方式: - **RAG 链**: 基于检索结果生成回答(使用 LangGraph 工作流) - **纯检索链**: 仅返回检索结果 - 点击 "查询" 查询结果下方会显示: - **RAG 评估**:忠实度、答案相关性、上下文召回率三指标评分 - **工作流日志**:各节点执行过程和耗时 - **对话历史**:最近多轮对话记录(超出窗口自动压缩) - **长期记忆**:自动提取的用户偏好和实体信息 ### 3. 验证知识库 在页面 "验证知识库" 部分: - 点击 "验证知识库状态",查看知识库中的文档数量 - 查看文档列表,包含每个文档的预览、分类和 ID - 点击 "查看详情" 按钮,查看文档的完整内容 - 点击 "删除" 按钮,删除指定文档 ### 4. 本地调试(可选) 项目提供了本地调试追踪器,用于查看 LangGraph 工作流的执行过程: ```python from services.rag_service import get_rag_graph from services.debug_tracer import LocalDebugTracer # 创建调试追踪器 tracer = LocalDebugTracer( verbose=True, # 显示详细输入输出 log_file="debug.log", # 保存日志到文件 show_llm_inputs=True, # 显示 LLM 输入 show_llm_outputs=True # 显示 LLM 输出 ) # 获取带调试追踪器的工作流 graph = get_rag_graph(tracer) # 执行工作流 result = graph.invoke({ "question": "你的问题", "documents": [], "context": "", "answer": "", "retrieval_count": 0, "max_retrievals": 2 }) # 打印执行摘要 tracer.print_summary() ``` 或使用快捷脚本: ```bash python -m services.debug_run ``` 调试输出示例: ``` 15:32:10.123 [INFO] [START] 开始执行节点: 检索文档 15:32:10.456 [INFO] [DONE] 节点完成: 检索文档 (耗时: 0.335s) ... ================================================== 📊 执行摘要 ================================================== 执行节点数: 4 总耗时: 2.456s 各节点耗时: - 检索文档: 0.335s - 格式化文档: 0.012s - 反思: 1.234s - 生成答案: 0.875s ================================================== ``` ## RAG 工作流说明 项目使用 LangGraph 构建 RAG 工作流,流程如下: ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 检索文档 │───▶│ 格式化文档 │───▶│ 反思 │ └─────────────┘ └─────────────┘ └─────────────┘ ▲ │ │ ┌─────────────┐ │ └───────────┤ should_continue ├◀──────┘ └─────────────┘ │ ┌────┴────┐ ▼ ▼ "生成答案" "反思" │ │ ▼ ▼ ┌─────────────┐ │ 生成答案 │ └─────────────┘ ``` - **检索文档**: 从向量数据库检索相关文档(支持混合检索) - **格式化文档**: 将检索到的文档格式化为上下文(支持压缩) - **反思**: 反思检索结果,决定是否需要继续检索 - **should_continue**: 条件判断,控制工作流走向 - **生成答案**: 基于最终上下文生成回答(注入记忆上下文) ### 多轮检索机制 1. 第一轮:检索 → 格式化 → 反思 → 判断 2. 反思后如果认为需要更多文档 → 回到检索 3. 否则 → 生成答案 通过 LLM 分析检索结果,如果认为检索不够充分,会自动改进搜索关键词进行新一轮检索。 ## 检索后处理 ### 混合检索(稠密 + 稀疏) 融合 Chroma 稠密向量检索和 BM25 稀疏检索结果,通过加权组合提升检索质量。 ### 重排序 使用 Cross-encoder 模型对检索结果进行重排序,提升与查询相关文档的排序位置。 ### 上下文压缩 过滤低相关度文档,截断过长内容,减少 LLM 输入噪声。 ## RAG 评估 使用 LLM-as-judge 方式,自动评估三项指标: - **忠实度 (Faithfulness)**: 回答是否基于检索上下文,有无幻觉 - **答案相关性 (Answer Relevancy)**: 回答是否切题 - **上下文召回率 (Context Recall)**: 上下文是否覆盖了问题所需信息 评估结果以 0-10 分展示在页面,绿色/橙色/红色区分高/中/低分。 ## 记忆系统 ### 短期记忆(对话窗口管理) - 维护最近 N 轮对话(默认 5 轮) - 超出窗口时自动调用 LLM 压缩为摘要 - 新查询自动注入历史对话上下文 ### 长期记忆(偏好、实体提取) - 每次对话后自动提取用户偏好和关键实体 - 使用独立的 Chroma 向量库持久化存储 - 新查询时检索相关记忆并注入上下文 - 自动去重,避免重复存储 ## 提示词模板 提示词模板保存在 `templates/prompts/prompts.yaml` 文件中: | 模板名 | 用途 | |--------|------| | `rag` | RAG 回答生成 | | `reflect` | 反思检索结果 | | `eval_faithfulness` | 忠实度评估 | | `eval_relevancy` | 答案相关性评估 | | `eval_context_recall` | 上下文召回率评估 | 可以在不修改代码的情况下调整提示词内容。 ## 注意事项 - `.env` 文件包含敏感 API 密钥,已加入 `.gitignore`,请勿提交到 Git - 向量数据库存储在 `chroma_db` 目录(可通过配置修改) - 长期记忆存储在 `memory_store` 目录(可通过配置修改) - 确保 API 密钥有足够的调用额度 - 文档会被自动分块存储,每个分块大小为 1000 字符(可通过配置修改) - 开发模式下禁用 Python 字节码缓存(`__pycache__`),方便调试