ARTICLE DETAIL

资讯详情

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

AI Agent知识获取管道:RAG检索增强生成从切分到重排的实战指南

AI Agent知识获取管道:RAG检索增强生成从切分到重排的实战指南 1. 为什么知识获取管道是 AI Agent 落地的第一道生死线做 AI Agent 的人十有八九会把注意力先放在Agent 怎么规划任务怎么调用工具怎么多轮对话上但真正把项目推到生产环境之后你会发现一个很扎心的事实Agent 的智能上限往往不是被模型能力卡住的而是被它拿到的知识卡住的。模型再强如果检索回来的上下文是错的、过时的、残缺的它输出的东西就是一本正经地胡说八道。这就是为什么我把知识获取管道放在整个 Agent 体系里优先级最高的位置——它是 Agent 的眼睛和耳朵眼睛瞎了脑子再好也没用。这一篇是走进 AI Agent系列的第四篇前面我们聊了 Agent 的基本架构、工具调用、记忆机制现在正式进入 RAGRetrieval-Augmented Generation检索增强生成这个绕不开的核心话题。我尽量不写成教科书而是把我自己在搭知识管道时踩过的坑、做过的取舍、以及那些文档里不会写的经验原原本本讲清楚。不管你是刚接触 RAG 的新手还是已经用 LangChain、Spring AI、LangChain4j 搭过 demo 的老手这篇都能帮你把知识获取管道这件事从能跑推进到能扛。先说清楚 RAG 到底解决什么问题。大模型的知识有两个硬伤一是时效性训练数据有截止日期昨天刚发的文档它不知道二是私域性你公司内部的 ERP 数据、产品手册、客服话术模型训练时根本没见过。RAG 的思路很朴素——既然模型不知道那就在它回答问题之前先把相关资料检索出来塞进上下文让它开卷考试。听起来简单但检索什么怎么检索检索多少怎么塞这四个问题每一个都能让项目翻车。我见过太多团队RAG 的 demo 半天就跑通了然后兴冲冲上线结果用户一问稍微绕一点的问题就答非所问。问题几乎都出在知识获取管道上文档切分切碎了语义、嵌入模型选错了语言、检索只做了向量召回漏掉了关键词、召回的内容没做重排直接喂给模型。这些环节环环相扣任何一环掉链子最终体验都会崩。所以这一篇我会把管道拆成文档处理—嵌入表示—检索召回—重排增强四段逐段讲透。提示RAG 不是向量数据库 大模型这么简单。把它理解成一条流水线每个工位的良品率都会影响最终产出而流水线的瓶颈往往在最不起眼的那一环。2. 文档处理切分策略决定了检索质量的天花板2.1 为什么切分是 RAG 里最容易被低估的环节很多人拿到 RAG 项目第一反应是去挑向量数据库、去比嵌入模型却把文档切分当成一个随便切切就行的预处理步骤。我的经验恰恰相反切分策略决定了检索质量的天花板后面所有环节再优化也突破不了这个天花板。原因很简单检索的最小单位是块chunk如果一块内容本身语义不完整那无论你的嵌入模型多强、重排多精细召回来的都是一堆残缺信息。举个我实际遇到的例子。有个做产品检索的项目文档是产品说明书最初用固定长度 500 字符切分结果产品 A 的保修期是 3 年这句话被从中间切断前半句在上一块后半句在下一块。用户问产品 A 保修多久检索召回了前半句产品 A 的保修期是模型只能瞎猜。后来改成按语义段落切分问题立刻消失。这就是切分的威力——它不改变模型能力但直接决定了模型能不能拿到完整信息。切分策略大致分三档我按适用场景排一下切分策略适用场景优点缺点固定长度切分结构松散的纯文本、日志实现简单、块大小可控容易切断语义递归字符切分通用文档、Markdown兼顾结构与长度需要调分隔符优先级语义/结构切分说明书、合同、代码语义完整度高实现复杂、依赖解析我个人的默认选择是递归字符切分配合合理的分隔符优先级段落 换行 句号 逗号再叠加一个重叠窗口overlap。重叠窗口这个参数特别关键它让相邻块之间有一段共享内容避免关键信息正好落在边界上被割裂。我一般设 overlap 为块大小的 10%~20%比如块 500 字符overlap 设 50~100 字符。2.2 元数据让检索从能搜到进化到搜得准光有文本块还不够每个块都必须带上元数据这是很多人忽略的一步。元数据包括来源文档、章节标题、页码、更新时间、文档类型等等。为什么重要因为检索时你可以用元数据做过滤。比如用户问2025 年最新的报销政策你可以先用元数据过滤出更新时间在 2025 年的文档再在里面做语义检索命中率会高一大截。我在一个企业知识库项目里就吃过亏。最初所有文档混在一起检索用户问研发部的考勤规则结果召回了行政部的考勤规则因为两段文本语义太像了。后来给每个块打上部门标签检索时先按部门过滤准确率直接从 60% 多提到 90% 以上。元数据不是锦上添花它是结构化过滤的抓手尤其在文档量大、领域交叉的场景下没有元数据的 RAG 基本没法用。元数据的设计我建议至少包含这几项source来源文件、section所属章节、updated_at更新时间、doc_type文档类型、tags业务标签。这些字段在入库时就要一起写进向量库检索时作为 filter 条件传入。别等到出问题了才回头补那时候重新处理全量文档的成本高得吓人。2.3 文档解析的坑PDF、表格、扫描件怎么处理真实项目里的文档格式五花八门PDF、Word、Excel、PPT、网页、扫描件都有。PDF 是重灾区尤其是那种双栏排版、带表格、带公式的 PDF直接抽取文本经常乱序。我处理 PDF 一般分两步先用解析库抽取文本和版面信息再根据版面信息重建阅读顺序。如果 PDF 是扫描件还得先做 OCROCR 的准确率又直接影响后续所有环节。表格的处理更麻烦。表格里的信息是二维的直接转成文本会丢失行列关系。我的做法是把表格转成 Markdown 或 HTML 格式保留结构或者把每一行转成列名: 值的键值对形式。比如一张产品价格表转成产品: A, 价格: 100, 库存: 50这样的文本块检索和生成都会更准确。这个转换过程看起来笨但实测效果比直接塞原始表格好太多。注意文档解析的质量是隐形的它不会报错但会悄悄拉低整个管道的效果。上线前一定要抽样人工检查解析结果尤其是表格和特殊排版。3. 嵌入表示稠密与稀疏不是二选一而是组合拳3.1 稠密嵌入和稀疏嵌入到底差在哪嵌入Embedding是把文本转成向量的过程向量之间的距离代表语义相似度。这里有个关键分叉稠密嵌入Dense Embedding和稀疏嵌入Sparse Embedding两者原理和适用场景完全不同很多人只知道稠密结果在关键词敏感的场景下翻车。稠密嵌入用神经网络把文本压成一个几百到几千维的稠密向量每一维都有值代表某种抽象语义特征。它的强项是语义匹配——用户问怎么退款文档里写如何申请退货字面不一样但语义相近稠密嵌入能匹配上。缺点是它对精确关键词不敏感比如产品型号XZ-2000这种稠密嵌入可能把它和XZ-3000混为一谈。稀疏嵌入典型代表是 BM25、SPLADE 这类则是高维稀疏向量大部分维度是 0只有出现过的词对应的维度有值。它的强项是关键词精确匹配用户搜XZ-2000它就能精准命中包含这个词的文档。缺点是不懂语义退款和退货在它眼里是两个无关的词。我把两者的差异整理成表方便对照维度稠密嵌入稀疏嵌入向量形态低维稠密如 768/1024 维高维稀疏词表维度匹配方式语义相似关键词精确强项同义改写、模糊提问专有名词、型号、代码弱项精确关键词、罕见词语义泛化典型代表BGE、E5、text-embeddingBM25、SPLADE3.2 混合检索为什么我几乎不再用单一向量检索看完上面的对比你就明白了稠密和稀疏是互补的不是替代关系。我现在的默认方案是混合检索Hybrid Search同时跑稠密和稀疏两路召回再用融合算法比如 RRFReciprocal Rank Fusion把两路结果合并排序。这样既能抓住语义又能保住关键词实测召回率比单路高出一大截。RRF 的融合逻辑很优雅它不关心两路分数的绝对值只看排名。公式大致是每个文档的最终得分 各路排名倒数的加权和。这样即使稠密和稀疏的分数尺度完全不同也能公平融合。我一般给两路各 0.5 的权重如果业务偏关键词比如代码检索、型号检索就把稀疏那路权重调高。混合检索的代价是计算量翻倍因为要跑两套索引。但在大多数场景下这个代价完全值得。我做过一个对比测试同一个知识库纯稠密检索的 Top-5 命中率是 72%混合检索能到 89%。这 17 个百分点的差距直接决定了用户觉得你的 Agent聪明还是智障。3.3 嵌入模型选型中文场景别照搬英文榜单嵌入模型的选择上我踩过最大的坑就是照搬英文榜单。MTEB 榜单上排名靠前的模型很多是英文优化的直接拿来处理中文效果可能还不如一个中等规模的中文专用模型。中文场景我一般优先考虑 BGE 系列的中文版、以及一些国产的中文嵌入模型它们在中文语义上的表现明显更稳。选型时还要看向量维度和推理成本的平衡。维度越高表达能力越强但存储和检索成本也越高。768 维和 1024 维在实际效果上差距不大但存储成本差 30% 多。我的建议是先用 768 维起步如果效果不够再往上加。另外要注意最大输入长度很多嵌入模型只支持 512 token超过就被截断所以块大小要配合模型长度来定别切出超过模型上限的块。还有一个容易被忽略的点嵌入模型和查询必须用同一个。有人入库用模型 A查询用模型 B结果向量空间对不上检索全是噪声。这个错误听起来低级但我在真实项目里见过不止一次尤其是多人协作时一个人换了模型没同步整个库就废了。4. 检索召回从能搜到到搜得准的最后一公里4.1 Top-K 不是越大越好召回和噪声要平衡检索阶段最直观的参数是 Top-K也就是召回多少个块。新手容易犯的错是把 K 设得很大觉得多召回一些总没错。但召回越多噪声越多喂给模型的上下文里混进无关内容反而会干扰生成。我见过有人把 K 设成 20结果模型被一堆无关信息带偏回答质量还不如 K3。我的经验是Top-K 先设 5~10再配合重排做二次筛选。第一路召回可以稍微宽一点比如 20保证不漏然后用重排模型精排取前 3~5 个真正相关的喂给模型。这样既保证了召回率又控制了噪声。K 的具体值要看文档粒度和问题类型事实型问题 K 可以小一点综述型问题 K 可以大一点。4.2 重排RAG 效果提升性价比最高的一步如果只能选一个优化点我会毫不犹豫选重排Rerank。重排模型Cross-Encoder 架构会把查询 候选块拼在一起打分比单纯的向量相似度精细得多。它的原理是让查询和文档在模型内部做充分的交叉注意力捕捉细粒度的相关性代价是计算慢不能对全库做只能对召回的小候选集做。实测下来加一层重排Top-3 的准确率能提升 15~25 个百分点这是所有优化手段里性价比最高的。重排模型我一般选 BGE-Reranker 系列中文场景表现稳定。流程就是混合检索召回 20 个候选重排模型打分取前 3~5 个。这套组合拳打下来检索质量基本能到生产可用的水平。提示重排模型和嵌入模型是两回事别搞混。嵌入模型负责粗筛重排模型负责精排两者配合才能发挥最大价值。4.3 查询改写用户的问题往往不是好的检索词用户提问和文档表述之间经常有语义鸿沟。用户问我买的手机坏了咋办文档里写的是售后维修流程直接拿用户原话去检索效果往往不好。这时候需要查询改写Query Rewriting把用户的口语化问题转成更适合检索的形式。查询改写有几种做法一是用大模型把问题改写成多个检索式Multi-Query并行检索后合并二是做 HyDEHypothetical Document Embeddings先让模型生成一个假想答案再用这个答案去检索因为答案和文档的表述风格更接近三是做查询扩展补充同义词和相关词。我常用的是 Multi-Query让模型生成 3 个不同角度的检索式召回率提升很明显。查询改写不是万能的它会引入额外的模型调用增加延迟。我的建议是对复杂问题开启对简单问题关闭或者用一个轻量分类器判断问题类型再决定。别为了追求效果把所有查询都改写一遍延迟上去了用户体验反而差。5. 把管道串起来一个可复现的 RAG 基础实现5.1 整体流程与关键参数前面讲了四段现在把它们串成一条完整管道。整体流程是文档解析 → 切分 → 嵌入 → 入库 → 查询改写 → 混合检索 → 重排 → 上下文组装 → 生成。每一段都有对应的参数我把我的默认配置列出来你可以直接抄作业再按需调整。环节关键参数我的默认值调整方向切分chunk_size / overlap500 / 80文档结构化程度高可调大嵌入模型 / 维度中文 BGE / 768效果不够升 1024检索Top-K召回20文档量大可调大重排Top-N精排5事实型问题可调小融合RRF 权重稠密 0.5 / 稀疏 0.5关键词场景调高稀疏这套配置我在多个项目里验证过属于开箱能用的基线。真正上线前一定要用真实业务问题做评测别用自己编的测试集因为自己编的问题往往和文档表述太接近测不出真实效果。5.2 一个最小可跑的检索代码骨架下面这段是检索部分的核心逻辑用伪代码风格写方便你迁移到 LangChain、Spring AI 或 LangChain4j 里。重点看流程不纠结具体 API。def retrieve(query, top_k20, top_n5): # 1. 查询改写可选 queries rewrite_query(query) if is_complex(query) else [query] # 2. 混合检索稠密 稀疏 dense_hits dense_index.search(embed(query), top_k) sparse_hits sparse_index.search(query, top_k) # 3. RRF 融合 fused rrf_fusion([dense_hits, sparse_hits], weights[0.5, 0.5]) # 4. 重排精排 reranked rerank_model.rank(query, fused[:top_k]) # 5. 返回 Top-N return reranked[:top_n]这段代码里每一步都有讲究。查询改写那步用is_complex判断避免简单问题也走改写增加延迟RRF 融合那步的权重是可调的重排那步的top_k是候选集大小top_n是最终返回数。这几个参数我建议做成配置项方便不同业务线调优。5.3 上下文组装别把召回的块直接拼起来召回的块怎么塞进 prompt也是有讲究的。别简单地把块按顺序拼起来那样模型很难分清哪块是重点。我的做法是给每个块加上来源标注和序号比如[来源1: 产品手册 P12] 内容...让模型知道信息出处。同时控制总长度别超过模型的上下文窗口超了就按相关性截断。还有一个技巧是把最相关的块放在最前面和最后面。有研究表明模型对上下文首尾的信息更敏感迷失在中间现象所以把重排后最相关的块放两端能提升利用效率。这个细节很小但在长上下文场景下效果明显。6. 那些文档不会写的 RAG 实战心得6.1 评测集比模型更重要我见过太多团队花大力气调模型、换框架却从来没建过一个像样的评测集。没有评测所有优化都是盲调。我的做法是项目一开始就攒一个 50~100 条的真实问题集每条标注正确答案和应该召回的文档块。每次改动管道都跑一遍评测看命中率和准确率的变化。这个习惯让我避免了很多感觉变好了其实变差了的误判。评测集要覆盖不同类型的问题事实型、对比型、综述型、否定型。尤其别漏了否定型问题比如哪些产品不支持退货这类问题最容易暴露检索的短板。评测指标我主要看两个检索的 RecallK 和生成的答案准确率。前者衡量管道后者衡量端到端。6.2 知识割裂是 RAG 的隐形杀手热词里有个词叫解决了知识割裂这戳中了很多 RAG 项目的痛点。知识割裂指的是相关信息散落在多个块里单个块都不完整检索时只召回其中一块导致答案片面。比如一个产品的参数分散在三个章节用户问这个产品的完整规格只召回一块就答不全。解决知识割裂有几种思路一是父子块Parent-Child检索用小块保证精度返回时带上父块保证完整性二是图结构GraphRAG把实体和关系建成图检索时沿着关系扩展三是块间关联入库时记录块之间的引用关系检索时一并召回。我常用父子块方案实现简单效果明显。GraphRAG 效果更好但成本高适合知识关系复杂的场景。6.3 别忽视检索不到的情况很多 RAG 系统有个通病无论检索到什么都硬塞给模型生成。结果用户问一个知识库里根本没有的问题模型拿着无关内容硬编输出一堆幻觉。正确的做法是加一个相关性阈值如果重排后的最高分低于阈值就明确告诉用户知识库中没有相关信息而不是硬答。这个阈值怎么定我的做法是拿一批知识库外问题跑一遍看它们的重排分数分布取一个能过滤掉大部分外问题、又不误伤内问题的值。这个阈值不是固定的换嵌入模型或重排模型都要重新校准。加了这个机制之后用户对系统的信任度明显提升因为不知道就说不知道比一本正经胡说强太多。6.4 增量更新与版本管理知识库不是一次建好就完事的文档会更新、会新增、会作废。增量更新的能力必须在设计阶段就考虑进去。我的做法是给每个文档一个唯一 ID 和版本号更新时先删旧版本再插新版本保证不重复不遗漏。同时记录更新时间检索时可以按时间过滤避免召回作废的旧文档。版本管理还有个坑是嵌入模型升级。如果换了嵌入模型全库向量都得重新生成否则新旧向量空间不一致。这个操作成本很高所以嵌入模型选型要慎重别频繁换。如果非要换做好灰度方案别一次性全量切换。7. 从基础 RAG 到 Agentic RAG 的演进方向基础 RAG 跑通之后你会发现它有几个天然局限检索是一次性的不会根据中间结果调整不会判断这个问题需不需要检索不会多轮检索逐步逼近答案。这些局限催生了Agentic RAG——把 RAG 从一条固定流水线变成 Agent 可以自主调度的工具。Agentic RAG 的核心变化是Agent 自己决定要不要检索、检索什么、检索几次、要不要基于结果再检索。比如用户问一个复杂问题Agent 先检索一次发现信息不够自动改写查询再检索直到信息足够才生成答案。这种检索—反思—再检索的循环能显著提升复杂问题的回答质量。实现 Agentic RAG 的关键是把检索封装成一个工具让 Agent 通过工具调用来使用。同时要给 Agent 一个判断信息是否足够的能力这通常靠一个反思 prompt 或者一个专门的评估模型。我实测下来Agentic RAG 在复杂问题上的表现明显优于基础 RAG但延迟和成本也更高适合对质量要求高、对延迟不敏感的场景。从基础 RAG 到 Agentic RAG不是推倒重来而是在基础管道之上加一层调度逻辑。所以基础管道一定要打扎实切分、嵌入、检索、重排每一环都做到位Agentic 那层才有发挥空间。基础不牢上面盖得越高越容易塌。我个人在实际项目里的体会是RAG 这件事没有银弹所有的效果都是一环一环抠出来的。别指望换个框架、换个模型就能质变真正拉开差距的是对每个环节的理解和调优。先把这条基础管道跑通、跑稳、跑准再去考虑 GraphRAG、Agentic RAG 这些进阶玩法路会走得踏实很多。
返回列表