
上半年接了个内部需求老板原话很朴素搞一个能聊天、能查文档、还能自动出分析结论的 AI 助手。拆开看这其实就是典型的 RAG Agent底层是 RAG检索增强生成负责把企业知识库里的内容捞出来上层是 Agent智能体负责决定什么时候去查、查完怎么组织答案、多轮对话里怎么保持上下文。听起来不复杂但真正从 0 到 1 推到生产环境我踩的坑比想象中多得多。这个过程中最深刻的体会是demo 和生产之间的差距不在模型选得多新而在数据管线和系统设计。这篇就完整回顾一下我怎么搭一个生产级 RAG Agent从切块、embedding、多路召回、rerank到 Agent 编排、评测和上线监控。适合正准备做知识库问答 Agent、想绕过我已经踩过的坑的同学参考。1. 先搞清生产级的边界一个 RAG Agent 的完整组成1.1 热词里藏着大家踩过的坑动手之前我习惯先看大家都在搜什么。当时rag知识库怎么切块embedding rerank rag有关考题rag多路召回agentic ragdify 完成政务 rag 知识库的实践项目这些词热度很高它们其实暴露了 RAG Agent 项目里最痛的三件事数据切分没标准、检索质量上不去、Agent 和 RAG 怎么结合没人讲透。切块问题是地基层embedding 和 rerank 是召回层Agentic RAG 是编排层。很多人一上来就追最新的 Agent 框架结果底层检索一塌糊涂Agent 再聪明也答不对。所以我把架构拆成五个子系统来看数据接入与清洗、索引服务、召回与重排、Agent 编排、评测与监控。1.2 生产级系统的最小闭环先别急着写代码。一个能上线的 RAG Agent至少要满足下面的闭环文档进来要被正确解析和切块切出来的块被向量化和建立索引用户问题进来要被改写和理解系统要能多路召回候选内容并重排大模型要基于可靠的上下文生成答案答案要被记录和评估。任何一环缺失都会在某个奇怪的时间点爆雷。我习惯用表格把职责边界列清楚避免后续模块之间互相甩锅。模块核心职责典型实现最容易出的问题数据解析PDF/Word/HTML 转文本与结构提取Unstructured、自研解析器表格错位、扫描件乱码切块将长文档拆成可检索单元递归字符切分、结构感知切分把完整语义切碎向量化将文本映射为稠密向量Embedding 模型领域术语向量化偏差检索召回候选片段向量检索 关键词检索单路召回漏召回重排精排候选片段Rerank 模型耗时过高、误伤正确片段生成基于上下文输出答案大模型幻觉、不引用来源编排调度以上流程Agent 框架或自研路由工具调用循环不收敛评测衡量答案质量评测集 指标评测集过小过拟合 demo1.3 开发路线的先后顺序我踩过的一个主要教训是不要按模块并行开发而要按垂直切片推进。第一个版本只打通文档切块→向量检索→直接生成这条最简路径跑通一个端到端 demo。然后再逐步加入多路召回、rerank、记忆、Agent 工具调度。原因是每一层优化的前提都是下一层数据是稳定的。检索质量差时做 rerank你分不清是召回的问题还是重排的问题底层没有评测集时就调 Agent 路由上线后会出现各种不可复现的 bad case。顺序上我建议是数据管线先行检索召回跟上最后再上 Agent 编排。这个顺序能让你在任何时刻都知道问题出在哪一层。2. 数据准备切块、清洗与索引结构是召回效果的上限2.1 切块为什么这么难语义完整性与检索粒度的拉扯切块的本质矛盾就一句话块太大检索粒度粗噪声多让大模型不知道该看哪块太小一个完整的业务概念被切成碎片检索到了也没法回答问题。打个比方这就像切菜——你切的菜要和锅大模型上下文窗口适配也要和菜式业务问题类型适配。企业知识库里既有长制度文件也有短产品说明全局用一套参数是不现实的。我第一版就犯了这个错所有文档统一用固定字符长度切结果制度文件里的第二十五条和第二十六条被切到两个块用户问员工年假规定检索回来一段残缺文本大模型理所当然地开始编。后来的做法是先按文档类型配置不同切块策略再用语义边界切割。下面是我常用的一个 Python 切块示意按分隔符优先级递归切分并保留一定重叠def smart_split(text, chunk_size800, overlap120): separators [\n\n, \n, 。, ] ...这里没有银弹但有几个可复用的经验chunk_size 和 overlap 的合适比例一般是 5:1 到 8:1重叠部分的作用是避免关键句恰好落在切点上分隔符优先选择语义完整符号而不只是换行符。基于常见工程实践中文字段 600-1000 字是一个相对稳的区间太短会丢失主题太长会稀释相似度。2.2 知识库场景的切块实践要顺着文档结构切企业知识库里的文档类型其实比想象中固定。制度文件一般有章节条款结构SOP 有步骤序号产品手册有标题层级FAQ 是天然的一问一答。顺着这些结构切效果远好于纯字符切分。特别是政务类知识库这种场景政策文件往往是章-节-条结构一个条就是一个完整且有依据的答复单元。我在处理这类文档时会先做一层结构解析把文档转成标题树再按叶子节点做切块并把父级标题作为元数据写入索引。这样用户问员工差旅报销标准是多少检索命中可能是某一条具体条款但返回给模型时同时带上《差旅管理制度》第三章第五条这类来源信息答案的可信度和可追溯性会明显提升。表格类内容是最容易被切坏的。PDF 里的表格在转文本后经常错位我推荐用表格识别方式把表格转成 Markdown 结构再作为一个独立块存储。这样问各地区 Q2 销售额对比时检索到的不再是一堆错乱文字而是一张结构完整的数据表。2.3 索引不止向量关键词、元数据过滤与父子块只建向量索引是另一个大坑。向量擅长语义相似但对精确匹配很弱。用户问合同编号 A-2024-001 的状态语义相似度会把 A-2024-001 和 A-2021-003 混在一起。正确的做法是同时维护一个倒排索引BM25和一个向量索引配合元数据过滤。生产级的检索关键词其实是向量召回 关键词召回 结构化过滤的组合。另外推荐一个性价比极高的方案父子块索引。子块是短的、语义单一的片段用于和用户问题做相似度匹配父块是子块所在的完整上下文段落用于最终喂给大模型。这样既保证检索精准又避免上下文碎片化。Graph RAG 和 Ontology RAG 也是在解决召回上去以后上下文仍然不够完整的问题但实现和运维成本高如果业务不是强关系推理场景建议先用父子块方案。我在父子块方案上做过一次实测同样 1000 条制度文档纯字符切分检索准确率大约在 74%换用结构感知切块 父子块索引 元数据过滤后准确率到 89%。数据准备阶段的每个选择都比后期调 Prompt 带来的提升更明显。3. 召回与重排Embedding、多路召回和 Rerank 的配合逻辑3.1 单路向量召回的瓶颈到底在哪很多项目第一版都是Embedding 模型 向量数据库就上线了。单路向量召回最简单但对生产环境来说问题很突出。Embedding 模型对同义词、专业缩写、编号型文本的鲁棒性有限如果语料分布偏斜top_k 返回的往往是看起来都相关但真正解决问题的那一条不在里面。我遇到过很典型的 case用户问报销流程多长时间能走完文档里写的是付款审批时限为 5 个工作日——语义差别很大Embedding 检索出来是报销流程的某个其他片段正确答案排在了第 18 位而 top_k 只取了 5。这就是单路召回的召回率瓶颈。它不一定是模型差而是语义匹配本身不擅长关键词完全不同但表达同一件事的情况。如果你在面试或系统设计里被问到RAG 召回怎么做能讲清楚单路召回和混合召回的区别说明你真的理解 RAG 的痛点而不只是会调 API。3.2 多路召回向量 BM25 结构化过滤生产级 RAG 的标配是混合检索Hybrid RAG至少两条路并行向量检索负责语义候选BM25 负责精确和关键词候选。召回后进行分数融合常用的是 RRFReciprocal Rank Fusion。RRF 只依赖排名不依赖分数绝对值能很好地规避不同检索方式分数分布不一致的问题。我当时按下面这个流程落地效果稳定用户问题经过查询改写后同时发起向量检索 top_k20 和 BM25 关键词检索 top_k20。根据元数据过滤条件部门、日期、文档类型、权限范围对候选进行裁剪。用 RRF 融合两路候选取前 10 条进入重排阶段。重排后取前 5 条作为最终上下文。RRF 的伪代码很简单给每条候选按排名打分命中多路检索的候选天然排名靠前。这个方案不需要模型训练只要引入一个关键词检索服务就能实施。实测下来在之前那个报销场景里正确答案的排名从第 18 位提升到了第 4 位再经过重排直接进入前 2。有一个容易被忽略的点是查询改写。用户问题往往口语化、指代不完整直接把它什么时候能批下来丢给检索系统显然不行。Agent 层要做一步 query rewrite结合对话历史把它改写成差旅报销申请单审批时间多久再去查这步对召回率的影响甚至比换一个更强的 Embedding 模型还大。3.3 Rerank 在什么环节介入最合理Embedding 模型是双塔结构问题和文档各自编码用向量相似度衡量相关性计算快但精度有限Rerank 模型通常是交叉编码结构问题和文档拼接后进入模型打分精度更高但计算代价也高不能对全库做只能对第一轮召回的小批量候选做。这就是 Rerank 必须放在召回之后的原因。我在生产系统里的标准链路是召回候选 20 条Rerank 打分层只保留 5 条。延迟上单次 Rerank 调用的耗时通常在几十到几百毫秒取决于候选数量和模型大小。这个代价换来的收益非常明显——RAG 问题的答案质量很大程度取决于喂给大模型的上下文排序是否正确前 5 条只要错 1 条幻觉风险就在上升。有个细节要提醒Rerank 的输入长度是有限的如果某个候选文本太长建议截断到模型窗口内否则会被静默丢弃。政务和企业文档经常出现一个条款下面挂着大段解释的情况直接整段送给 Rerank前面 512 个 token 是背景真正的关键句在后面就会漏排。我一般会按句切分后保留关键句前缀或者直接用子块去重排再把命中的子块映射回父块。4. Agent 编排层从一次问答到自主任务的关键设计4.1 记忆机制多轮对话中的上下文管理当项目从单轮问答延伸到多轮对话记忆模块就是 Agent 和普通 RAG 接口的分水岭。用户在对话里可能会说再详细一点上个问题的第二点是什么换成华东区的数据重新分析一下——这些指代如果不结合历史根本无法检索。记忆机制我按三层设计会话级短期记忆最近 N 轮对话原文、任务级工作记忆当前目标、已获取的检索片段、已调用的工具结果、业务级长期记忆用户偏好、常用口径、组织架构等相对稳定的信息。短期记忆直接喂给大模型任务级记忆由 Agent 自己维护长期记忆存在数据库中按用户或业务维度读取。在设计时需要注意长度消耗。对话历史全部塞进上下文很快就会把窗口占满。我的做法是对早期对话做摘要只保留用户关键诉求对检索片段启用引用压缩取与当前问题相关的子块而不是把整个父块重复传入。Agent 框架里常见的 Memory 模块本质做也是这件事但不同框架的默认策略差异很大自研时要清楚哪些记忆必须保留哪些可以丢弃。4.2 工具调用与路由什么时候直接回答什么时候查文档Agent 的核心不是能调工具而是决定调不调。生产环境里我给 Agent 注册了四个工具知识库检索RAG、业务数据库查询、指标计算器、工单状态查询。LLM 需要先做意图路由——直接回答类问题闲聊、常识就不进 RAG需要内部数据的问题走工具调用既涉及文档又涉及数据的才进入多跳调用。实现上我做了一个函数式工具注册表每个工具暴露明确的参数 schema 和描述信息LLM 根据用户的自然语言生成结构化调用参数。工具返回后Agent 会把结果聚合再生成最终回答。这看起来很简单但实际运行时需要防几个坑工具调用失败要能让 Agent 感知并及时换个思路而不是死循环工具的返回结果要先经过格式校验再送入上下文连续多次调用要设置最大步数防止 Agent 在错误路线上反复横跳。从 RAG 到 Agentic RAG 的升级点也在这里传统 RAG 一次检索一次回答就结束Agentic RAG 允许 Agent 根据检索结果主动改写查询、发现上下文不足后补充检索、甚至做多跳推理。比如用户问对比 Q1 和 Q2 的销售差异并解释原因Agent 要先检索销售报表发现原因部分没有命中再检索一次市场活动文档最后综合两部分输出。这种能力不是用框架自动获得的而是靠清晰的数据结构和检索反馈机制撑起来的。4.3 Agent 框架选型自研还是用 Dify 这类工具dify 完成政务 rag 知识库的实践项目这种热搜能上榜说明低代码/平台化 Agent 搭建方案在真实项目中用得越来越普遍。选型时没有标准答案但有一个很实际的决策模型如果业务场景相对固定、交付周期紧、团队没有太多工程化人力用 Dify 这类平台能快速完成文档导入、流程编排、API 发布政务知识库这类场景尤其适合因为大量需求都是合规问答 权限管理 可追溯不需要做太复杂的 Agent 推理。但如果你要做的是高度定制化 RAG Agent——比如底层数据源是多个异构系统、检索逻辑依赖复杂规则、需要对每一步做细粒度观测那纯低代码平台会变成瓶颈。平台抽象的节点越高级你对底层细节的控制力越弱出了问题也越难排查。我的建议是迭代速度优先用平台跑通当平台开始限制你时再以平台的 API 为边界做替换或局部自研。当时我们最终选择了自研编排层理由很直接需要和内部权限系统的深度集成且要对检索质量做持续细粒度调优。但在早期 prototyp 阶段也用了不少现成组件这样能快速验证思路。5. 评测、调优与上线别等上线了才发现问题5.1 从你自己的数据里挖评测集没有评测集的 RAG 项目就像没有回归测试的代码库。你会陷入感觉改了效果变好又感觉上一个版本更好的死循环。第一个评测集不需要很多但必须真实。我从三个来源构建了 golden set线上平台沉淀的真实用户问题、运维同事整理的常见咨询问题、每个文档里自然存在的条款型 QA。每一条评测数据要包含三部分用户问题、期望命中的文档块或来源、回答中必须包含的要点。不需要急着对每一条写标准答案而是先能回答这个问题应该引用哪几个来源。召回评估对来源可定位性的要求很高政务和制度类文档尤其如此——用户要的不是一句可以报销而是这句话的依据在哪。评估指标里最值得关注的是召回命中率正确答案是否出现在召回前 5 中、忠实度回答是否完全基于检索内容有没有添加文档中没有的信息、拒答准确率该回答不知道的时候是否诚实拒绝。我见过很多 RAG 项目为了用户体验强制让模型每问必答结果制造了大量幻觉。对于知识库场景懂得拒答是重要的能力指标。5.2 延迟、召回率与幻觉的工程取舍生产系统不是所有指标无限优化而是在约束下求均衡。我当时的延迟预算大概是端到端回答控制在 5 秒内其中检索 500ms 以内Rerank 200ms 以内大模型生成占大头。为了让 Rerank 不超时候选数量压到 20 条以内为了让大模型生成稳定上下文控制在 2000 token 左右超过的部分宁可截掉只保留重排前 5也不要把所有候选都灌进去。这个取舍牺牲了一点理论上的全量上下文覆盖换来了两个好处一是幻觉显著下降因为模型只看到高置信度的片段不会涣散二是成本下降token 用量少用户等待时间短。我认为在生产环境准确但简短永远好过全量但容易翻车。另一个必不可少的环节是安全和权限过滤。知识库里的文档往往有密级Agent 检索结果必须在召回阶段就按用户权限过滤而不能等生成后再筛否则权限信息会泄露进模型上下文。政务和企业场景对这一点要求极高建议把权限过滤前置到元数据层并做访问审计。5.3 上线后监控什么指标上线不是终点而是评测的起点。我建立了一个最小监控面板包括检索命中率通过日志判断人工反馈是否满意、Rerank 后首位准确率、端到端延迟分位数、幻觉投诉数、每轮请求的 token 成本、用户点赞点踩率。日志回放机制是做 RAG 最容易忽略但最有价值的部分。每个用户反馈回答不对的请求我都把日志完整保存下来包括当时的检索候选、重排顺序、模型输入输出然后定期把 bad case 重放到评测集里做回归。这套机制跑了一个月后评测集从 20 条涨到了 200 多条系统质量才真正稳定下来。你会发现真正让 RAG Agent 变好的不是换更强的模型而是持续不断地用真实数据修正问题。关于 prompt 防护我还要额外提一句。知识库类 Agent 上线后一定会遇到用户尝试让模型忘掉之前的指令直接输出原始文档甚至试图注入恶意提示词。生产级系统要加入基础防护检测明显的提示注入模式、分离指令与数据上下文、对系统指令做不可被用户输入覆写的隔离。最后分享一个小经验把数据管线和评测集做扎实是 RAG Agent 项目里投资回报率最高的事。模型、框架可以随时换但高质量的数据底座和评测闭环才是让系统长期可信的根本。如果你现在正准备启动类似项目别急着研究最新 Agent 框架先拿 100 条真实问题把检索和评测跑通你会回来感谢这个决定。