ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RAG管道全解析:从文档切分到Agent知识获取的实践指南

RAG管道全解析:从文档切分到Agent知识获取的实践指南 1. 为什么说RAG是Agent的知识获取管道如果只看模型本身你会发现一个挺拧巴的现象大模型肚子里装了海量的常识但你一聊到具体业务它就露馅。比如模型能给你背出《红楼梦》的判词你问它我们公司售后政策里写着超过十五天能不能退它就哑了——不是它偷懒是这类私有知识它压根没见过。我在做Agent项目时有句话常挂嘴边模型负责聪明知识库负责知道。一个Agent没有外部知识获取机制就像高材生被关在没有资料室的房间里考试脑力再强也只能瞎猜。这也是第四篇我想把RAG单独拎出来讲的直接原因——它是Agent考试时补充资料的那个通道也就是知识获取管道。需要先说明一点这套内容适合有基本Python经验想从零理解RAG原理并在自己Agent里落地知识查询能力的开发者。如果你已经用过LangChain但始终说不清每个环节在干什么这篇文章也能帮你把概念和实操之间的裂缝填上。1.1 Agent的知识饥饿模型自带的只是常识聊训练数据这件事得先放下一个错觉模型不是数据库它是学会如何预测下一个词的统计机器。它的记忆是某种压缩过的、模式化的东西不是逐字记下原文等你查询。这带来两个致命限制一是训练语料有截止时间之后的新消息它不知道二是任何私有数据只要没有公开到训练语料里对它来说就等于不存在。Agent想在真实业务里跑起来面对的恰恰是这两个边界。拿客服场景举例你给Agent的工单系统、产品手册、退货政策都是私有文档模型连看都没看过你让它自动处理一条昨天用户提交的工单这些内容比训练数据还新。靠推理硬编是不可能的必须先有一个喂知识的通道。这里要区分一个概念知识获取和上下文不一样。往上下文窗口里塞几段检索出来的相关资料是一种临时借用知识的方式而RAG做的是为每次提问现找现用——它不试图让模型记住知识而是让模型在回答问题的那一刻手里恰好有正确的资料。这个区别看着小实际决定了RAG的系统设计方向存储、索引和检索才是主角模型只是最后一步的阅读者。1.2 三种知识注入路线对比为什么RAG是主流想让模型知道某个新领域的知识市面上就三条路线微调、长上下文、RAG。我见过很多团队上来就想微调结果折腾一个月效果还不如直接prompt示例给得好。微调的本质是改变模型的权重让它把某些知识内化。它适合风格迁移、输出格式固定、特定领域术语习惯等场景但它有三个硬伤训练成本高一截、每次知识更新都要重训、以及改完权重你很难追溯模型到底学没学到、学到哪一步了。如果你只是想让模型知道一份动态变化的政策文档微调是最不划算的方案。长上下文则是把希望寄托在更大的窗口上。这两年窗口确实越做越大但能装下和用得好是两回事。窗口变大后模型在超长上下文里的注意力会出现稀释位于中部的信息更容易被忽略业内管这个叫lost in the middle。而且每轮都塞全量文档成本和延迟直线上升这跟Agent多轮交互的场景基本是冲突的——你不会想让Agent每次回答前都读一遍整个产品目录。RAG站在中间的位置它把知识从模型内部挪到了模型外部。知识存在知识库里每次有提问检索出最相关的几个片段拼进Prompt。好处立刻就能看见知识可以随时换、随时更新成本可控而且回答可以带来源链接用户能验证模型的幻觉空间也被压缩了。这也是现在几乎所有生产级AI应用默认使用它的原因。1.3 管道到底管什么四个环节的职责切分我这些年带项目觉得用一个比喻理解RAG最好使它是一条流水线原料是你的原始文档产出是模型的回答中间四个环节各有分工。第一个环节是解析与清洗。PDF、Word、Markdown、HTML各有各的结构表格、代码块、扫描件各有各的坑。这一步的目标只有一个把一份文档变成机器能读、且保留了足够语义信息的纯文本。第二个环节是分块与向量化。把长文档拆成合适大小的块然后交给嵌入模型把每个块变成一个高维向量。这一步最关键因为后面检索什么完全取决于这里块切得对不对、向量算得准不准。第三个环节是检索。用户提问时把问题也向量化然后在向量空间里找距离最近的那几个知识块。这里有个容易忽略的事检索到的内容质量决定了下游生成的上限。分类模型做得再烂只要检索没检索对回答就不可能对。第四个环节是生成。把用户问题加检索到的文档片段按一定模板拼进Prompt交给大模型让它基于这些材料回答。生成环节听起来最简单实际讲究更多怎么排布、怎么避免模型忽略中间块、要不要带引用、指令该怎么写都有经验在里面。这四个环节环环相扣任何一个瘸腿都会拖垮整条管道。下面我按管道顺序从数据预处理一路写到生成环节把每一段的原理和实操都拆开来讲。2. 管道第一站知识从文档到索引这一站经常被低估。很多教程demo里三步就完成了加载让人觉得文档处理没什么可讲的。但真正在生产里跑过的人都有同感RAG系统的最终效果有相当一部分在源头就注定了——垃圾进垃圾出。2.1 文档解析别小看PDF和网页的处理差异先说最常见的坑。把一份PDF直接丢给解析工具你会得到各种残次品扫描件会变成一张张图片文字根本抽不出来文字版PDF里的表格会被横七竖八地切成碎片多栏排版的技术文档解析后逻辑顺序是乱的本属于同一段的内容可能被拦腰断开。处理PDF我通常先判断它是文字型还是扫描型。文字型用常规解析器能拿到可编辑文本但表格和排版还是要额外处理——比如某些工具可以按行或按块提取你能保留下标题的层级关系这对后面分块大有帮助。扫描型必须先做OCR这一步会有识别错误必须配合后续清洗。如果你想偷懒现在很多文档解析服务号称PDF转Markdown一步到位实测下来对简单文档还行遇到复杂排版仍然会出错别把宝全押在它身上。网页抓取是另一个常见来源。HTML里到处都是导航栏、广告位、版权通告直接拿正文会惨不忍睹。我在做数据抓取时会先做两步用选择器定位正文容器把整个页面裁出来再把多余DIV剥掉只留标题、段落、列表、表格这类语义元素。处理完的数据干净了嵌入模型算出来的向量才不会跑偏。还有一类容易被忽略的是多页文档的连续性。一本操作手册如果按页码被硬切成单页上下文就碎了第3页说按上一步操作…第2页的内容在另一个块里检索的时候就对不上。所以解析完还要做拼页处理把属于同一章节的内容重新粘起来。这个细节看着小实际决定了多轮检索的稳定性。2.2 切分策略chunk size为什么是玄学切分是整个RAG里最没有完美答案的环节。块太大嵌入时信息被稀释检索回来的块里可能只有一小段是用户关心的块太小单个块缺乏上下文检索结果是零碎句子没法直接用来生成答案。这事没有银弹但有几个方向可以把握。固定长度切分是最朴素的做法按字符数或token数硬切常见配一个overlap来保证相邻块之间不丢上下文。我自己的起步配置一般是512个token左右的窗口配80个token的重叠然后根据实测效果慢慢调。纯固定切分的毛病是容易打断句子甚至打断句号内容语义完整性没保障。进阶一点的做法是按文档结构切分。既然Markdown有标题层级、PDF有章节标记切分器可以先识别结构以标题为边界做递归切分遇到大标题开新块子标题下内容足够长再继续切。这样切出来的块几乎不会出现语义断裂检索命中率会明显提高。我强烈建议文档从源头就保留好结构信息这对后面所有环节都是福报。语义切分是更激进的路线先切一小段送进模型让它判断和下一段是不是同一主题靠语义连续性来决定边界。效果最好但成本高、速度慢适合文档总量不大但对效果有极致要求的场景。多数业务场景按结构切分已经是性价比很高的选择。切分完之后还有一步容易漏掉的——清洗。空行、重复的页眉页脚、乱码字符要在向量化之前清理掉。我见过有团队把每一页的产品操作手册页眉一并嵌了进去结果检索时用户问任何问题都能匹配到一堆这个页眉一次检索8个结果有5个是垃圾。这种问题查起来很隐蔽但源头其实只需要过滤一下行内容就能避免。2.3 嵌入模型选型与向量库选择分好块之后要做的就是把每个块变成高维向量。这里涉及嵌入模型的选型。中文场景下我常用的思路是优先考虑在中文语料上表现好的模型比如现成的bge系列或同类开源模型。嵌入模型决定了语义距离的质量选得好检索才有基础。嵌入模型有几个参数要心里有数向量维度决定了存储和检索的规模维度越高越占资源但表达力不一定线性提升最大输入长度限制决定了你喂进去的文本不能太长超出就要截断或调整。选模型时可以做一个小样本测试准备一批问题让系统和答案片段计算相似度看看相关结果的得分和非相关结果的得分分得开不开了。分不开说明嵌入模型选得有问题。向量库的选择要看你的数据规模和使用场景。几百条文档做成demo用轻量级库或嵌入式向量库就够了Redis、Chroma这类都能跑部署省事。数据量到了百万级生产服务化部署就需要Milvus或Elasticsearch这类专门的向量搜索引擎了。不必一开始就上重型武器等量来了再迁移迁移成本没有想象中那么大——前提是你从第一天就把文档ID、切块内容、向量、元数据这套schema设计好。这里还要多说一句向量库本质是个数据库除了存向量还要存原始文本和元数据。因为检索出来后最后给模型看的是原文不是你算出来的那个向量。如果你只存向量不存文本检索再多结果都白搭。3. 管道第二站检索召回质量的分水岭检索是RAG里最能体现工程师水平的地方。原因也简单生成环节有太多现成的模型可以兜底但检索错了模型再聪明也只能在错误材料上编答案。这一站的成色直接决定系统可用性。3.1 从关键词匹配到语义匹配早期的信息检索靠词面匹配用户搜退货文档里没有退货这个词但有退款那就算没匹配上。关键词匹配的问题就在这——同义词、近义词、换种说法就查不到了。向量检索的思路完全不同。嵌入模型把文本和问题都映射进一个高维语义空间语义相近的文本在空间里天然距离就近。你问退货流程块里写申请退款的操作步骤虽然词面不重叠语义上也该被搜出来——向量检索能解决这种场景。但这不意味着向量万无一失。在实际测试里向量检索对专有名词、缩写、型号这类精确信息经常翻车PLC-3000这种序列号语义匹配很难比得上正则匹配和关键词语义一致。整件包含所有现象更好更通用的做法是混合检索用BM25做关键词召回同时做向量语义召回然后把两路结果合并去重再统一排序。这样既保住语义泛化能力也保住精确匹配能力是我在所有生产项目里的默认配置。3.2 召回质量的三把尺recall、precision、hit rate聊检索就离不开评估指标。我见过太多人调了半天向量阈值但说不清楚目标是什么。RAG里的检索评估至少要看这三把尺子。第一把是recall(召回率)针对一个测试问题检索出的结果里真正相关的有多少。在RAG场景里召回率的意义是有没有把该找的找回来。第二把是precision(精确率)检索出的结果里有多少是真正相关的。它衡量的是有没有把不该找的也召回来了。第三把是hit rate用我自己的话说就是答案材料是否在前K个结果里——给一个测试题相关文档片段是否出现在检索结果Top-N中命中率越高说明检索链路越可靠。实际做法上我会准备一个50条左右的人工标注集问题、相关文档片段、是否命中。拿它跑一轮看看hit rate是多少再逐条看没命中的问题为什么没检索到。这一步对调优的帮助远超玄学式加维度。3.3 检索白合与重排序把命中率再往上顶即使混合检索已经做了Top-K结果里也常有相关但不对位的情况系统检回了正确文档但正确的那一段在不该出现的位置。这时候**重排序(Re-ranking)**就派上用场了。重排序的原理很好理解第一轮用轻量向量检索快速找100个候选块然后交给一个精度更高的排序模型对候选块按与用户问题的相关性重新打分取前3~5个作为最终结果。重排序模型往往本身就是一个精排模型它比向量距离更能捕捉细粒度相关性代价是速度慢所以只能用在第一轮的少量候选项上不能全库跑。这一招通常能让命中率涨十来个点是我项目里的常备组件。还有一个细节是关于Top-K和阈值的配合。初学者常犯的错是到处调相似度阈值想把低相关度结果全过滤掉。但阈值设得越高漏召回的风险越大而重排序已经能处理前面的一批低质量候选。我的习惯是第一轮宽松一点Top-K开大比如50~100阈值基本不设重排序后只保留得分靠谱的前3~5个。这样召回率不掉精度又不差。4. 管道第三站生成让模型把资料用起来检索做得再漂亮最后一步生成没接住用户感受到的还是智障回答。生成环节的任务不是生成而是在正确材料上生成并且要看起来有理有据。4.1 检索结果如何塞进Prompt把检索到的文档块直接糊进Prompt是最粗糙的用法。模型看一堆没有结构的文本很容易找不到重点或者开始在无关信息上自由发挥。我在实践中会把检索结果做两件事。第一是排版。给每个文档块编号用分隔线和说明文字隔开告诉模型以下是参考资料回答时优先参考它们的内容。模型对清晰结构的信息利用效率远远高于乱糟糟的一段文字这个观察在多轮长文本里尤其明显。第二是控制数量和信息量。通常我给最终生成阶段3到5个块每个块在200到500 token之间加在一起控制在模型能一口气读完的范围。塞得太多模型注意力分散哪个都读不仔细最后生成的答案反而更空。Prompt模板上也有一点小讲究。指令部分和材料部分要分开开头说清楚角色和任务中间给资料结尾再重复一遍请只基于上述资料回答并标注引用来源。这样三层结构模型更不容易跑偏。有一个坑我踩过检索回来的块未必都是相关的偶尔会有错配的噪声块。如果你不告诉模型资料可能包含无关内容别瞎用它会把噪声块也当依据编进去。正确的写法是加一句如果资料中没有答案直接说明不知道能显著降低幻觉。4.2 Agent场景的检索多轮交互下的动态需求RAG在单独问答里是一问问一答但在Agent场景里就不是这么简单了因为它要服务于多轮对话和任务分解。多轮对话里的第一个问题是query改写。用户说它怎么退这个它如果不结合上文检索系统根本不知道搜什么。解决方法是把历史对话和当前问题一起交给模型让模型把当前问题改写成一个能独立检索的完整查询语句再去检索。这一步看着多花钱和时间但对多轮命中率帮助巨大。第二个问题是意图与实体信息的使用。用户问上次那个订单怎么操作如果只是改写成那个订单怎么操作检索还是抓瞎。要让Agent在改写时把对话里提到的具体实体订单号、产品名、日期提取出来拼进查询语句里检索才有意义。这本质上已经很接近Agentic RAG的思路了——检索不再是被动执行一次而是Agent主动决策可能检索多轮、多来源再动态决定下一步。4.3 引用溯源与幻觉控制RAG一个很大的优势就是可溯源检索到的知识块自带来源模型回答时如果能带上引用用户就能自己核实错误回答也能被快速抓住。我在系统设计里强制要求流式输出时附带上引用的块ID然后在前端展示成链接。这看起来是个体验细节实际上是一个质量校验机制——一个回答如果引用的内容和它说的话对不上问题当场暴露比用户事后吐槽强得多。幻觉是RAG避不开的话题。就算检索对了模型也可能在生成时自由发挥几句怎么管我的经验是三层防护第一层在指令层面就跟它说清只基于资料回答第二层在检索结果结构上做干净去掉无用字段只留可能有用的信息第三层在最终生成后加一个简单的验证环节——让模型自己评估一下你刚才的回答里哪句话在资料里找不到依据这招叫自洽性校验不用额外模型实测能拦住不少幻觉。5. 实操从本地文件到RAG管道的搭建记录说了这么多原理不落地等于白说。下面我按一套最小可用的方案大概写下从本地文件到能问出答案的完整搭建过程。这里我会以一个技术选型示例为主重点讲解每一步在做的事而不是追求某个框架的API熟练度。5.1 环境与数据准备我一贯的路线是Python LangChain作为编排层嵌入模型用开源的BGE系列向量库用轻量的Chroma起步生成模型用OpenAI兼容接口的任意大模型。这套组合的好处是全开源可替换重点是让你理解管道逻辑而不是被某个商用工具绑架。准备数据时我建议先找你最熟悉的业务文档别一上来拿几百份PDF练手。拿一份操作手册或者政策文档转成Markdown人工确认内容没乱、结构完整——这保证了后续问题都出在管道本身而不全在数据质量上。做第一轮调试最怕变量太多。5.2 端到端跑通的最小代码示例起步代码大概长这样我用伪代码加注释的方式写方便你看逻辑不纠结具体API# 1. 加载文档 document load_markdown_file(handbook.md) # 解析后得到纯文本块列表保留章节元数据 # 2. 切分按标题结构递归切分 chunks recursive_splitter.split(document) # 每块约512 token块与块之间重叠80 token # 3. 向量化 embeddings BGEEmbedding(model_namebge-base-zh-v1.5) vectors embeddings.encode(chunks) # 4. 存进向量库 vector_store Chroma(collection_namehandbook) for chunk, vector in zip(chunks, vectors): vector_store.add(vector, metadata{source: chunk.page_id}) # 5. 检索 query 退货需要哪些手续 q_vector embeddings.encode(query) candidates vector_store.search(q_vector, top_k50) # 6. 重排序 reranked re_rank(query, candidates) final_blocks reranked[:4] # 7. 组装 Prompt 并调用 LLM prompt assemble_prompt(query, final_blocks) answer llm.chat(prompt)这套流程跑通以后你就有一个可以问问题的RAG雏形了。但我要泼一盆冷水demo跑通只是万里长征第一步接下来才是考验。别急着加复杂功能先做一件事——准备20个你真实业务里会遇到的问题挨个问一遍看答案错在哪。5.3 实测效果与调参记录我自己测试时遇到过一个很典型的案例。第一版系统把政策文件按固定长度500字符切块问十五天内退货怎么操作系统的前三个检索结果里有两个来自产品介绍页答案自然一派胡言。当时怀疑嵌入模型选得不对换了好几个模型还是老样子。后来逐条查才明白问题出在源头政策原文里有很长一段总则内容跟退货操作相关的句子夹在总则和细则中间被切碎了。改成按标题结构切分后同一问题一下子就能命中细则那一整段答案瞬间就正常了。这个故事我想强调的只有一点很多检索问题根源在切分而不在模型。调参过程我也记录了一组数据供你参考切分粒度从500字符调到800字符后hit rate反而掉了五个点——因为窗口太大针对性信息被稀释了。反过来当重叠从0调到80整体命中率又回升了一些。这说明每个参数都要用你的真实数据测别照搬任何人的配置。6. 从RAG到Agentic RAG管道会往哪里走把基础RAG跑通之后你大概率会开始琢磨一个事这个管道现在只会查一次答一次能不能让Agent自己去决定怎么查、查几轮、要不要结合多个知识库这条路就是现在热门的Agentic RAG。6.1 静态管道与动态编排的差异基础RAG的流程是固定死的检索、生成结束。Agent化之后模型开始有主导权它可以把检索当成一个工具来调用甚至可以决定这个问题先查政策再根据政策内容去查对应产品的库存一次任务里调两次检索检索之间还有依赖关系。编排能力来自哪里来自我们把检索封装成工具并且给大模型一个清晰的工具使用协议。模型收到用户问题后不是直接去命中某个固定流程而是自己规划需要什么知识就调什么工具拿回结果再做下一轮推理。这就是从管道到Agent的关键转变知识获取从预定的流程变成了模型主动决策的行动。这种转变的价值在于复杂问题能拆解着查了。比如我们仓库还有多少能退货的库存单次检索抓不到完整答案但Agent可以先查退货政策再查库存记录再把两轮结果合并起来回答。这已经不是传统RAG能做好的事。6.2 Agent如何主动使用知识管道把RAG升级成Agentic RAG有几件具体的事可以做。第一个是让Agent自己生成检索计划。第二个是给Agent配上多路知识工具——比如一个工具查内部政策一个工具查FAQ一个工具查产品参数Agent根据问题选择调用哪个。第三个是让Agent判断检索结果够不够不够就继续查够了才给出最终回答。这个方向我也还在持续摸索中目前比较实用的经验是别一上来就把全部流程交给Agent自由发挥。可以先显式定义两三种检索模式让Agent在这几套模式下做选择稳定后再逐步放权。完全自由的编排在真实业务里经常因为一次错误决策导致整个任务失控。关于技能编排、系统提示词和自定义工具的细节我打算放到下一篇文章展开。这一篇先把知识获取管道的地基打好——毕竟无论Agent规划得多聪明它最终要做出高质量回答看的还是知识管道能不能把对的资料送到它手上。就我个人经验而言这恰恰是决定AI应用成败的基石。
返回列表