拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AI Agent知识管道实战:从RAG基础到Agentic RAG落地

做过Agent的朋友应该都有一种体会模型本身能说会道但真正让它靠谱地完成任务它得先“知道”该知道的东西。我在这个系列的前三篇里从Agent的基本构成写到核心循环这一篇终于要聊一个落地时躲不开的模块——知识获取管道也就是RAGRetrieval-Augmented Generation检索增强生成。RAG不是什么空泛概念它实质上是把外部知识变成可检索、可引用的语料再让模型基于这些语料回答问题的整套工程链路。这篇适合谁看想从0到1搭建AI Agent、要给Agent接入私有知识库或者刚接触RAG却被各种名词绕晕的人。看完你应该能理解RAG在Agent里的位置也能直接上手搭一条最小知识管道。1. 模型里的知识是死的管道里的知识才是活的很多人刚开始做Agent时会有一个错觉只要模型够聪明什么都能答。这个错觉很快会在实际项目里被打破。你会发现模型对公开常识表现很好一旦你问它公司内部制度、产品版本差异、某个项目的历史决策它要么开始一本正经地编要么说“我不知道”。这不是模型不行而是它根本没有途径获取这些你不知道、它也不知道的信息。1.1 参数知识、上下文与外部知识的三角关系大模型脑子里存的东西叫“参数知识”训练完之后就固化在权重里了。它有一个明确的时间截止点也不可能因为你晚上更新了一份文档就自动知道新内容。所以想让Agent处理不断变化、私有化、垂直领域的知识只有三条路把内容硬塞进上下文窗口但这受限于上下文长度而且每次都要重新塞一遍成本和延迟都受不了让Agent调用外部API实时查数据适合结构化数据比如查天气、查库存用RAG把文档切碎、索引、检索然后把命中的片段塞进上下文让模型基于片段回答。这三条路不是互斥的。一个成熟的Agent通常三者混用。RAG解决的是“大量非结构化文本怎么按需进入对话”的问题。它最核心的价值不是让模型记住更多而是让模型知道去哪里“查”以及查到的内容可以被追溯和验证。1.2 知识管道在Agent整体架构中的真实位置如果你画过Agent的架构图通常会看到感知、规划、记忆、行动这几个模块。知识获取管道横跨“记忆”和“行动”之间它把外部文档变成一种可检索的长期记忆同时又能像一个可调用工具一样被Agent主动使用。我在第一篇文章里提到过Agent的核心循环是“感知—规划—行动—观察”。RAG刚好嵌入在“规划”和“行动”之间Agent接到用户问题后先判断自己是否缺少相关知识如果需要就触发一次知识库检索把检索结果作为上下文输入给模型模型再组织回答。因此不要把RAG理解成“在对话前做一次搜索”它应当作为Agent决策链路上可以被反复调度的一环。这样后面讲Agentic RAG时你才能理解为什么不是“加个向量库”就完事。1.3 三种知识获取方式的对比我在带项目时经常用一个简单表格帮团队对齐概念这里分享给你方式适用场景主要优点主要缺点上下文直接注入少量、一次性内容实现最简单模型理解最充分浪费token无法扩展工具/API查询结构化、实时数据精确、权威、可写回需要接口维护语义理解弱RAG检索大量非结构化文档可扩展、可追溯、可持续更新工程链路长效果依赖分块与检索质量记住这个前提RAG不是要取代工具调用也不是要把所有知识都塞进上下文。它是给Agent补上“大块文本知识”这块拼图。搞清楚了RAG在Agent里的位置后面那些参数调优才有意义。否则你很容易陷入“为什么我加了RAG还是答不对”的泥潭却不知道问题出在知识没有被Agent正确调度而不是知识库本身没建好。2. 最小可用的RAG管道加载、分块、索引、检索聊完概念直接上手。一条最小可用的RAG管道拆开看就四步加载文档、切分文本、向量化索引、检索上下文。如果只是做原型验证这一步半天就能跑通。我以基于LangChain的流程为例这是目前社区里最常见、资料也最全的做法。2.1 文档加载比想象中麻烦的环节很多人以为文档加载就是read(), 真正做过才发现麻烦事一大堆。PDF有多种排版、Word里有表格、扫描件要OCR、网页要抓正文去广告。加载做不好后面全白搭。我建议第一版只支持Markdown和纯文本先把管道跑通。PDF等复杂格式可以放到第二版用专门的解析服务来处理。用LangChain的话这一步通常是from langchain_community.document_loaders import TextLoader, DirectoryLoader loader DirectoryLoader(./docs/, glob**/*.md, loader_clsTextLoader) docs loader.load() print(len(docs))这一步的目标只有一个把乱七八糟的文档变成干净的字符串并且保留结构信息。注意如果你用TextLoader它不会帮你处理PDF里的表格也不会保留目录层级。对第一版来说这没问题但你心里要清楚。2.2 分块策略为什么不能把整篇文档丢给模型文档读进来之后你不能直接把它全部塞进向量库。原因有两个一是embedding模型有最大输入长度限制二是检索粒度太粗会导致精度极差。想象一下你问“退货政策是什么”如果整个200页用户手册被表示成一个向量那这个向量的语义会被铺天盖地的其他内容稀释根本检索不准。分块要把握“语义完整”和“尺寸足够小”的平衡。我第一版推荐用递归字符分割器代码很简单from langchain_text_splitters import RecursiveCharacterTextSplitter splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap80, separators[\n\n, \n, 。, , , , ], ) chunks splitter.split_documents(docs) print(chunks[0].page_content)chunk_overlap很多人不理解它的作用是让相邻两个片段之间有部分重复内容防止句子被拦腰切断导致语义丢在“分界线”上。separators里放了一串从长到短的分隔符程序会优先按段落切再按句号切最后才按字符硬切。设置chunk_size时最好考虑embedding模型的输入上限如果你的embedding模型最多支持512个token那500字符是比较合理的起点。2.3 向量化与索引选Embedding模型和向量库分完块之后就是给每个块算一个向量。这一步决定了“检索到的内容”和“用户问题”之间能不能对得上。我见过太多新手在OpenAI的embedding和开源的BGE之间纠结半天其实思路很简单中文内容优先考虑BAAI/bge-m3或m3e系列开源、本地可跑、中文效果好如果公司预算允许也可以直接用云厂商的文本向量接口胜在省心向量维度不是越高越好维度高意味着内存占用大检索未必更准。构建索引这一步推荐先拿FAISS顶一阵。FAISS是元数据库内存型、部署简单适合原型和小规模知识库。生产环境再考虑Qdrant、Milvus或Elasticsearch。示例代码from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import FAISS embeddings HuggingFaceEmbeddings(model_nameBAAI/bge-m3) vectorstore FAISS.from_documents(chunks, embeddings) retriever vectorstore.as_retriever(search_kwargs{k: 6})这里k6表示每次检索返回6个片段。第一版别贪多先返回6个试试效果。你会发现有些问题一个片段就够有些问题需要六个片段才能凑齐答案这就是后面讲Agentic RAG时要解决的问题。2.4 检索与调用拿到片段之后别直接丢给模型检索不是终点。你拿到的6个片段可能只有两个有用剩下四个是噪音。如果在提示词里没有约束模型可能被噪音带偏。所以我习惯把检索结果做成带引用的提示词块要求模型“只基于给定的片段回答不要臆测”并标注每个答案来自哪个片段。这一步虽然简单但效果提升很明显。到这一步“加载—分块—索引—检索”的最短闭环已经可以回答简单问题了。我常跟团队说先把这条管道跑通再谈优化。因为只有跑通了你才知道哪些地方真正拖了后腿。接下来我讲的调优经验就是基于这条最小管道展开的。3. 决定RAG上限的分块与检索细节实测经验和参数解释很多文章会把RAG讲成“文档切一切、向量存一存、搜一搜”的三步曲。真做进项目里你会发现这条链路里每个环节都有坑。我在这里把踩过的坑和验证过的经验集中说一下。3.1 分块大小不是玄学是匹配问题我第一次做RAG时所有文档统一用512字符分块结果问答效果极差。后来排查发现不同文档需要的分块策略完全不同。我的经验大致可以总结成一张表文档类型推荐分块方式推荐大小原因政策制度、文章正文按段落切300-500字符语义完整上下文明确FAQ、名单类按问答对/条目切逐条避免把多个问题混在一起表格类保留Markdown表头行小表格整块表格拆开会丢列含义代码示例按代码块切尽量整块拆开会出现语法不完整分块的本质是“匹配用户提问的粒度”。用户问“退款周期是几天”你希望命中的是一个清晰的条款段落而不是半页产品说明书。所以在处理结构化内容时优先保留结构比如Markdown标题、表格的行列关系而不是机械地按字符数硬切。这比任何参数优化都重要。3.2 查询改写用户的问题太口语化怎么办另一个常见问题是用户问法跟文档措辞完全对不上。比如文档里写的是“售后服务承诺”用户问的是“坏了咋办”。向量检索的相似度在这种情况下经常翻车。解决方案是加一道查询改写让Agent先基于用户原问题生成几个更完整、更书面化的检索式。我说的查询改写不是写死几个同义词而是让模型先对用户输入做一次“转述”。举个例子用户问“它多少钱”改写后的检索词应该是“当前查询对象的价格信息”。这一步可以用一个快速模型完成不消耗太多算力但对召回率提升很明显。另外还有一种技巧叫HyDE就是让模型先基于问题生成一个“假设答案”再用这个假设答案去检索效果在部分场景下不错但会增加延迟我一般只在特定业务里用。3.3 重排序第一次检索不要太较真重排再把关如果你只做一次向量检索就把结果交给模型效果通常只有六十分。原因在于向量检索的目标是“召回”不是“精排”。第一轮用较小的top_k召回30个候选再用一个交叉编码器模型对这30个候选重新打分最后只取前5个进上下文。这比直接调大向量检索的k值有效得多。重排序模型可以理解为“把问题跟候选片段逐一做深度匹配”的分类器比双塔结构的embedding相似度更精准。中文场景下bge-reranker-base是个不错的起点。添加重排模块之后常见的效果提升是“回答置信度显著上升”因为噪音片段被过滤掉模型没有机会被无关信息牵走。3.4 用hit rate说话先建评测集再谈优化很多团队调RAG全靠“感觉这回答不错”这不行。RAG工程里最该先做的事情是花一两个小时构建一个最小评测集。所谓评测集就是20到50对“问题—标准答案片段来源”。然后定义一个指标最常用的是hit rate也就是“前k个检索结果里是否包含标准答案所在的片段”。给一个很朴素的Python示例hit_count 0 for q in eval_set: retrieved retriever.invoke(q[question]) ids {doc.metadata[source_id] for doc in retrieved} if q[source_id] in ids: hit_count 1 hit_rate hit_count / len(eval_set) print(fhit_rate{k} {hit_rate:.2f})hit rate高不等于回答一定对但hit rate低说明检索环节已经失败后面模型再聪明也没用。我一般要求线上知识库的hit rate至少到0.7再谈回答质量。你可以把评测集保存成一个JSON文件每次调分块参数、换embedding模型时都跑一遍用数字对比而不是凭记忆说“好像变强了”。4. 从基础RAG到Agentic RAG知识管道怎么变成Agent的决策能力文章开头我说过RAG在Agent里不是一次性的前置搜索。当你把RAG和Agent的规划能力结合起来就出现了社区里常说的Agentic RAG。这可能是你在热搜词里看到它却觉得陌生的原因其实它并不难理解普通RAG是“用户问一次系统查一次”Agentic RAG是“Agent根据问题自己决定查什么、查几次、要不要换一种方式查”。4.1 一次检索搞不定的问题类型我举一个很现实的例子。用户问“我们公司最近更新的报销制度里差旅住宿标准是多少对比三个月前有什么变化”这种问题涉及两个知识片段一个是新制度中的住宿标准一个是旧版本制度。如果你只做一次向量检索很可能只拿到其中一个片段甚至两个都拿不到因为旧版本文档可能已经被移出主知识库。这种情况下Agent需要先识别出“这个问题需要分别检索新旧两份制度”然后发起两次检索再把结果合并比较。这不是模型读一遍提示词就能完成的它需要在规划阶段就拆解子任务。也就是说RAG从“一个工具”变成了“被Agent调度的能力组合”。4.2 几种常见的Agentic RAG模式我在项目里常用这么几种模式你可以从易到难逐步尝试路由式先判断问题属于“闲聊”还是“知识库问答”还是“实时查询”然后决定是否触发RAG。实现简单效果稳定。工具编排式把多个检索器封装成不同工具比如“政策文档检索器”“产品手册检索器”Agent根据用户问题的领域选择调用哪一个。这种模式解决的是多知识库混合场景。多轮自适应式第一轮检索结果不够时Agent根据缺失信息自动改写检索词再查一次。有点像人查资料的“不满意再换关键词”的过程。反思式模型先生成答案然后用检索证据对答案做事实核对发现对不上就回退重新检索。这类模式最接近Self-RAG的思路但实现成本和调试难度也最高。别一上来就追求最复杂的反思式。我自己的路径是先做路由式保证“不该检索的时候不检索”然后给Agent加一个查询改写的小工具最后才尝试多轮自适应。每一步都用评测集跑一遍hit rate确认有效再往下走。4.3 把RAG封装成Agent的Skill怎么描述才不会被乱调在Agent开发框架里检索能力通常以一个“Skill”或“Tool”的形式暴露给大模型。这里有个关键细节描述信息写不好Agent就不知道什么时候该调用甚至把每个问题都丢进知识库。我习惯在技能描述里写清楚三件事这个技能解决什么类型的问题、什么时候不要用、参数应该如何规范化。一个配置示例大概长这样{ name: search_knowledge_base, description: 当用户询问公司制度、产品文档、操作手册或政策条款时使用该技能检索知识库。闲聊、数学计算、实时行情类问题不要使用。, parameters: { question: { type: string, description: 把用户问题改写为名词化的检索描述 } }, returns: [retrieved_chunks, source_ids] }你看这里最值钱的是“什么时候不要用”这句话。我踩过很多次坑Agent明明可以用自身知识回答的问题偏要去检索一顿结果拿回一个不想关片段反而答错了。把边界写清楚能省掉后面大量的拒答调优。4.4 GraphRAG和Ontology RAG别在基础没打牢时冲锋最近GraphRAG和Ontology RAG的概念很热我也看到很多人在聊。它们的核心思路是在普通向量检索之外再叠加一层实体关系图让模型能回答“A与B之间有什么关系”这类多跳问题。听起来很酷但我的建议是先把普通RAG做到hit rate达标、引用清晰再考虑图结构。GraphRAG不是简单“加个图谱库”就行的它需要高质量的知识抽取成本高、更新难。如果基础向量检索都没做好叠加图谱只会放大错误而不是弥补错误。你可以先把它列入观察名单等知识库稳定了再来评估是否真的需要。5. 落地选型与上线避坑本地知识库怎么选别为了炫技买单最后聊一聊部署和上线。你一定在热搜词里看到过“搭建本地RAG”“rag本地知识库”很多人确实有私有化部署的需求。但“本地”不是目标是手段。先搞清楚你要解决什么问题再选技术栈不然很容易买一堆资源却交付不了。5.1 本地部署还是云上服务先算账本地RAG的好处是数据不出内网适合机密文档多的企业而且不依赖外部API延时可控。坏处是硬件、运维和模型迭代成本都自己扛。云服务则反过来上手快、按量付费但隐私合规要仔细看条款。我的建议很简单如果知识库只有几百份文档、调用量一天几千次先用本地小模型加FAISS就够如果知识库达到几百万份文档、需要高并发检索再认真评估Elasticsearch、Milvus这类分布式方案。别在第一天就搭一套Kafka加Spark的“大数据检索平台”那是给自己挖坑。5.2 常见技术栈组合Python和Java生态都没有缺席从社区现状看LangChain起步快适合快速验证。如果你负责的是Java后端也不用担心langchain4j和Spring AI都在提供RAG抽象逻辑跟Python版本类似只是接口风格不同。我在实际项目里见过的那套“本地ERP加RAG加LLM做产品检索”本质也都是同一条管道转文档、切块、向量化、检索、进提示词。我提供一个偏生产向的组合参考模块原型阶段生产阶段文档解析LangChain LoaderUnstructured/自研解析服务分块RecursiveCharacterTextSplitter结构化感知分块EmbeddingBGE-M3本地模型BGE-M3或云向量接口向量库FAISSQdrant/PGVector/Elasticsearch重排bge-reranker-base交叉编码器加工程配置这个表格不是标准答案只是我试过比较稳的组合。生产阶段要注意向量库不能裸奔最好加上元数据过滤和权限过滤。权限过滤的意思是一个普通员工检索时不应该命中文档库里“高管薪酬”这种权限外片段。这是我见过最容易遗漏的安全点。5.3 上线后的常见问题排查链路我给团队排查线上RAG问题时一般按“召回—重排—生成”三层定位。用表格总结一下现象可能原因排查方法优先处理检索结果明显不相关分块太大/太小embedding域不匹配抽查分块内容跑hit rate调整分块策略检索结果为空元数据过滤条件太严或索引构建失败看向量库count测试去掉过滤放宽过滤条件答非所问检索结果相关但被噪音干扰检查提示词和重排结果加引用约束、调重排幻觉严重模型知识太强不信任检索片段试探性去掉RAG输出对比强化提示词必要时换更强模型知识更新不生效索引没重建或检索到了旧版本片段查文档更新时间字段加版本过滤定时重建索引这套排查逻辑能覆盖八成以上的线上问题。核心思想是别一看到回答差就去换大模型先用评测集和hit rate确定问题到底出在哪一层。5.4 知识库清洗垃圾进垃圾出最后一个我要强调的点听起来像废话但真正做到的人不多RAG的效果天花板取决于语料质量。如果原始文档里有大量扫描件OCR错字、过时政策残留、重复内容再强的检索模型也救不回来。我经历过一个项目客户抱怨RAG一直答错排查到最后发现知识库里同时存在两个版本的员工手册旧版本还排在前面。这种事在真实项目里太常见了。所以在建库之前先把文档去重、确认版本、处理明显的OCR错字成本远低于后面所有环节的调优。知识库的“入库管理”这件事应该被当作正式流程来做而不是随缘导入。说到这这篇RAG基础其实已经讲得比较透了。我自己做了好几个Agent项目后最大的体会是RAG不是终点它只是Agent获取知识的管道之一。先把这条管道用最简单的方式打通、测准再根据业务需要逐渐加上查询改写、重排、权限过滤和Agentic的调度逻辑这个顺序比什么都重要。真到了那一步你会发现后面那些“更高级”的概念跟“糟糕的检索聪明的模型”完全是两回事而正确的前提永远是先把基础知识管道搭扎实。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门