首页 / 资讯中心 / 文章详情

RAG与AI Agent知识管道:从检索原理到LangChain实践

RAG与AI Agent知识管道:从检索原理到LangChain实践 ★ FEATURED ARTICLE
先说个可能颠覆认知的结论AI Agent 项目里最容易翻车的环节往往不是规划、不是工具调用而是最不起眼的“知识获取”。我做过好几个 Agent 练手项目也帮朋友调过基于 LangChain 的知识库问答最后发现大家踩的坑高度一致——模型明明很强却总在问私有数据时一本正经地胡编。这就是为什么我把这个系列的第四篇专门留给 RAG它才是 Agent 真正长记性的管道。这篇文章我想认真聊聊知识获取管道的底层逻辑大模型为什么离不开 RAG、一条完整管道里每个环节到底在干什么、以及用 LangChain 从零搭一条可用的 RAG 链路需要调哪些参数。适合正在从 0 到 1 搭建 AI Agent 的开发者也适合那些已经被检索效果差回答胡说八道折磨过、想搞清楚问题出在哪的实践者。1. 为什么 AI Agent 的知识管道必然要聊 RAG1.1 大模型的三个天然缺陷先别急着写代码。你要真想把 RAG 玩明白得先理解这个问题到底在解决什么。大模型本质上是一个参数化的知识压缩器。训练完成后它的全部知识都冻结在网络权重里这就带来三个要命的缺陷。第一知识有时效性模型训练数据截止的那一刻就是它认知的终点你问它今年新发布的政策、新出的产品规格它只能靠猜。第二幻觉问题当它不知道答案时语言模型的天性不是说不知道而是编一个最像答案的东西这在对话里极难察觉。第三无法感知私有知识你公司内部的制度文档、项目周报、数据库里的业务数据模型一概不知。我见过很多团队试图用微调来解决知识问题结果成本高、更新慢、还容易过拟合。微调适合让模型改变说话风格或固定行为模式但不适合让它记住海量、频繁更新的业务知识。这就好比让一个员工把整本百科全书背下来再考试不如让他坐在书架前随时翻书。这个翻书的动作就是 RAG。1.2 开卷考试式生成RAG 的全称是 Retrieval-Augmented Generation检索增强生成。核心思路一句话给大模型配一个外部知识库回答前先检索相关内容把检索结果和问题一起塞给模型让它基于这些资料作答。我说一个生活化类比。传统大模型是闭卷考试模型凭记忆答题遇到不会的题只能硬编。RAG 则是开卷考试模型拿到试卷后先到资料库里快速翻找相关章节然后照着资料结合自己的理解写答案。这个类比足够说明一个关键点RAG 的答案质量上限取决于你递给模型的资料质量而不完全取决于模型本身。在 AI Agent 架构里RAG 的位置是知识获取管道。Agent 要感知环境、要决策、要行动但所有决策都需要知识支撑。一个没有 RAG 的 Agent等于一个没有工作经验的实习生能力再强也不知道你的业务规则。1.3 RAG 与微调的取舍很多刚接触这个概念的人会纠结到底该用 RAG 还是微调我把两者的差异整理成了对比表方便你做决策。对比维度RAG微调知识更新换文档即可秒级生效需重新训练周期长硬件成本普通 CPU 也能跑需要 GPU 训练资源知识时效实时可控冻结在模型参数中适合场景事实性问答、动态知识库风格迁移、特定输出格式幻觉风险相对可控但仍需评估可能产生灾难性遗忘维护成本需维护索引和检索链路需管理训练数据集和版本我的经验是事实性知识用 RAG行为规范用微调。比如你希望 Agent 回答问题时语气热情一点可以微调但如果你希望 Agent 知道公司年假规定请老老实实做 RAG。两条路可以结合不是互斥关系。2. RAG 管道核心环节拆解从文档到向量的加工流水线2.1 文档加载与切分chunk size 不是拍脑袋一条标准 RAG 管道可以拆成离线索引和在线查询两段。离线索引阶段负责把文档变成可检索的向量数据库在线查询阶段接收用户问题、检索相关片段、拼装 prompt 给模型。很多人在离线阶段就栽了因为忽略了一个关键设计决策文档怎么切。原始 PDF 或 Word 不可能整篇塞进模型上下文必须切成一段段文本术语叫 chunk。切分看似简单却是影响召回质量最深的坑。chunk size 太小语义被切断比如一句虽然表面看起来没问题实际上存在隐患被从中间切开后半段就完全丢失了转折语境chunk size 太大向量粒度太粗精准匹配率下降而且检索到的块会挤占上下文窗口。实际操作中我建议从 300 到 800 个 token 的块大小起步再配合 50 到 100 token 的重叠。重叠的意义在于一个完整的语义单元无论落在哪个切分边界都能被至少一个块完整包含。另外不要对所有文档用同一套切分逻辑。Markdown 文件按标题结构切代码库按函数切长篇幅规章制度按段落切这比纯字符长度切好得多。LangChain 里的 RecursiveCharacterTextSplitter 支持按分隔符优先级递归切分是我最常用的工具你可以自定义分隔符列表。2.2 嵌入模型与向量数据库选择切好的文本块需要转成向量这个转换器就是嵌入模型Embedding Model。选嵌入模型主要看三个指标维度、语义理解能力和语言适配性。中文场景下我强烈建议用专门针对中文优化的嵌入模型比如 BAAI/bge 系列或 text2vec直接用通用英文嵌入模型处理中文文档检索质量会明显打折。向量数据库负责存储这些向量并支持相似度检索。市面可选方案很多我把常见选择做成了一张选型表。向量数据库适合场景扩容方式备注Chroma本地小规模学习、原型验证单机轻量适合练手FAISS纯向量检索库需结合外部存储Facebook 开源高性能Milvus生产级大规模检索分布式功能全面运维稍重pgvector已有 PostgreSQL 的场景随数据库扩展省去额外基础设施Elasticsearch已有 ES 且需混合检索自带分片机制支持 BM25 与向量融合我个人的项目实践排序是先拿 Chroma 跑通原型需要混合检索或持久化更强时迁移到 pgvector 或 Milvus别一上来就整生产级分布式集群容易把精力耗在运维上。2.3 检索不是搜索相似度、TopK 与重排序很多人以为检索就是把问题向量和库里所有向量算一遍余弦相似度然后返回最接近的。这个理解没错但不够。向量相似度检索只解决语义相关问题它不解决精确匹配和答案片段定位问题。一个常见的坑用户问2024 年销售额是多少如果你只做向量检索库里的2024 Sales Revenue片段可能因为表述差异排在很后面。要解决这个建议引入混合检索也就是 BM25 关键词检索和向量检索并行再通过 RRF 或加权方式融合结果。关键词检索擅长精确命中型号、编号、人名向量检索擅长理解意思相近但表达不同两者互补。TopK 参数决定了查多少条候选片段送给模型。设太小比如 TopK2可能漏掉关键信息设太大比如 TopK10又可能把不相关噪音塞进上下文干扰模型判断。我的经验是先从 4 到 6 起步观察回答质量后再逐个实验。此外有条件就加一个重排序环节用 cross-encoder 模型对候选片段重新打分排序这一步经常能把回答准确率提升一到两成。3. 实操过程用 LangChain 搭一条可用的 RAG 管道3.1 技术选型与准备说了这么多原理到了动手环节。当前主流框架里LangChain 生态最丰富、教程最多适合快速验证Spring AI 则适合 Java 技术栈、想融入企业级应用的同学。我自己在练手项目里用 LangChain在公司 Java 团队里推过 Spring AI两者都能完成标准 RAG 链路。下面以 LangChain 为例给出完整链路。先准备 Python 环境安装依赖。pip install langchain langchain-community langchain-openai chromadb bge-reranker如果你本地有模型文件也可以用 Ollama 或 llama.cpp 跑本地嵌入模型避免调用外部 API 产生的费用和数据隐私问题。我强烈建议涉及公司内部数据时优先考虑本地部署这不是技术问题是合规问题。3.2 索引构建代码索引阶段分四步加载、切分、嵌入、存储。我用一个示例展示核心逻辑。from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma # 1. 加载文档 loader PyPDFLoader(./员工手册.pdf) documents loader.load() # 2. 切分按结构切token 级控制 text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap100, separators[\n\n, \n, 。, , , ., , ], ) chunks text_splitter.split_documents(documents) # 3. 嵌入用中文优化的 bge-small 模型 embeddings HuggingFaceEmbeddings(model_nameBAAI/bge-small-zh-v1.5) # 4. 存储本地 Chroma持久化到目录 vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db, ) vectorstore.persist()这段代码里最值得留意的是切分参数。我建议把中文断句符号。加进 separators因为它们对中文语义边界的判断比单纯空格和换行更准确。很多英文教程只写了 \n、空格直接套到中文文档上效果会差不少。3.3 检索问答链路代码查询阶段要做的是把用户问题向量化、检索相似片段、构造 prompt、调用大模型生成答案。from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI retriever vectorstore.as_retriever( search_typesimilarity, search_kwargs{k: 5, score_threshold: 0.6}, ) qa_chain RetrievalQA.from_chain_type( llmChatOpenAI(modelgpt-4o-mini, temperature0), retrieverretriever, return_source_documentsTrue, ) question 员工请年假需要提前几天申请 result qa_chain.invoke({query: question}) print(答案:, result[result]) print(参考来源:, [doc.metadata.get(source) for doc in result[source_documents]])这里有两个关键参数。第一个是 temperature问答场景建议设为 0 或接近 0因为你要的是确定性事实不是创意发散。第二个是 score_threshold 相似度阈值低于阈值的片段会被过滤掉有效减少强行回答无关内容的情况。但阈值设太高也会导致检索不到答案这个值需要你根据自己的嵌入模型和文档情况来回试。我还有一个建议不要直接用 RetrievalQA 模板了事。项目后期我习惯自建 prompt把检索片段和对话历史一起塞进上下文让 Agent 同时具备记忆和知识检索能力。自建 prompt 也方便你加入如果资料中没有答案请明确说不知道的指令。4. 从基础 RAG 到 Agentic RAG检索不再是单向动作4.1 基础 RAG 的局限如果你用基础 RAG 跑过真实业务一定会撞上三个痛点。第一是单轮检索的局限复杂问题需要多步推理比如对比 A 产品和 B 产品在售后服务上的差异一次检索拿到的是同一批候选无法分别针对售后服务和A 产品B 产品精准取料。第二是问题改写缺失用户的问题常常是口语化的比如这个怎么弄里的这个指代不明直接检索命中率很低。第三是知识密度不足单个知识库答不了跨领域问题Agent 可能需要先查规章制度、再查操作手册、甚至调一次外部 API 才能拼出完整答案。这些问题催生了 Agentic RAG也就是把 RAG 从一次检索、一次生成升级为由 Agent 编排的多步检索与工具调用过程。4.2 三种常见的 Agentic RAG 模式我整理了自己实践过的三种 Agentic RAG 模式欢迎参考。查表式路由检索Agent 先判断问题属于哪个知识域再路由到对应的向量库。典型场景是企业同时有 HR 知识库、技术文档库和财务制度库用户提问报销流程怎么走时先分类路由而非在三个库各检一遍。这样做既省时间又提升准确率。多跳检索Agent 把一个复杂问题拆解成多个子问题分别检索后合并推理。举个例子问上季度华南区的退货率是否异常Agent 会先检索退货率的正常范围再检索上季度华南区退货数据最后基于两份资料综合判断而不是试图一次检完。反思式检索Agent 生成初步回答后自己审查答案缺失项主动发起二次检索补充。这类似写论文时先写初稿再根据审稿意见回头补资料。落地时要给 Agent 明确的指令比如如果当前资料不足以证明结论请继续检索并标注补充来源。4.3 在 Agent 架构里整合 RAG 管道的建议Agentic RAG 听起来很高级但实操上我建议你用渐进式路线落。先保住基础管道质量再给 Agent 增加两个工具一个叫知识库检索工具接收用户问题返回相关片段一个叫知识库路由工具帮 Agent 判断该查哪个库。让 Agent 自己决定是否调用这些工具也就完成了 RAG 与 Agent 工作流的自然融合。说到底RAG 是 Agent 的一个工具Agent 是 RAG 的调度者。只有把两者当作一个整体设计知识获取管道才能真正为决策服务。5. 常见问题与排查技巧实录5.1 检索效果差命中率低、答非所问这是反馈最多的一类问题。当你发现答案明显不相关时先别怀疑大模型考察检索召回质量。我一般按这个顺序排查第一步检查测试用例的 TopK 结果把检索到的片段直接打印出来看是否相关第二步检查切分设置看是不是把关键内容切散了第三步检查嵌入模型换成中文优化模型试试第四步引入混合检索用 BM25 弥补向量检索的盲区。既然提到评估就顺便聊聊热词里常说的 Hit Rate 命中率。它的定义简单粗暴在测试集中对于每个问题看标准答案片段是否出现在检索结果的前 N 条中。这个指标能客观衡量你的检索链路是否健康建议在修改参数前后都跑一遍用数据说话别凭感觉调参。5.2 回答仍有幻觉来源与答案对不上很多团队以为做了 RAG 就一定能消灭幻觉这其实是误区。RAG 只能降低幻觉概率不能根治。当我发现模型明明检索到了正确内容却依然给出错误答案时通常有两个原因。一是 prompt 没有明确约束模型只能基于片段回答导致模型开始自由发挥二是 TopK 太多噪音片段盖过了关键片段。前者改 prompt后者降 TopK 或加重排序。5.3 延迟过高与成本失控在建管道时延迟瓶颈通常不在检索而在模型推理。检索返回 4 到 6 个片段每个 500 token拼起来大概 3000 token 的输入长度这不会太耗时。真正拖慢速度的是模型输出和额外的重排序环节。我的建议是把重排序做成可选策略简单问题直接跳过对用户频繁问的标准问题加一层缓存命中缓存就不走模型能大幅降低成本。5.4 排障速查表我把遇到的典型问题整理成了一张速查表方便你对照自查。现象可能原因建议操作检索结果不相关嵌入模型不支持中文换 bge-zh / text2vec关键信息总是被切丢chunk_size 过小或分隔符不合理增大 chunk 并加入中文标点分隔符相似度阈值过低导致一堆噪音score_threshold 设太高了会有相反问题观察检索得分分布调平衡点答案编造原书中没有的细节prompt 缺少仅基于资料约束在 system prompt 中显式声明多个文档越混合越乱没有做路由为不同知识域建独立向量库检索慢、响应超时数据量过大且未分区加索引分区或换 Milvus 级方案6. 从 RAG 到 Agent 知识管道的扩展心得6.1 本地化知识库数据不出门的务实方案如果你的业务涉及公司内部数据或者你不想按 token 支付调用费强烈建议做本地 RAG。本地化方案的核心是本地嵌入模型加本地向量库再配合本地推理模型。我用过 Ollama 跑对话模型本地部署的问题是显存占用嵌入模型相对轻量可放在 CPU 上跑但生成式大模型强烈建议用带 GPU 的机器。实测下来一台 16G 显存的机器跑中等规模的对话模型加上小型嵌入模型完全能支撑几十人规模的知识库问答场景。本地方案还有个隐藏好处离线可用。这在一些网络受限的办公环境里是刚需。6.2 知识更新与版本管理别忽视管道维护RAG 上线之后最大的敌人不是准确率而是知识过期。员工手册改版了、产品规格更新了向量库里还躺着旧版本内容Agent 就会回答出新瓶装旧酒的答案。我建议把知识库更新纳入版本管理每次批量写入都给知识库打标签比如2025Q3 员工手册 v3.2查询时按版本标签过滤或者在知识变更后主动重建相关模块的索引。文本切分与向量存储的联动也要注意如果你改了切分规则旧索引必须重建否则块与块之间会出现语义不对齐的问题。6.3 个人体会做了一整个系列之后我最大的体会是RAG 不是把文档丢进向量库就完事的玩具它是需要持续打磨的知识基础设施。技术上每个环节都有讲究但从项目角度看清晰的文档结构、合理的知识分类、业务规则的沉淀往往比参数调优更深远地影响最终效果。如果让我给新手一个最快入门的路径那就是先搭一个最小的管道立刻跑通再逐个换组件看效果差异。你会发现换来换去提升最大的一次往往不是换了更强的模型而是把文档重新整理合格了。
阅读完成 · 觉得有帮助?
咨询建站