
1. 这套课程想解决什么问题先说个真实场景。我在过去一年里前后参与了几个RAG项目从最初几个人用的小工具到后来面向真实用户的生产服务踩过不少坑。最典型的一个现象是demo做出来人人都说好一上生产就翻车。翻车方式还五花八门——问A答B、引用了完全无关的文档、知识跟新数据对不上、响应慢到用户直接关页面。后来我逐渐明白一个道理RAG的demo和生产之间隔着一条巨大的鸿沟。demo只需要让检索→生成这条链路能跑通而生产需要回答另外一串问题检索质量如何量化、跨文档冲突怎么办、多跳问题怎么处理、延迟和成本怎么平衡、线上的失败如何追踪。这些问题在教程里很少被系统讲清楚因为它们不像装一个库然后调用那样能给出标准答案。这个项目production-agentic-rag-course的核心目标就是把这条鸿沟填平。它不是又一个三步搭建RAG知识库的入门教程。它聚焦在两个词上production生产级和agentic智能体化。前者意味着所有方案都要能被度量、被监控、被灰度、被回滚后者意味着RAG不再只是检索一次、拼进Prompt一次的机械流程而是让系统具备路由、拆解问题、多次检索、自我验证的能力。我整理这篇内容时刻意把它写成了踩坑复盘实战拆解的形式而不是从零开始的教程。适合的读者是已经跑通过基础RAG demo、正在或即将把它推向生产环境的人以及那些觉得检索质量上不去、换模型也没用的团队。它解决的痛点是你知道RAG的原理是什么但不知道生产环节里每一步该怎么选、怎么测、怎么演进。2. Demo到生产绝大多数RAG项目翻车在这个过渡带2.1 Demo能跑和生产稳定是两套逻辑我会在开头就强调一个可能反直觉的判断一个跑通的RAG demo对你的生产系统几乎没有参考价值。Demo环境的数据量级通常是几十篇文档查询样本是精心挑过的几条你甚至可能无意中记住了哪几条query会命中哪几段内容。但生产环境的数据是持续增加的用户的query是完全不可预测的文档格式五花八门同一份信息在多个地方出现且互相矛盾。Demo验证的是这条路能走通而生产验证的是这条路在所有情况下都能走通且可维护。举一个具体的例子。很多人搭建RAG的第一件事是把PDF、Word直接丢给解析器抽出一大段纯文本然后切块、embedding、灌进向量库。这个流程在10篇文档时完全没问题因为即便检索结果不理想上下文窗口也能把足够多的块拼进去。但文档数量到几百篇、上千篇之后向量检索的噪声开始主导结果你会发现top-5的chunk里可能只有1个是真正相关的另外4个跟query字面上沾边但语义上毫无关系。此时整个系统的性能上限其实已经被定死了——不是模型不够好是检索这一层就已经在喂垃圾给模型了。2.2 生产环境特有的高频翻车现场根据我观察到的真实案例RAG上生产后最常见的几类事故有知识库更新后回答不更新。文档删除了、修改了但向量库里的旧向量还在系统依然会检索到过期内容。跨文档信息冲突。A文档说某个接口超时时间是3秒B文档说是5秒模型可能把两个都引进来生成一个自相矛盾的答案。检索结果东拼西凑。top-k个chunk来自完全不同的主题模型强行把它们捏成一个逻辑通顺的答案表面看起来流畅实际是一本正经地胡说八道。查询意图太复杂。用户问的是需要三步推理才能回答的问题比如今年Q2我们哪个渠道的退款率最高对比Q1是上升还是下降单轮检索根本无法覆盖所需信息。延迟与成本失控。为了把所有可能相关的上下文都塞进去把chunk数量调高导致每次请求的Prompt体积巨大既慢又贵。这些问题在demo阶段几乎不会暴露因为demo的评估方式是看起来对不对而生产的评估方式是统计意义上有多准、多稳、多快。这就引出了一个核心观点RAG项目想上生产评估体系必须前置而且要跟主架构同步建设。提示如果你正准备把一个RAG项目推向生产第一条建议不是急着调模型、调embedding而是先把失败的case收集机制建起来。没有失败样本后面所有优化都是盲目的。2.3 为什么切碎→embedding→检索这条捷径最危险我必须直说把文档简单切块然后暴力检索是搭建RAG最危险的捷径。说它危险不是因为这条路完全走不通而是因为它用最小的前期工作量换来了最大的后期维护成本。很多人选chunk size的方式是这样的看别的项目用512自己就也用512或者干脆用256、128都试一遍凭感觉看哪个回答更顺。这种做法的本质问题在于分块本身不是一个独立参数它跟你的文档结构、query形态、检索策略、模型上下文长度绑定在一起。没有一套固定的最佳参数只有针对你的数据形态调出来的相对合理参数。举个例子。某类技术文档是围绕API接口编写的每个接口的说明通常在1000~2000字左右内部包含参数表、错误码、示例代码。这种情况下如果你的chunk size是512一个完整的接口说明会被切成两三块而且每一块的边界很可能落在参数表和示例代码之间——检索时你拿到的常常是缺失了上下文的半个接口文档。模型回答的时候就会漏掉一部分参数说明甚至把示例代码和参数表对应错。另一个常见误区是只做稠密向量检索。向量检索擅长的是语义匹配但面对精确匹配场景——比如查一个订单号、一个版本号、一个配置项名称——向量检索的表现反而不如传统的关键词检索。这也是为什么我们后面会专门聊混合检索Hybrid Search稀疏检索BM25和稠密检索是互补关系不是替代关系。生产级RAG默认应该两者都有并用Reranker把两路结果合并排序。3. 检索质量的地基工程解析、分块、嵌入、召回3.1 文档解析被严重低估的第一环很多RAG教程默认你手里的文档已经是干净的纯文本了。但现实是你的输入可能是扫描版PDF、带复杂表格的Excel、有页眉页脚和目录的Word、PPT里只有少量文字的幻灯片。每一个格式都有自己独特的坑。PDF是最典型的。市面上流行的解析库有些基于规则的抽取有些基于版面分析模型。规则式抽取在简单的纯文字页面上效果不错但一旦遇到多栏排版、表格、图片内文字就全线崩溃。版面分析则相对好一些但仍需要人工校验。我的经验是解析环节一定要给自己留出抽查的空间——不是盲信某个库的输出而是定期抽取一部分文档看解析结果尤其是表格和复杂版面。这里必须多说一句关于RAG知识库能存储图片吗的热门疑问。答案是如果你走的是多模态路线把图片直接送给多模态模型理解那可以存但多数RAG系统走的还是文本路线图片里的文字信息必须在解析环节被抽出来OCR否则它对你的检索系统来说就是不存在的。很多团队一开始没意识到这一点等到上线后被用户问为什么文档里的截图内容查不到才补OCR这属于早期规划能避免的返工。关于数据格式还有个我很想强调的点不要把PDF当作知识库的唯一来源格式。如果你的团队能控制上游应该尽量让文档以结构化程度更高的格式归档Markdown、HTML、Docx并且维护每个文档的元数据作者、版本、更新时间、所属产品线。这些元数据在后面的过滤、权限控制、时效性判断里会派上大用场。3.2 分块策略从拍脑袋到按语义边界回到分块这个话题。我建议团队在建RAG的第一天就建立一个分块实验记录表而不是拍一个参数然后用到底。记录表至少包含以下几列参数项示例值说明分块策略固定长度 / 递归字符 / 语义分块按字符数硬切还是优先切在段落、标题层级上chunk_size256 / 512 / 1024单个块的目标大小overlap0 / 32 / 64 / 128相邻块之间的重叠字符数补偿切分边界信息丢失是否保留标题层级是 / 否把markdown标题作为元信息随块存储分块原则有三条一是尽量让每一块是语义完整的二是确保块内包含足够多的锚点信息标题、关键词、实体名三是块大小与后续模型对上下文的利用能力相匹配——块太小则检索粒度细但上下文碎片化严重块太大则检索精度下降且容易把无关内容带进来。实操中递归字符分块Recursive Character Text Splitter是性价比最高的起步方案。它通过分隔符优先级从段落到句号再到逗号逐步切分能保证块尽量落在语义边界上。而语义分块Semantic Chunking是更进阶的做法利用嵌入向量相似度变化来判断语义断层效果更好但计算成本更高。建议路径是先用递归字符分块跑通全链路在评估集上记录基线分数再引入语义分块对比结果用数据决定是否升级。还有一个细节经常被忽略分块时要保存父子关系。比如一个chunk属于某个chapterchapter属于某个document。检索时可以先通过小节级别找到最相关的候选再向上回溯到父级获取完整上下文也可以在重排阶段用父级内容做更精准的过滤。这种父子块检索Parent-Child Chunking在生产级系统里几乎是个标配了。3.3 嵌入模型选择小模型省成本但别省在刀刃上嵌入模型的选择直接决定了检索质量的天花板。当前可选项很多开源的有BGE系列、E5系列、GTE系列、Jina Embeddings等商业的有OpenAI的text-embedding-3系列、Cohere的embed系列。选择时我关注的几个维度中文还是多语言。如果你的知识库和query以中文为主务必用中文效果好的模型。很多英文强模型在中文上的配对距离表现并不理想。向量维度与检索成本。维度越高单条记忆存储和检索的计算成本越高但并非维度越高效果越好要看评测数据。是否支持长文本。有些模型对单条文本长度限制在512 token内有些支持到8000。如果你的分块策略倾向于大chunk就要匹配支持长输入的嵌入模型。领域适配度。通用模型在通用语料上好用但在垂直领域法律、医疗、代码偏差会显著显现。有条件的话要用自己的领域数据做一个小规模评测集对比几个候选模型的检索命中率而不是只看公开榜单。另外嵌入模型的升级也是很多团队踩过的坑嵌入模型一旦换了之前灌进向量库的所有向量都要重新生成。所以在选型阶段要慎重一旦定了尽量避免频繁更换。有的团队会把重新全量embedding作为一个版本型操作来管理——可以升级但要连同评估集回归一起做别偷偷换了没发现检索质量下降。3.4 向量库选型与混合检索、重排的配合向量数据库的选型也是个热门争论。当前主流选择大概分两类一类是独立向量库服务Milvus、Weaviate、Qdrant、Pinecone一类是传统数据库的向量检索扩展pgvector、Elasticsearch的kNN、Redis、ClickHouse。我的判断标准其实很简单你的数据是否已有强关系型诉求。如果知识库里的文档具有复杂权限体系、需要按多个字段频繁过滤、需要与业务表做关联查询优先考虑pgvector这类跟现有数据库融为一体的方案运维成本低一大截。数据规模是否真的需要独立集群。千万级向量以下pgvector配合恰当的索引通常够用到了千万级以上或者对召回延迟有极高要求的场景才有必要引入独立向量库。团队是否养得起额外的基础设施。每个中间件背后都是运维负担多一个组件就多一份告警、多一份存储成本。混合检索Hybrid Search的落地形式也有两种向量库原生支持如Elasticsearch同时做BM25和kNN、或者单独维护一个倒排索引与向量库并行。我倾向于在这个环节做一次真实的对比实验用同样的评估集分别测纯向量、纯BM25、混合检索的Recallk你会发现它们在大多数场景下是明显互补的。有了两路召回之后重排Rerank就很有必要了。重排的本质是对候选结果做更精细的二阶段打分它从第一批粗召回可能有几十条里选出真正有用的top几条。生产级实现里重排模型必须轻量、低延迟否则它是整条链路里新的瓶颈。在我测试过的方案中用一个几十MB级别的交叉编码器模型做重排在1千~1万条候选池上跑延迟通常在几十毫秒这个成本是完全可以接受的。注意重排器和嵌入模型不要选用同一个模型。嵌入模型负责把文本映射到向量空间重排器负责做query与文档的精细相关性打分两者任务不同、结构不同。有些团队图省事共用模型结果就是重排退化成了向量相似度的再排序没有任何额外增益。4. Agentic RAG为什么检索一次注定不够用4.1 单体RAG的天花板在哪里传统的单体RAG流程可以概括成retrieve-and-read拿到用户query做embedding去向量库找top-k把这些chunk拼进Prompt交给LLM生成答案。这套流程在query足够简单、知识库内容单一的前提下是有效的但它的天花板也很明显。天花板之一是单轮查询无法覆盖多跳信息需求。用户问新版本支持了哪些之前不支持的功能你需要先知道新版本是什么时候发布的再筛选出该时段内的变更记录再定位到具体功能点——这是两个步骤的检索单次retrieve无法完成。天花板之二是全局性问题容易被局部chunk误导。向量检索返回的是局部相似度最高的若干个片段它天然不擅长回答需要跨多个文档汇总、对比、统计的问题。比如这个事故在过去一年出现了几次——答案可能散布在不同时间的记录里单轮top-k根本拿不全。天花板之三是缺乏验证机制。单次检索完成后系统就直接生成答案了没有人检查检索到的内容是否真的与问题相关、是否自相矛盾、是否基于最新版本。也就是说错误一旦发生就一路随流到最终答案里。你们可能注意到一个现象在这个项目讨论的热搜词里rag瓶颈这个词出现频率很高。它背后其实是大量实践者的共同困惑——我在上一段落描述的天花板正是他们感知到的瓶颈。4.2 Agentic RAG的三种核心能力Agentic RAG的出现本质上是想打破单体RAG一锤子买卖的局限。它把一次检索变成了一场能决策、可多步、可自我纠正的工作流。这里的核心能力有三个路由Routing。把所有query都往向量库里丢是一个典型的看着简单但很蠢的设计。Agentic RAG首先要做的决策是这个问题是否需要检索应该检索哪种数据源如果用户只是问你好你能做什么你不需要检索任何文档直接走通用对话即可。如果用户问的是数字精确匹配类的查询可以走结构化数据源而不用向量库。如果用户的问题是跨知识图谱关系的可能还要走图查询。路由决定了让哪个工具来处理这是整个工作流的起点。拆解Query Decomposition。把复杂问题拆成多个子问题分别检索最后汇总。这一能力直接命中前面说的多跳信息需求。例如对比A方案和B方案在灵活性和成本上的优劣拆解后需要三次检索一次找A方案的描述、一次找B方案的描述、一次找关于成本对比的段落。拆解策略有两种实现一步到位让模型生成多个子query或多步循环让模型每轮根据已有信息决定下一步查什么。反思与验证Reflection Verification。在生成最终答案之前Agent先检查自己的中间产出检索到的chunk是否真的回答了子问题是否存在矛盾是否需要补充检索如果当前信息不足或冲突Agent应该触发新一轮检索而不是硬着头皮作答。这个机制能显著降低一本正经胡说八道率这是生产级系统最无法容忍的错误之一。4.3 路由、工具调用与多智能体协作落地Agentic RAG时有一个必须想清楚的决策点是用代码写死工作流还是让模型自己编排工具调用。代码写死工作流的典型模式是if-else判断query类型每种类型走固定的检索API。优点是可控、易追踪、故障影响面小缺点是灵活性低遇到未覆盖的query类型就只能走fallback。模型自编排工作流则是让LLM自己决定调用哪个工具、调用几次、何时结束。用业内常用术语说这是Function Calling工具调用或Agent Loop。优点是能应对开放性任务缺点是可观测性差、容易进入无限循环、token成本高。我的建议是生产环境的Agentic RAG应该走混合编排路线——把确定性的流程固定子任务、固定的数据源用代码写死把开放性的决策如何处理边界case、是否补充检索交给模型判断。具体到实现上路由环节常由模型intent识别来驱动但每一种intent对应的后续步骤要有一个明确的执行模板。这样既获得了灵活度又保住了可控性。多智能体协作是这个方向更激进的形态不同Agent分别负责摘要、检索、图数据库查询、代码执行由一个Orchestrator协调。但从当前工程实践看除非团队有很强的Agent编排能力否则多Agent的复杂度通常超过收益。我更推荐大多数团队先做单Agent多工具也就是一个调度模型加上一组工具函数这个架构已经能覆盖绝大多数生产需求。这里顺带回应一个高频问题搜kg知识库、rag知识库和结构知识库区分的人很多。Agentic RAG的价值之一就是它在路由层解决这个区分问题了——你可以同时挂一个向量知识库、一个结构化SQL/图数据库让路由根据query性质自动决定走哪个而不是只堆一个向量库幻想用它解决所有问题。这也是production-agentic-rag项目标题里最核心的架构思想。5. 评估先行没有度量体系的RAG生产项目等于盲飞5.1 RAG评估指标忠实性、相关性、上下文精确率如果只能从这篇文章里带走一件事我希望是RAG系统的优化必须跑在可复现的评估集上。没有评估指标的生产RAG每次改动都是在赌运气。目前实践中最通用的评估框架是RAGAS它定义了三个核心维度忠实性Faithfulness生成答案中的每个事实性论断是否都能从给定的上下文中找到依据。它衡量的是模型有没有胡编。答案相关性Answer Relevance生成答案是否切题是否回答了用户真正问的东西。上下文精确率/相关率Context Precision/Relevance检索回来的chunk中有多大比例是对答案真正有用的或者反过来说检索是不是把噪声也带进来了。这三个维度恰好对应了RAG链路中三个环节的质量检索得好不好上下文、综合得好不好忠实性、回答得好不好相关。在评估Agentic RAG时还有两个额外维度很关键工具调用正确率路由决策是否正确、工具参数是否合理和任务完成率是否成功走完所有步骤并得出答案。5.2 评估集建设30条优质case比200条劣质case更值钱评估集的质量比数量重要得多。我在项目实操里的流程是这样的第一从真实用户日志里捞query。生产环境上线后把用户真实query沉淀下来定期抽样进评估集。这是评估集的基站因为只有真实query才能暴露真实问题。第二人工标注参考答案和关键依据。每条query需要标注标准答案或至少答案要点、对应的知识来源文档、复杂query还需要标注需要的检索步骤。初期这个标注工作会占用不少时间但它的回报是后续每一次系统改动都能被量化验证。第三分层覆盖。评估集不能全是简单问题要刻意加入多跳问题、跨文档冲突问题、无答案问题知识库里根本不存在答案、模糊问题等边界case。这些边界case决定了你的系统上线后能防住多少高难翻车。我经常看到团队用200条自动从文档里生成的问题做评估集认为量大就代表全面。实际上自动生成的很多是同义改写看似有200条其实只覆盖了少数几个简单模式对多跳、冲突、无答案这类关键能力的验证几乎为零。评估集在精不在多条件允许的话核心case保持在100~150条、定期迭代就已经能支撑一个不错的生产基线了。5.3 人工评测与自动化评测的协同策略全自动评估存在一个现实的坑LLM-as-Judge本身也有误差。用GPT-4o给系统打分时它可能偏好更长的答案、更华丽的措辞而你的真实用户可能只想要一个精确的数值。所以我的策略是自动化人工抽检双轨并行。自动化评测跑在每一次代码变更上作为回归测试的门禁。比如新改了一个分块策略跑一遍评估集如果忠实性和上下文精确率下降超过一个阈值这次变更就不能合入。人工抽检则聚焦在自动化难以判断的维度上答案的可读性、专业性、是否冒犯用户、是否符合业务口径。建议每周从线上真实回答里抽2~3%做人工打分积累一段时间后把值得注意的类型归纳成规则回流到自动化评估集里。另外对Agentic工作流一定要记录推理轨迹trajectory——每轮工具调用、中间返回、最终答案。因为Agent的失败不像单体RAG那样一眼能看出是哪一步检索出错了你得靠轨迹判断是路由错了、子query拆错了、还是反思循环没触发。实操命令参考非特定环境评估流水线一般会跑在CI里比如用Python脚本对每条评估case依次调用推理API然后将结果与标注答案交给Judge模型打分最终输出一个包含忠实性、相关性等指标的报告。嫌麻烦的团队可以先从脚本化手动跑评估做起但一定要保证每次变更都有一份可对比的报告。6. 生产工程化延迟、成本、可观测性一手抓6.1 延迟预算拆解别让Agentic变成慢半拍Agentic RAG的生产化以瓶颈大多不是效果问题而是延迟和成本问题。一个典型的工作流如果路由1次、检索2次、LLM调用若干次总延迟很容易从单次RAG的1~2秒飙升到5秒以上。用户不会为更聪明的架构额外等你3秒。延迟治理要先做预算拆解。设定一个总目标假设p95在3秒内然后分环节估算意图识别100ms、路由200ms、两次检索共300ms、重排50ms、LLM生成1200ms、再校验400ms加在一起还在预算内如果有Agent循环每多一轮就要多预留1秒。拆完之后你会发现真正能砍的主要是并行化独立子任务两个子query可以并行检索、缓存命中见后文、以及压缩不必要的Agent循环次数。**Cycle Budget轮次预算**是一个很值得认真做的参数限制Agent最多只能执行N轮工具调用达到上限后必须基于已有信息作答。这个机制既防死循环也防成本失控。我见过不对循环做限制的项目一次回答产生40多次工具调用账单和用户等待时间双双爆炸。6.2 缓存、限流与故障兜底生产系统和高并发API打交道的常规手段在RAG上同样适用但有一些RAG特有的细节。语义缓存是其中最有价值的。LLM领域的缓存通常有两层一是请求级别缓存用户问了完全相同的问题直接返回上一次答案二是语义缓存即问题相似时复用。语义缓存的实现方法是对query做embedding后跟缓存库里的历史query做相似度比较相似度超过阈值比如0.92就直接复用缓存答案。这能在高并发时期打掉一大半重复请求。注意缓存key要包含知识库版本号知识库升级后缓存必须失效否则就出现了旧知识新答的坑。限流的核心不是限制用户而是保护下游依赖。Agentic RAG内部会多次调用大模型API一次用户请求可能对应3~5次LLM调用如果发生流量尖峰下游API很容易被限流甚至触发失败。所以要站在一次用户请求消耗多少下游配额的维度做预算而不是按用户数粗算。故障兜底建议做三级第一级LLM调用异常时自动重试注意区分超时和限流限流要指数退避第二级某一路检索源挂了降级到另一路比如向量库故障时降级到BM25第三级全链路异常时返回兜底话术并记录trace而不是让用户面对一条报错。生产系统里可以答不上来但不能崩得难看。6.3 可观测性给每次回答配一张体检单RAG系统有一个特性让排查特别困难同一个问题在不同时间、不同上下文条件下答案可能不同。这意味着你无法用今天badcase明天能不能复现的方式在线下排查。唯一的出路是线上全链路trace。我的做法是给每一次用户请求生成一个request_id并把链路里所有关键信息串进去用户query的原始文本路由决策结果及置信度各数据源检索出的chunk列表含来源文档ID、chunk内容、相似度分数重排后的结果及分数Agent每一轮工具调用的输入输出LLM生成用的最终Prompt内容及其长度各环节耗时与token消耗最终答案及评测维度的自动打分有了这份体检单当用户投诉回答不对时你可以像病理分析一样回溯整条链路是检索没找到对的还是找到了但被重排压下去了还是路由走错了数据源又或是LLM用了错误chunk。没有trace的RAG系统等于在黑暗里修机器。日志方面我建议把检索chunk的内容完整落库至少是top-5的来源ID和内容片段这些数据既能用于badcase分析也能定期回流到评估集——把线上失败的case自动入库作为下一轮评估集的候选样本。6.4 成本估算与知识库更新的版本管理Agentic RAG的成本比单体RAG高一个量级这一点在做预算时要有所准备。单体RAG一次查询通常是1次embedding 1次LLM调用Agentic下一次查询可能变成1次embedding、1次意图识别、3个子查询、1次重排、2次LLM生成、1次校验总LLM调用次数翻了几倍。成本因此不是线性上升而是倍数上升。成本控制方向上有几个杠杆缓存命中率见上文、小模型做路由和大模型做生成的分层、精简chunk数量不要为了多而多、对Agent循环的轮次上限做严格约束、重排模型选轻量的开源的小型交叉编码器完全够用。知识库更新同样是个版本管理问题。生产系统的知识库不应该随时往向量库里塞新文档而应该是通过版本化发布流程来升级。具体做法是每个文档版本对应一个版本号向量库记录每个chunk的版本信息升级时批量更新受影响向量并同步使语义缓存失效。更极端的团队会为每个知识库版本分配一个独立的索引别名切换时做原子切换这样出现线上严重badcase时可以快速回滚到上一版本。我在实践中的体会知识库版本的发布流程越像代码发布流程有环境隔离、有回滚、有审计生产事故就越少。知识变了但索引没变、索引变了但缓存没清这两类问题占了知识库更新事故的八成。7. 架构演进路线把单体RAG升级为Agentic RAG7.1 先别推翻重来单体RAG跑通后再加智能很多团队看到Agentic RAG的火热就想着把现有架构推翻重来。我的建议非常明确不要一开始就上Agent。第一步应该是把单体RAG打磨干净解析、分块、检索、重排、评估把整个链路的基础质量和指标基线建好。这一步如果没做好直接上Agent只会得到更聪明地传递垃圾——Agent可以多路检索但如果每一路检索都是噪声多路只是噪声乘以N次方。一个可以用来自查的朴素基线是先确保不加Agent的情况下简单query的正确率已经达到你满意或者至少可接受的水平。如果连简单的都做不好复杂问题的坏结果不是Agent能救回来的。7.2 第二步引入路由与查询改写有了稳定基线后的第一层智能不是上完整的Agent Loop而是加两个相对可控的能力query改写和路由选择。Query改写解决的是一个最常见的问题用户的query通常是口语化、指代不清的。那个新功能还有bug吗——这里的那个指代什么需要结合上下文它应该支持并发吧——它是什么改写层就是要利用对话历史把query补成自包含的完整表述再做检索。我可以负责任地说这一层带来的检索质量提升往往比换一个更强的embedding模型还要明显。路由选择则是在要不要检索、走哪个库这个维度上做决策。它可以是基于规则加模型的混合模式比如检测到query里包含订单号、版本号等模式就直连结构化数据源检测到需要汇总对比的历史数据就走图查询或SQL检测到普通语义相似性问题才走向量库。7.3 第三步编排Agent Loop并约束行为当路由和改写稳定后再引入真正的Agent Loop。这一步的关键是把多步推理做成一个受约束的工作流而不是无边际的自由发挥。我在落地时的具体做法可以用一个抑制不住的比喻Agent是个聪明但容易多动的实习生你必须给他一张写满了最多借几步、用完必须回来报告的工单而不是只给他一间资料室钥匙。具体约束包括工具清单固定且有限不是让模型幻想出任意工具而是给它一个白名单里的几个函数query_documents、query_sql、query_graph、search_web。每个工具的参数有明确说明这样模型不会胡编参数。循环轮次上限根据业务场景设3~5轮超出自动触发fallback策略。每轮工具输出都要做校验输出是否为空、是否包含有效信息校验失败则以本次结果作答并记录原因。定义终结条件信息足够生成答案时Agent必须把已获取的上下文汇总给生成模型而不是继续探索。7.4 搭建环境落地与技术栈参考关于怎么在Mac上搭建RAG知识库这个在近期热搜里高频出现的问题其实在学习和开发阶段一台Mac完全够用。本地跑起来一套最小可用的RAG链路的典型组合是ollama或LiteLLM跑本地模型至少满足开发调试需求、Chroma或Qdrant以容器方式跑本地向量库、LangChain或LlamaIndex做编排再加一个FastAPI包装成服务。这套开发环境的好处是CI和迭代都在本地闭环不需要一上来就为基础设施付费。但要注意本地跑通了模型不等于生产环境选型已验证——生产环境的并发、数据规模、延迟预算和本地是有本质差异的开发环境的价值是快速验证思路而不是替代生产验证。这里也补充一下对怎么在Mac上搭建RAG知识库搜得比较多的一种合理预期多数人问这个问题其实不是想学向量数据库的容器配置而是想快一点把文档灌进去、能聊天、能搜索这条链路跑通。如果你也是这个目标我建议先别折腾一堆中间件从一条最简链路开始解析→分块→本地embedding→Chroma存储→本地模型生成一次性跑通后再按本文前面几章的原则逐步替换组件。生产化过程中的组件替换绝不应该是不加约束的原则是一次只换一个变量并用评估集验证差异。7.5 一次完整的多步推理示例理论落地为代码说了这么多没有代码示例总觉得不够踏实。我给出一个简化版的多步Agent RAG核心逻辑便于理解整体结构。伪代码里省略了具体API细节重点展示路由、拆解、验证这一套控制流的骨架class QueryAgent: def __init__(self, retriever, sql_tool, graph_tool, llm, max_steps4): self.retriever retriever # 向量检索工具 self.sql_tool sql_tool # 结构化查询工具 self.graph_tool graph_tool # 图查询工具可选 self.llm llm # 生成/决策/反思模型 self.max_steps max_steps def route(self, query: str) - str: # 意图识别 路由返回 vector / sql / graph / chat prompt f判断以下问题最适合使用哪类数据源 - vector: 需要语义检索非结构化文档 - sql: 需要精确数值、统计、订单级查询 - graph: 需要多跳实体关系推理 - chat: 闲聊或无需知识库即可回答 问题{query} 只返回一个词。 return self.llm.complete(prompt).strip() def decompose(self, query: str) - list[str]: # 将复杂问题拆解为多个可独立检索的子问题 prompt f将复杂问题拆解为最多3个独立子问题每个子问题应能通过一次检索回答。 问题{query} 以JSON数组返回如 [子问题1, 子问题2]。 raw self.llm.complete(prompt) return json.loads(raw) def verify(self, query: str, contexts: list[str]) - bool: # 判断现有上下文是否足够回答原问题不足则触发下一轮检索 joined \n---\n.join(contexts[-3:]) # 只取最近若干段上下文 prompt f根据已提供的上下文能否回答用户问题如果信息不足或存在矛盾回复 INSUFFICIENT否则回复 SUFFICIENT。 问题{query} 上下文 {joined} return self.llm.complete(prompt).strip() SUFFICIENT def run(self, query: str) - str: source self.route(query) if source chat: return self.llm.complete(query) contexts [] # 第一步路由检索 if source vector: contexts.extend(self.retriever.retrieve(query, top_k5)) elif source sql: contexts.append(self.sql_tool.query(query)) else: contexts.extend(self.graph_tool.query(query)) # 第二步验证信息充分性不足则拆解并补充检索 for step in range(self.max_steps): if self.verify(query, contexts): break sub_queries self.decompose(query) for sub_q in sub_queries: contexts.extend(self.retriever.retrieve(sub_q, top_k3)) else: # 达到轮次上限记录告警并基于已有信息作答 print(REACHED_MAX_STEPS, query) final_prompt f基于以下上下文回答问题。如果上下文不包含答案请直接说明。 问题{query} 上下文 {chr(10).join(contexts)} return self.llm.complete(final_prompt)坦率地说这段代码离生产还有段距离——缺少缓存、trace、嵌入层封装、评估钩子等。但它的价值在于展示Agentic RAG与传统RAG最本质的差别答案不是一次性检索生成的而是经过路由决策→检索→验证→补检索→总结的多步骤循环。把这个循环控制好你的RAG系统才真正有了智能体的质感否则只是换了几个API的壳。8. 维护与迭代生产级RAG是活的系统生产级RAG系统上线只是一个开始。知识库在变、用户query分布也在变系统必须有个持续迭代的机制。我强烈建议每个RAG项目都配置一个每周节奏的badcase复盘点。从线上trace里挑出5~10个典型失败case人工分析失败原因归纳成类别是检索问题该查到的没查到、还是分块问题信息被切碎了、还是生成问题模型综合错了、还是Agent决策问题路由走错、循环触发错误。积累几个星期后你会发现失败模式的分布非常清晰优化优先级也自然浮现。还有一个容易被忽略的点版本间的回归测试要做在prompt和配置的每一层。生产级RAG的改动太容易被觉得应该更好影响比如有人把温度从0调到了0.3前后对比感觉回答更自然了就直接上了线。但没有跑评估集你并不知道忠实性是不是下降了。任何一次参数调整、prompt改动、模型变更都必须放在已固化的评估集上跑回归这个原则我反复强调也不嫌烦。讲到这我猜有团队会问那评估集是我们的标注人员落后了怎么办其实评价集的维护本身也是一个迭代流程每周把线上坏case筛一批、人工标注后并入评估集淘汰掉一些已经被模型背下来的旧case。这样评估集本身就在跟随真实用户需求进化。9. 一些我踩过之后的实话说给你听写到最后聊聊我在多个生产RAG项目里反复验证过的几个朴素结论。第一大部分RAG项目最大的瓶颈不是模型是检索质量。很多团队遇到badcase的第一反应是换更大的模型、调Prompt、加few-shot但真正的问题往往出在解析阶段丢了结构化信息、或者分块切碎了关键上下文。先把检索质量做到可量化、可信任再谈模型怎么用。第二Agentic RAG值得做但必须带着约束做。不加约束的Agent会让你的延迟、成本、失败率全面失控。生产级的Agent一定是自由决策上边界清晰、工具清单固定、循环轮次有限、全过程trace的风格。它不酷但稳定。第三评估体系要先于优化落地。在我参与的项目里凡是先建评估集再优化改动的基本都能在几轮迭代内看到量化提升凡是先改参数再凭感觉判断的大概率原地打转。评估集是团队沟通质量的共同语言这个投入绝对不能省。第四知识库的版本管理比想象中重要。它的重要性仅次于检索质量。把知识库更新当成发布系统来做每一次更新都有版本号、有回滚预案很多生产事故能提前规避。第五在Mac上把RAG跑通不算什么把评估集跑起来才算真正的第一步。本地demo的价值在于验证链路但下一步就必须进入数据评估迭代的循环。如果你正在做一个RAG项目且正卡在demo能跑、生产不稳的过渡段我的建议是先不要急着追求Agentic的时髦把检索质量和评估体系扎扎实实做好然后带着约束逐步引入路由、多步推理和反思验证。这条路径没有捷径但每一步都能用数据确认你在往前走。