ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

从 0 到 1 搭建 RAG 个人知识库 Agent:LangChain + LangGraph + Chroma 全栈实战

从 0 到 1 搭建 RAG 个人知识库 Agent:LangChain + LangGraph + Chroma 全栈实战 写在前面你是否也遇到过这样的烦恼——ChatGPT 答得头头是道但一问到公司内部文档 / 私人笔记就一本正经地胡说八道这就是 LLM 的知识陈旧和幻觉两大痛点。这篇文章会带你从 0 到 1 搭建一个真正能用的RAG 个人知识库问答 Agent上传你的 PDF / Markdown / TXTAI 基于你的私有资料回答每条答案标注来源知识库答不上时自动搜索网络兜底还支持多轮追问。完整代码已开源文末附 Gitee / GitHub 仓库地址建议先 Star 再读。一、项目简介Agent_RAG_Project是一个生产级 RAG 个人知识库问答系统采用RAG 检索 LangGraph Agent 编排双引擎设计核心目标只有一个让大模型基于你的私有资料回答问题并做到可溯源、可兜底、可多轮。它解决了 3 个 LLM 原生痛点知识陈旧训练数据有截止日期私有资料未公开幻觉编造大模型会一本正经地胡说八道缺乏上下文传统 RAG 链无法处理它的作者是谁这种代词追问二、核心特性私有知识问答支持 PDF / Markdown / TXT / HTML / URL 多种格式上传AI 只基于你的文档回答答案可溯源每条答案都标注来源文件名或URL可核实、不编造多轮追问支持对话上下文它的作者是谁型代词追问能正确接住自动兜底知识库答不上时自动调 Tavily 搜索网络明确标注来自网络本地部署向量库 / 上传文件 / 日志全部本地存储仅调用模型 API数据隐私可控️完整工程化5 个真实 bug 排查文档、阶段 1~3 验证报告、单元 集成 端到端测试三、技术架构3.1 整体技术栈层次选型解决什么问题LLMDashScopeqwen3.5-plusOpenAI 兼容中文生成 推理EmbeddingDashScopetext-embedding-v41024 维文档向量化RerankDashScopeqwen3-rerank检索结果精排向量库Chroma本地持久化存储 相似度检索关键词检索BM25rank-bm25弥补向量对专有名词召回差混合融合RRFReciprocal Rank Fusion向量 BM25 加权融合Agent 框架LangGraph4 节点状态图决策 / 评估 / 兜底 / 多轮记忆前端Streamlit快速搭建聊天界面搜索兜底Tavily Search APILLM 优化过的搜索 API监控LangSmith可选链路追踪3.2 架构图Mermaid3.3 核心数据流一句话概括用户提问 →混合检索向量 BM25→关键词匹配率评估→ 够用就基于知识库生成不够就调 Tavily 搜索兜底 → 生成答案并标注来源 → 跨轮记忆MemorySaver thread_id。四、核心流程深度解析4.1 RAG 检索4 种策略对比app/rag_pipeline.py的retrieve_with_strategy是整个系统的检索中枢支持4 种策略策略实现适用场景vector纯向量相似度检索通用语义匹配hybrid向量 BM25RRF 融合默认推荐兼顾语义 关键词rerank向量检索 Rerank 精排召回还行但需精排full混合检索 Rerank最高质量Agent 默认采用为什么需要 hybrid向量检索擅长语义匹配同义词、paraphrase但对专有名词、代码标识符、数字召回差BM25 反之。两者数学上互补融合后召回率显著提升。核心代码片段app/retrievers/hybrid_retriever.pyclass HybridRetriever: 混合检索器向量 BM25 加权融合RRF def __init__(self, vector_retriever, bm25_retriever, weightsNone): if weights is None: weights [0.5, 0.5] # 向量 / BM25 各占一半 # 把 VectorRetriever 转 LangChain 标准接口 vector_lc vector_retriever.as_retriever() # 用 EnsembleRetriever 自动做 RRF 融合 self._ensemble EnsembleRetriever( retrievers[vector_lc, bm25_retriever], weightsweights, )RRF 公式score(d) Σ weight_i / (k rank_i)k 一般取 60。简单讲就是在多个检索结果中都排得靠前的文档胜出。4.2 Agent 编排LangGraph 4 节点状态图这是整个项目最精彩的部分。为什么不用普通 Chain单一RetrievalQA链遇到知识库答不了会硬生成可能编或返回空Agent 化后多一层评估 决策知识库不够用就显式切到网络兜底答案标注清晰状态流转图核心代码app/agent/graph.pyworkflow StateGraph(AgentState) ​ # 注册 4 个节点 workflow.add_node(retrieve, retrieve_node) # 混合检索 workflow.add_node(grade, grade_node) # 评估检索质量 workflow.add_node(search, search_node) # Tavily 兜底 workflow.add_node(generate, generate_node) # 最终生成 ​ # 边retrieve → grade固定 workflow.add_edge(retrieve, grade) ​ # 边grade → {search, generate}条件分支 workflow.add_conditional_edges( grade, decide_to_search, # 关键词匹配率 ≥ 0.3 走 generate否则 search {search: search, generate: generate}, ) ​ workflow.add_edge(search, generate) workflow.add_edge(generate, END) ​ # 多轮记忆MemorySaver thread_id app_graph workflow.compile(checkpointerMemorySaver())4.3 评估节点grade_node的精妙之处grade_node是 Agent 的大脑决定要不要兜底。为什么用规则模式而不用 LLM 评估app/agent/nodes.py# 规则判断模式默认不调 LLM省配额、避免 429 GRADE_MODE rule KEYWORD_MATCH_THRESHOLD 0.3 ​ def _keyword_match_score(question, documents): # 1. 提取问题关键词中文 英文过滤停用词 # 2. 统计关键词在文档中的命中率 # 3. 返回 0.0 ~ 1.0 的匹配率 ... ​ def grade_node(state): if not state.get(documents): return {need_search: True} score _keyword_match_score(state[question], state[documents]) if score KEYWORD_MATCH_THRESHOLD: return {need_search: True} # 兜底 return {need_search: False} # 知识库够用设计哲学规则模式零 LLM 调用、零延迟、不消耗 API 配额且不会触发 DashScope 速率限制这是我踩过的真实坑详见bug_docs/BUG-002_dashscope_rate_limit_429.md。4.4 多轮记忆MemorySaver thread_idapp/agent/state.py的chat_history字段用了 LangGraph 的add_messagesreducerclass AgentState(TypedDict): question: str documents: List[Document] answer: str # 关键Annotated add_messages 让 LangGraph 跨轮追加而非覆盖 chat_history: Annotated[List[BaseMessage], add_messages] ...调用时只需传thread_idconfig {configurable: {thread_id: user_001}} result1 agent.invoke({question: LangChain 是什么}, configconfig) result2 agent.invoke({question: 它的作者是谁}, configconfig) # 自动继承上文实测可正确处理它指代 LangChain验证通过 ✅五、踩过的 5 个真实坑干货预警⚠️这一节是我开发过程中最宝贵的经验。每个 bug 都记录在bug_docs/目录。#问题根因解决方案DashScope Embedding 大文档导入失败DashScopebatch size ≤ 20限制且 SDK 内部对长文本二次分段init_vectorstore分批入库实测必须 ≤5 才稳定迭代 10→5DashScope qwen3.5-plus 速率限制 429limit_burst_rate限制短时间并发必触发ChatOpenAI(max_retries3) 节点层手工重试 4 次间隔 8s双层防护OpenAIEmbeddings兼容 DashScope 报 400默认会用 tiktoken 分词后发 token 列表DashScope 兼容模式只接受字符串check_embedding_ctx_lengthFalseStreamlitsession_state不能在 widget 实例化后修改Streamlit 限制已实例化的 widget 的 key 不能在 callback 里改信号变量模式callback 改标志、下次渲染时读标志再更新规则评估模式的代词指代问题短追问它呢规则评估容易误判借助 LangGraphMemorySaver多轮记忆让它在上文已有主体时直接通过 完整复盘每个 bug 都有独立的 markdown 文档包含复现条件 / 根因分析 / 影响范围 / 解决方案 / 验证步骤。建议大家也养成踩坑就写文档的习惯团队受益巨大。六、快速开始6.1 环境要求Python 3.10推荐 condaAPI 密钥DashScope阿里云百炼必填Tavily网络搜索兜底必填6.2 一键启动Windows PowerShell# 1. 克隆项目 git clone https://gitee.com/ganhaifeng/agent-rag-project.git cd agent-rag-project ​ # 2. 创建 conda 环境 conda create -n agent_rag python3.10 -y conda activate agent_rag ​ # 3. 安装依赖 pip install -r requirements.txt ​ # 4. 配置 API 密钥 Copy-Item .env.example .env # 用编辑器打开 .env填写 DASHSCOPE_API_KEY 和 TAVILY_API_KEY ​ # 5. 启动应用 streamlit run main.py浏览器访问 http://localhost:85016.3.env关键配置# 必填DashScope API Key DASHSCOPE_API_KEYsk-xxx ​ # 必填Tavily Search API Key TAVILY_API_KEYtvly-xxx ​ # 模型选型一般不用改 DASHSCOPE_MODELqwen3.5-plus DASHSCOPE_EMBED_MODELtext-embedding-v4 DASHSCOPE_RERANK_MODELqwen3-rerank ​ # 可选Ollama 本地模型不花钱需先 ollama pull # OLLAMA_BASE_URLhttp://localhost:11434 # OLLAMA_EMBEDDING_MODELqwen3-embedding:8b七、项目展示启动后你会看到一个侧边栏 主区双栏布局侧边栏知识库管理上传文档支持 PDF / Markdown / TXT / HTML 拖拽上传已导入文档列表显示每个文件的 chunk 数☑️选择性导入默认全选未入库文件可手动勾选重名跳过️按文件名删除先查 ids 再删规避 Chroma 不支持 filter 参数的坑退出系统按钮解决 Windows CtrlC 退不干净问题主区域聊天对话 消息流用户 / 助手气泡分明来源卡片每条答案末尾自动追加引用来源知识库文件名 或 网络 URL 来自网络 多轮追问自动继承上文它的作者是谁能正确接住典型使用场景搜索 LangChain 的核心组件有哪些LangChain 的核心组件包括Models模型、Prompts提示词模板、Chains链、Indexes索引、Memory记忆、Agents智能体...引用来源知识库langchain_tutorial.md [rerank0.9521]那它和 LlamaIndex 有什么区别它LangChain和 LlamaIndex 的主要区别在于...自动理解它指代 LangChain ✅八、总结与展望✅ 已完成v1.0RAG 全流程加载 → 切分 → 向量化 → 入库 → 检索 → 生成4 种检索策略对比 Agent 默认采用full混合 RerankLangGraph 4 节点状态图 多轮记忆Streamlit 完整 UI上传 / 选择导入 / 删除 / 退出5 个 bug 文档 阶段 1~4 验证报告 路线图v1.0当前 → v1.x体验优化 → v2.0持久化 → v3.0生产化v1.xbug 修复、UX 优化、检索策略可视化对比v2.0MemorySaver→SqliteSaver对话历史持久化重启不丢v3.0Docker 容器化、多用户、权限管理、LangSmith 全链路追踪 未来可优化方向评测体系构建标准评测集30~50 QA用 Recall5 / MRR 量化检索质量RAG 进阶Self-RAG / CRAG / 父子文档small-to-big增量更新文档修改后只更新变更的 chunk️多模态图片 / 表格解析 多模态 Embedding联网增强query rewriting / multi-query / HyDE 查询增强九、开源地址 如果这个项目对你有帮助欢迎Star / Fork / Issue你的支持是我持续维护的最大动力平台链接Giteehttps://gitee.com/ganhaifeng/agent-rag-projectGitHubAgent_RAG_Project/Agent_RAG_Project at main · Gavin2149161093/Agent_RAG_Project · GitHub 配套文档 项目使用手册 — 安装、配置、操作指南️ 技术架构说明 — 技术栈、模块详解、数据流 业务流程与应用场景 — 8 个真实使用场景️ 路线图与体验优化 — v2.0 / v3.0 规划✍️ 写在最后RAG 不是调包就完事。真正落地的 RAG 系统需要考虑检索质量评测、混合检索的融合权重、Rerank 的必要性、Agent 决策的可控性、LLM 速率限制、多轮记忆的持久化、长文档的切分粒度、增量更新的实现...这些坑我都替你踩过了5 篇 bug 文档就是我的全部经验。希望这个项目能成为你 RAG 学习路上的参考实现也欢迎在 Issue 区交流你的优化方案 我们下一篇见作者简介电子信息硕士研究生专注 AI Agent / RAG 方向。GitHub / Gitee 持续输出分享 LangChain 生态实战经验。版权声明本文首发于 CSDN 与稀土掘金转载请保留原文链接。
返回列表