RAG知识管道全解析:从索引、检索到生成,让AI Agent告别胡说八道

发布时间:2026/11/3 23:59:26
RAG知识管道全解析:从索引、检索到生成,让AI Agent告别胡说八道 先说个现象。不少朋友找我聊 Agent 项目的时候第一句话都是“我要做个能自己查资料、自己回答的智能体”结果一看架构LLM 直接裸奔要不就是把所有文档一股脑塞进 Prompt。这种方案跑个 Demo 还行真到生产环境模型一本正经地胡说八道你都不知道它是从哪段资料里编出来的。AI Agent 要落地知识获取管道RAG从来不是为了“显得高级”而是解决一个非常现实的问题模型不懂你手头的业务数据你总得有个正经管道把知识喂给它。这个系列写到第四篇前几篇聊了 Agent 的整体架构、规划能力和工具调用逻辑这次专门把知识获取这一层拆开。RAGRetrieval-Augmented Generation检索增强生成是当前最主流的知识接入方式几乎所有带知识库问答、企业资料检索、私域数据对话的产品背后都是这套思路。无论你是用 LangChain、LlamaIndex还是直接自己写检索逻辑核心流程都绕不开“索引、检索、增强、生成”这四步。这篇我会从原理讲到代码落地的工程选型再到实际调试中的性能问题尽量把 RAG 基础讲透让你看完就能动手搭一个靠谱的版本也算为后面 Agentic RAG 留个引子。1. 为什么 Agent 必须先解决“知识从哪来”的问题1.1 模型能力很强但知识是静止的很多人会把大语言模型想象成一个无所不知的大脑这是个巨大的误解。模型的参数里确实压缩了大量常识和公开知识但那个知识是训练时定格的。我的一个客户是做机械设备售后问答的他们用的模型在通用领域表现不错可一旦问到某型号设备的维修手册细节模型就开始自我发挥一本正经地编造扭力参数甚至能把液压系统和润滑系统的结构混为一谈。原因很简单这些私域信息根本不在模型的训练范围里或者只存在于某个犄角旮旯的网页角落模型根本没记住。我在实际项目中总结过一个特别直白的判断标准凡是需要查阅具体文档才能回答的问题都不要指望模型凭空生成答案。设备参数、公司制度、产品规格、法律条款、操作流程这些内容的核心特点是“确定性”和“权威性”——错误答案的代价很高而模型在生成时天然倾向于流畅而非精确。RAG 的存在就是为了解决这个矛盾把答案的来源从“模型记忆”迁移到“外部知识库”让模型变成一个基于给定资料的理解和归纳引擎。这就像你新入职一家公司老员工模型再资深也不可能记住公司内部每一份合同模板和审批规范。他回答你的问题时需要翻内部知识库才能给准确答复。RAG 就是那个帮老员工快速翻到正确页数的图书管理员。1.2 不引入 RAG 的 Agent 会陷入什么困境没有外部知识管道的 Agent会出现几个非常典型的问题我在评估不少开源项目时都见过一是“胡编型回答”。前面说的维修参数就是典型模型不知道答案但不想承认于是生成一个看起来很像样的数字这种错误在医疗、法律、工业领域是致命的。二是“过时型回答”。模型训练截止日期之后的新政策、新版本功能、新流程它一概不知。有个做电商客服的朋友跟我说模型会把已经下架的活动说成正在进行用户追问之后客服还得反复道歉。三是“无依据型推理”。Agent 做了多步推理但它每一步的依据是什么开发者和用户都无法追溯。这在调试阶段简直要命你根本不知道是规划错了还是知识错了。四是“上下文爆炸”。如果你试图把全部产品手册塞进 Prompt很快会碰到上下文窗口上限。即使用现在的大窗口模型硬塞进去超长上下文中有效信息密度太低注意力机制被稀释回答质量反而下降推理成本也直线上升。所以我说知识获取管道不是一个可选项而是 Agent 能真正“干活”的前提。RAG 的价值也不只是给模型找资料它还给开发者提供了一套可观测、可干预、可审计的知识访问机制——这一点对企业级项目来说甚至比“回答正确”更重要。1.3 RAG 在 AI Agent 架构里的位置如果把 Agent 比作一个人规划能力是“大脑的思维过程”工具调用是“手和脚”那 RAG 就是“眼睛和记忆”。Agent 在执行任务时往往需要先感知外部信息再决定下一步动作。在一个典型的多步 Agent 任务里RAG 的调用通常会嵌入在推理循环中。举个例子一个“帮用户比较三款显卡并给出购买建议”的 Agent 任务第一步可能是从知识库检索三款显卡的规格参数第二步是利用工具抓取当前电商价格第三步才是把检索到的结构化数据和实时价格送给模型做综合推理。这里的 RAG 不是一次性前置而是作为 Agent 的“检索工具”存在随时可以按需调用。所以基础 RAG 其实为 Agent 提供了一个非常关键的抽象把知识检索封装成一个可靠的服务Agent 只需知道“有一个工具可以查到相关知识”而不用关心底层的块策略和向量索引怎么设计。后面的 Agentic RAG 还会进一步把这个工具交给模型自主决策但这篇先讲基础管道地基不打牢后面都是空中楼阁。2. RAG 管道的四个环节索引、检索、重排、生成的取舍逻辑RAG 表面上看就是一个“先搜后答”的过程但落地时每一步都有取舍。我习惯把完整管道拆成四个环节来看每个环节都有自己的核心矛盾。2.1 索引离线阶段决定一切索引是 RAG 最容易被低估的环节因为你看不见它直接产出的效果但它在很大程度上决定了检索质量的上限。整个索引过程包括文档加载、清洗、切分、向量化、入库。文档加载看似简单实际上特别碎。PDF 要处理扫描件和排版错乱Word 要处理样式丢失HTML 要剥离标签表格要决定是转成 Markdown 还是 JSON。我见过不少项目第一步就翻车PDF 抽取出来全是断行的乱码检索倒是能搜到但送进模型后答案质量惨不忍睹。清洗环节也很容易被跳过。页眉页脚、导航文本、版权声明、重复段落、无关图表标注这些东西如果不去除会直接污染向量空间。你可以想象一下知识库里混进去 500 条“版权所有翻版必究”检索的时候它们就会成为噪音邻居把真正有用的信息挤到后面去。切分策略是整个索引环节里最考验经验的也是检索效果差异最大的分水岭。我后文会专门用一节来展开这块这里先给一个总体判断固定字符切分是最差方案语义切分是主流但必须结合文档结构做多级策略。一句话总结就是你想让模型读到“一个完整意思”而不是“一段被腰斩的话”。向量化是把文本块映射到高维向量的过程。选择的 Embedding 模型直接决定了检索质量的上限。OpenAI 的 text-embedding-3 系列用起来方便但数据要过 APIBGE、M3E 这类开源模型可以本地部署私域数据不出内网中文场景下我测下来 bge-large-zh 和 m3e-base 效果都在可用线以上。选 Embedding 模型的几个关键指标是语义相似度准确率、维度大小、推理速度、支持的最大序列长度。入库这一步的隐藏细节是“元数据”。每条向量不仅要存文本和向量本身还得挂上来源文档、页码、章节标题、时间戳、权限等级等元数据。这就像图书馆的书不能光按内容编号你还得记录它在哪个书架、属于什么分类。后续做元数据过滤、权限控制、引用追溯全靠这一步留的元数据。2.2 检索从 Top-K 到混合策略检索环节是用户查询和知识库之间的“桥梁”。传统做法是把用户问题向量化然后去向量库里找最相似的 Top-K 条文本块。这个过程任何一个 RAG 框架都有现成实现但难点在于“只靠向量相似度远远不够”。向量检索擅长捕捉语义相近的内容比如用户问“这个设备多久保养一次”知识库里写的是“每运行 500 小时需进行预防性维护”这两句话字面上完全不同但语义是匹配的。但向量检索也有明显短板对关键词和专有名词不敏感。比如用户问“BGE-512 嵌入模型”如果知识库里恰好有“bge-large-zh-v1.5”这样的写法向量检索未必能精确命中但关键词检索一眼就能锁定。所以现在的工程实践普遍采用混合检索Hybrid Search向量检索负责语义召回关键词检索负责精准匹配然后再用 RRFReciprocal Rank Fusion倒数排名融合或加权分数把两路结果合并。我在实际项目里针对问题型知识库做过一组对照测试只做向量检索的命中率Recall5大约是 68%加上 BM25 关键词检索后提升到 84%再加重排后准确率Precision3从 61% 拉到 79%。说实话这个提升幅度远超我最初的预期。混合检索不是“锦上添花”而是基础 RAG 迈向可用的必经之路。检索环节还有一个容易掉坑的地方查询改写。用户的问题是口语化的比如“那个新来的同事的报销流程是啥”而知识库里的表述是“新员工入职报销管理办法”。两者语义上虽然相关但直接检索效果往往不理想。基础的解决方案是把用户问题先交给一个轻量 LLM 做改写提取关键实体和意图生成更“知识库友好”的检索语句。这个思路到 Agentic RAG 里还会演化成“多路召回 子问题分解”但基础阶段先把它当成一个可选的优化点就好。2.3 重排让最正确的答案排在最前面为什么检索完之后还要重排原因在于向量召回得到的 Top-K 是“跟问题比较相似”的内容但“相似”不等于“答案就在这里”。举一个很典型的例子用户问“怎么申请年假”知识库里排前面的可能是“年假制度总则”这种大而全的制度概述而不是“年假申请操作步骤”。模型在做 RAG 生成时如果上下文里给了制度总则却没给操作步骤输出的答案就会偏空泛。重排环节做的事情是把召回的多条候选结果交给一个更强的语义匹配模型重新计算每条候选和用户问题的相关性滤掉不相关的噪音块再把真正有用的块排到前面。目前主流的重排模型是 BGE-Reranker 和 Cohere Rerank前者开源可本地部署后者是托管 API。实测下来经过重排之后送进模型的上下文里有效信息占比明显提升整体回答质量甚至有接近 25% 的主观评分提升。重排的资源消耗也不小所以工程上通常把它放在“召回大候选集 → 重排小精集”的两阶段流程里。举个常见的参数组合向量召回 Top-50重排后取 Top-3 到 Top-5 作为最终上下文。召回大一点没关系反正重排会帮你兜底如果召回阶段就只取 Top-5重排阶段就会很被动因为真正的答案可能压根不在候选里。2.4 生成把检索结果“压缩”成答案生成环节是整个管道的最后一环考验的是 Prompt 设计和模型的归纳理解能力。RAG 的 Prompt 不能简单写一句“请根据以下资料回答问题”你需要明确几个关键指令一是规定角色的权威边界。要让模型明确“你是知识库问答助手只依据提供的资料回答”这能明显减少模型借助自身“常识”强行补充的冲动。二是规定无法回答时的行为。资料里没有明确答案时模型必须承认“知识库中没有相关信息”而不是用开放性话说“一般来说可能应该……”。这一点在客服场景中特别重要任何凭空生成的建议都可能变成售后问题。三是规定引用来源。让模型在回答尾部标明信息来自哪个文档的哪一节方便用户追溯也方便开发者定位检索环节的“坏块”。我在实际项目里测过一组对比不加引用指令时模型有 30% 左右的概率把自创内容和知识库信息揉在一起用户几乎无法分辨加了引用指令后模型会更倾向于紧贴资料说话因为它在思考层面就被要求“素材来自已知资料”。生成环节还有个被忽略的优化点上下文压缩Context Compression。召回的信息块往往包含大量与问题无关的细节比如一个维修流程的块里既有故障描述又有保养周期用户只问了故障处理。全量塞进去既浪费 token又稀释注意力。部分高级 Agentic RAG 实现会加入一个 LLM 压缩步骤从块里提炼出与问题相关的部分。基础版本可以用一种更省钱的方案重排阶段优先选择与问题“局部相关”的块或者把块切得更细。后面实战部分我会展示具体做法。3. 从零搭一个最小可用的 RAG 管道代码与选型实录这一节我会直接把我试过的一套最小组合写出来你照着走一遍就能跑通。选型上以“本地优先、上手简单、可替换”为原则不依赖 OpenAI 的向量接口方便国内环境复现。3.1 基础设施选型Embedding、向量库、框架先说 Embedding 模型。我推荐用Ollama bge-m3的组合。Ollama 是一个本地模型运行器一条命令就能把模型拉起来bge-m3 是 BAAI 开源的多功能 Embedding 模型支持中文和英文支持 8192 长度的输入在检索效果上接近商业 API 的水平而且完全本地运行文档和私域数据不出内网。启动方式很简单ollama pull bge-m3向量库选ChromaDB原因就三个轻量、免运维、API 简单。它支持本地持久化对中小型项目几十万条以内完全没有性能压力。如果后续数据量上来再换 Milvus 或 Qdrant 也不难因为该换的只是向量存储层管道结构和业务代码不用动。Python 客户端安装pip install chromadb langchain langchain-community langchain-huggingface框架这块我用 LangChain 主要是因为它抽象了文档加载器、文本切分器和向量存储的接口。但我要提醒一点不要把 LangChain 当成黑盒来用。它更像一个“积木盒”每个组件都建议你拆开看一遍接口遇到问题也能精准定位。3.2 索引写入的完整流程与代码我拿一个真实场景来演示假设要做一个“公司内部 IT 运维知识库”原始文档是一堆 Markdown 文件加几份 PDF 手册。索引阶段的三步如下。第一步文档加载。LangChain 的 DirectoryLoader 可以直接批量读取目录下的文件但 PDF 的加载建议单独处理用 PyMuPDFLoader 识别效果比简单的文本抽取好得多from langchain_community.document_loaders import DirectoryLoader, PyMuPDFLoader # 加载 Markdown / txt 文件 md_loader DirectoryLoader(./docs/md, glob**/*.md) md_docs md_loader.load() # 单独加载 PDF保留更多版面信息 pdf_docs [] import os for f in os.listdir(./docs/pdf): if f.endswith(.pdf): loader PyMuPDFLoader(os.path.join(./docs/pdf, f)) pdf_docs.extend(loader.load())第二步清洗。这一步完全依赖你对自家文档的了解。IT 运维文档里常见的噪音是重复的表头、命令行示例中的注释、旧版的废弃说明。我一般用 Python 先统计每条文档的 md5 去重再按章节标题过滤掉“修订记录”“版权说明”这类固定段落from hashlib import md5 seen set() cleaned_docs [] for doc in md_docs pdf_docs: text doc.page_content.strip() if not text: continue # 去除固定噪音段落 if any(noise in text for noise in [修订记录, 版权声明, 禁止外传]): continue # md5 去重 fingerprint md5(text.encode(utf-8)).hexdigest() if fingerprint in seen: continue seen.add(fingerprint) cleaned_docs.append(doc)第三步切分。这里我强烈建议优先用语义切分器RecursiveCharacterTextSplitter它至少不会像固定长度切分那样无情地拦腰截断。但注意语义切分器的本质仍然是“按分隔符层级递归切割”所以你还是需要设置块大小和重叠区间from langchain_text_splitters import RecursiveCharacterTextSplitter splitter RecursiveCharacterTextSplitter( chunk_size512, chunk_overlap64, separators[\n\n, \n, 。, , , ., !, ?, , ;], ) chunks splitter.split_documents(cleaned_docs)关于参数为什么这么定我解释一下chunk_size 512 是在“语义完整程度”和“检索粒度”之间折中的结果。块太大单条块包含多个主题检索命中率上升但准确率下降块太小语义不完整模型又无法组织出完整答案。chunk_overlap 64 是为了防止一个完整语义单元被切分到两个块的边界上让前后两个块各留出一点上下文重叠区。如果你处理的文档本身是“一段一个主题”的结构化文档可以把 chunk_size 调到 800 左右。第四步向量化入库。ChromaDB 的接口很直接通过 HuggingFaceEmbeddings 封装接入 bge-m3。这里有一个非常关键的细节一定要把元数据挂进向量库。我需要把“来源文件名”“章节标题”“文档更新时间”都存到 metadata 里后面做过滤和引用溯源都要用from langchain_huggingface import HuggingFaceEmbeddings from langchain_chroma import Chroma embeddings HuggingFaceEmbeddings(model_nameBAAI/bge-m3) # 为每个 chunk 补充元数据 for i, chunk in enumerate(chunks): chunk.metadata[chunk_id] fchunk_{i} chunk.metadata[source_file] chunk.metadata.get(source, unknown) # 记录切分后的字符数后续调试时有参考 chunk.metadata[char_len] len(chunk.page_content) vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db, )跑完这一段你的本地./chroma_db目录下就会生成持久化向量库文件。索引完以后可以先用一个简单的相似度检索测试一下效果看看切分后的块是否保留了完整语义。我习惯查一堆“测试问题”然后人工看一眼召回的前几条是不是真的和问题相关这一步越早做越省后续排错的力气。3.3 检索与生成的代码链路检索这步最好封装成一个独立函数为后续接入 Agent 做准备。下面这段代码同时包含向量检索和关键词检索的融合逻辑from langchain.retrievers import BM25Retriever, EnsembleRetriever from langchain_chroma import Chroma vectorstore Chroma( persist_directory./chroma_db, embedding_functionembeddings, ) # 向量检索器默认按相似度召回 vector_retriever vectorstore.as_retriever(search_kwargs{k: 20}) # BM25 关键词检索器适合精确匹配专有名词 bm25_retriever BM25Retriever.from_documents(chunks, k20) # 融合检索器两种检索结果各占 50% 权重 ensemble_retriever EnsembleRetriever( retrievers[vector_retriever, bm25_retriever], weights[0.5, 0.5], ) # 查询改写把口语问题转成更适检的语句 from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI rewrite_prompt ChatPromptTemplate.from_template( 请将用户问题改写为适合知识库检索的查询语句保留关键实体输出只包含改写后的查询。\n用户问题{question} ) rewrite_chain rewrite_prompt | ChatOpenAI(modelgpt-4o-mini, temperature0)检索后接重排。我用 FlagEmbedding 的 bge-reranker-v2-m3 做本地重排这个模型对中文支持好而且同时支持多语言。重排阶段我通常让“召回 20 条 → 重排取前 4 条”from FlagEmbedding import FlagReranker reranker FlagReranker(BAAI/bge-reranker-v2-m3, use_fp16True) def search_with_rerank(query: str, top_k: int 4): # 召回 20 条候选 docs ensemble_retriever.invoke(query) if not docs: return [] # 用重排模型给每一条打分 pairs [[query, doc.page_content] for doc in docs] scores reranker.compute_score(pairs) scored sorted(zip(docs, scores), keylambda x: x[1], reverseTrue) return [doc for doc, _ in scored[:top_k]]最后是生成。Prompt 设计我上面说过要点直接给一个我实测好用的模板from langchain_core.prompts import ChatPromptTemplate qa_prompt ChatPromptTemplate.from_template( 你是一个基于知识库回答问题的助手必须严格遵守以下原则 1. 只依据参考资料中的内容回答禁止使用外部知识或自身记忆补充 2. 如果参考资料不足以回答问题直接回复知识库中暂无相关信息 3. 回答时标注每条关键信息的来源文件名与章节放在括号内。 参考资料 {context} 用户问题 {question} 请给出回答 ) def generate_answer(question: str): top_docs search_with_rerank(question, top_k4) context \n\n.join([ f[来源: {doc.metadata.get(source_file, unknown)}]\n{doc.page_content} for doc in top_docs ]) final_prompt qa_prompt.format(contextcontext, questionquestion) return call_llm(final_prompt) # 这里接你的 LLM 调用整体链路到这就打通了。enEmbedding→ 切块 → 入库 → 召回 → 重排 → 生成每一步都有明确的输入输出。接下来我想重点聊一下我怎么在实际项目中调优这个管道因为跑通只是万里长征第一步“好用”才是目标。4. 检索质量才是分水岭命中率、块大小的调试记录很多人的 RAG Demo 能跑通一问就露馅。常见症状是问训练集中出现过的知识点回答得挺好换个问法、换个场景直接答非所问。这一章我专门写写我在调试阶段做过的事情帮你避开我踩过的坑。4.1 建立一套属于自己的评测集没有评测集就没有优化的方向。我建议每个 RAG 项目开始前就先花半天建一套“黄金问题集”50 到 100 条。每一条包含四列问题、知识库中对应的黄金文档块 ID、问题类型术语查询/流程查询/FAQ/对比分析、难度等级。这套问题集的作用是在后续做任何策略调整时都能跑出两个指标对比。评价指标我用两个维度Hit Rate命中率Top-K 召回结果中是否包含黄金文档块。这个指标衡量的是“文件有没有被找到”。MRRMean Reciprocal Rank黄金文档块在召回列表里的排名倒数平均值。这个指标衡量的是“正确的文件排得够不够靠前”。实测结果最有说服力。我有一次把 chunk_size 从 512 调整到 256Hit Rate 从 81% 提升到了 88%但 MRR 反而从 0.62 降到了 0.51。原因很好解释小块更容易被检索命中但因为粒度太细黄金答案经常被切成了两半正确块虽然出现了但排名分散前几名不是完整的答案。最后我反过来采用“512 为主块 256 子块再检索”的策略Hit Rate 和 MRR 才同时提升。这种矛盾要靠评测集去暴露单靠感觉根本发现不了。4.2 切分策略的实战对比切分策略是我的重点调试对象。下面这个表格是我在同一个知识库约 200 篇运维文档上做的一组对比测试控制变量只改切分方式其他环节完全一致切分策略参数Hit Rate5MRR5主观回答质量固定字符切分512字符62%0.41差语义断裂严重递归结构切分chunk512, overlap6478%0.55中上语义切分 markdown headerchunk512, overlap6481%0.62好语义切分 摘要增强chunk512, 每块附带父块摘要86%0.70好上下文更完整摘要增强的做法值得展开说一下。我在每个文本块入库前用轻量 LLM 给该块所在的“父段落”生成一段 2 行摘要把摘要和原文块拼接后再向量化。这样当用户问题比较宽泛时摘要块能承担“引导定位”的作用当用户问题比较具体时原文块提供细节。缺点是多了一次 LLM 调用索引成本大概增加 30%但对于知识库更新频率不高的场景这个成本完全可以接受。4.3 检索链路上的“噪音块”问题即使重排环节做得再好还是会遇到一种情况召回 Top-K 里正确的那条确实在里面但其余的 9 条都是噪音块模型在生成时被噪音带跑偏。我试过最离谱的一次用户问“服务器重启命令”召回的前 10 条里有一条是“备份策略中关于服务器重启导致的数据同步注意事项”字面上句句不离“服务器重启”但实际上跟“怎么重启服务器”没有半点关系。我解决这个问题的方法分两步。第一步是在重排阶段用阈值过滤如果某条候选的相关性分数低于人为设定的阈值直接丢弃而不是强行凑满 Top-K。第二步是在生成阶段Prompt 里明确加一条“如果参考资料中存在相互矛盾或与问题无关的内容忽略它们优先采信与问题直接相关的条款”。这两步组合下来模型被噪音带偏的概率明显下降。4.4 别忽视元数据过滤这个杠杆很多人的知识库是“一个大杂烩”有产品手册、有 FAQ、有售后记录、有内部培训资料。不同类型的资料答同一类问题时优先级完全不同。比如“这个功能收费吗”这个问题产品手册里的价格说明远比培训 PPT 里的功能介绍有说服力。我建议在索引阶段就把文档类型写进元数据比如doc_type: manual、doc_type: faq。检索阶段根据问题类型做元数据预过滤。比如财务类问题只检索“doc_typefinance”的文档不做全库无差别检索。这个优化在调试阶段不太显眼但在线上知识库体量变大以后它能把检索噪音降低一个数量级而且实现成本几乎为零。4.5 使用现场的实际表现本地部署的硬性门槛有一个经常被忽略的点是——如果你给企业做 RAG知识库往往要部署在客户的内网环境。客户只给你一台 CPU 机器或者一块 T4 显卡。所以我在选 Embedding 模型前都会先问清楚部署环境。bge-m3 在 CPU 上跑512 条文本索引大约每秒处理 3 到 5 条整个索引流程可能慢到让人叹气。这种情况下要么压缩文档规模要么换成更轻量的 bge-small-zh要么分批离线索引。部署场景的差异会直接影响模型选型这也是我推荐在动手之前先做“环境探测”的原因。5. 从基础 RAG 到 Agentic RAG把知识管道接进 Agent 的思考链路讲完了基础 RAG 的搭建最后我来画一条延伸线它是怎么接入 Agent 的以及为什么现在大家都在聊 Agentic RAG。5.1 基础 RAG 在 Agent 里的两种接入方式第一种方式最简单把整套 RAG 管道封装成一个 Tool。Agent 在思考过程中决定“我需要查资料了”的时候就调用这个工具传入查询语句拿到召回结果。具体到代码上我在 LangChain 里是这么封装的from langchain.tools import StructuredTool from pydantic import BaseModel, Field class RetrievalInput(BaseModel): query: str Field(description要检索的内容描述尽量包含关键实体和意图) retrieval_tool StructuredTool.from_function( funcsearch_with_rerank, nameknowledge_base_search, description在内部知识库中检索相关信息。当用户问题涉及公司制度、产品参数、操作流程、历史方案时使用。, args_schemaRetrievalInput, )这个 Tool 有一个特别需要琢磨的细节description 里要写得“什么情况下用”而不是只写“这是什么”。因为模型靠 description 判断要不要调用这个工具你写得太窄它该用的时候不用写得太宽它不该用的时候也乱用。我多次实测下来把“适用场景”和“不适用场景”都写进 description 效果最好。第二种接入方式是把 RAG 当成 Agent 的“外部记忆系统”。这种设计不那么显式但我觉得更接近本质Agent 的规划模块决定“要完成当前子任务需要知道哪些知识”再调用检索工具获取。两种方式在工程上其实差别不大但思维方式不同。前者是“工具调用”后者是“认知循环”。Agentic RAG 的理念就是建立在后者之上的。5.2 Agentic RAG检索不再是“一次就完”基础 RAG 的检索是“用户问题进 → 召回结果出”一次搞定。实际情况往往没那么简单。比如用户问“分公司报销制度跟总部有什么区别”如果知识库里这两个制度分开在两份文档里一次检索很难同时拿到两份完整内容模型就会只看到一份制度然后编造差异。Agentic RAG 解决这个问题的方式是把检索工具交给 Agent 自主调用。Agent 先检索总部报销制度再检索分公司报销制度然后带着两个结果一起推理。如果第一次检索结果不够用Agent 会根据当前结果分析“还缺哪块知识”主动发起第二次检索。在 LangGraph 这类 Agent 框架里检索逻辑就是一个可循环调用的节点直到 Agent 判断信息足够为止。这种设计在工程上意味着检索从“一次性函数”变成了“可多轮交互的服务”。你封装 Tool 的时候就需要支持连续问答式的检索而不是只给一个 Top-K 列表。我见过比较优雅的做法是Tool 返回的不只是文本块还附带“该块来自哪个文档、相关文档还有哪些”这类扩展信息供 Agent 决定下一步检索方向。5.3 知识割裂的下一步GraphRAG 与本体思路热词里你可能会看到 ontology rag、graphrag、llm wiki 这些相关方向它们本质上都指向同一个痛点现有 RAG 的“块”是割裂的实体间的关联关系丢失了。基础 RAG 把一篇文档切成独立的块块和块之间没有任何关系也就无法回答“A 系统影响了 B 系统的哪些功能”这类跨文档推理问题。GraphRAG 的思路是在切块入库的同时抽取文档里的实体和关系构建一张知识图谱。检索时不仅召回相关文本块还沿着图谱找到关联实体附近的信息。这样“跨文档关联推理”能力会明显增强。微软开源的 GraphRAG 项目走的就是这个路线。我的建议是不要在基础阶段直接上 GraphRAG。它的索引成本和工程复杂度比基础 RAG 高一个数量级。正确的路径是先把基础 RAG 做到稳定好用再根据业务是否真的需要“跨文档关联推理”来判断要不要引入图谱。知识割裂的问题一定存在但你需要先确认是“检索不够准”还是“答案本身需要跨文档推理”。前者的解法是重排和查询改写后者才需要 GraphRAG 这类进阶方案。5.4 从 RAG 到 Agent 的落地顺序先稳定性后智能化我一向主张工程的节奏要稳。如果你正在从零搭建一个带知识管道的 Agent我建议按这样的顺序推进先搭基础 RAG把离线索引、在线检索、问答生成三个子模块跑通。建立黄金评测集用数据驱动的方式调优切分参数和检索策略。把 RAG 封装成稳定可靠的 Tool在 Agent 的“工具选择列表”里先让它成为默认必选。确认基础问答的准确率和检索命中率达到业务可接受线之后再引入多轮 Retrieval、子问题分解、图谱增强等 Agentic 能力。这个顺序的核心逻辑是每一步的产出都能验证每一步的失败都能定位。如果直接让 Agent 自主检索你分不清问题是出在“Agent 不知道用什么工具”还是“RAG 管道本身检索质量差”。先让管道本身足够可靠再把决策权交给 Agent。最后说一句这个系列一直延续的观点AI Agent 的能力边界很大程度上取决于它接入了多高质量的知识管道。RAG 基础这一篇我把从索引到生成全链路都过了一遍代码和调优思路都放在上面了。下一篇我会专门展开 Agentic RAG 的实战讲讲多轮检索、子问题分解和工具自主决策这些进阶玩法希望能帮你在落地 Agent 的路上省点时间。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询