
简介2024年智能体Agent与检索增强生成RAG融合应用的专题PDF文档面向具备一定技术基础的研发人员与技术管理者系统展现大模型在游戏娱乐、金融科技、语音助手、办公支持等前沿领域的落地探索。资源为单个PDF文件共146页压缩包大小12.43MB目前已有544人学习浏览。内容汇集八大实际案例网易伏羲实时语音交互AI队友、蚂蚁集团泛金融多智能体应用、ModelScope开源框架加速智能体开发、小米语音助手中的复杂任务处理、RAG在办公领域解决幻觉与信息老旧问题、Elasticsearch 8落地实践、西门子通用智能助理以及阿里云PAI大语言模型微调训练。各案例既呈现多智能体协作与决策方式的深层改变也剖析了RAG在数据检索、信息整合与安全性方面的优势并附有技术实现讲解与业务背景分析。整份资料基于真实生产经验能帮助开发者快速掌握Agent与RAG结合大模型的方法论理解前沿趋势为研发与创新提供有力参考。1. AgentRAG 是什么三个要素谁能直接上手2024 年之后的 AgentRAG不再等于“一个向量库加一段提示词”。RAG 解决的是“让大模型基于自有资料回答”Agent 解决的是“让大模型按步骤完成几件事”二者组合起来才是完整形态。标题里这份 146 页的资料名义上是八个案例实际上是在反复演示同一个融合骨架路由谁来做、检索谁来做、生成谁来做、不满意之后回不回头。这篇笔记就把这四件事拆开给出一套可以跑通的最小链路、八类案例的共性参数表以及五条会翻车的真问题。适合那些已有 RAG 基础、想把手上的知识库问答升级为可编排任务的人不适合还停留在“向量检索结果直接拼进提示词”阶段的读者。2. RAG 与 Agent 的分工线为什么增强生成不负责判断2.1 单轮 RAG 的作用边界能提供证据不负责决策RAG 的完整链路是文档解析、切片、embedding、向量检索、拼装上下文、交给大模型生成。它擅长的是“给定一个明确问题从库里找出相关片段再回答”。这句话拆开看有两个隐性前提问题本身已经明确库里有现成答案的片段。一旦问题需要拆解例如“对比 A 和 B 的条款差异给出一版费用说明”单轮检索往往只拿到 A 的片段或 B 的片段生成结果就会各说各话。这不是召回质量差而是链路结构不支持多步求证。很多团队在 2024 年初踩过同一个坑觉得命中率低就换 embedding 模型换成 bge-m3加上重排命中率上去了端到端的效果还是不行。原因是 RAG 的召回目标由 Agent 层决定问题没被拆成合适的检索子问题召回再准也答不到点子上。单轮 RAG 是“一次检索、一次生成”它不负责判断该问几次、该信哪份材料、生成结果是否自相矛盾。这些判断是 Agent 的职责也是二者组合后价值最大的部分。2.2 融合的三种编排模式串行、并行与反思回环从工程结构看Agent 给 RAG 只做三件具体的事决定何时检索决定检索目标决定什么时候终止。按照这三件事的执行方式可以把融合应用分成三种编排模式。编排模式执行方式典型场景延迟与成本串行模式先改写问题再检索最后生成售后知识库问答、产品文档答疑低一轮检索即可收敛并行模式一个问题拆成多个子查询同时检索多个索引合并结果多文档综述、竞品对比中查询数翻倍权重乘在查询数上反思回环生成初步答案后把答案送回检索器做二次求证不一致则重写合同审查、投资分析、医疗建议等高风险问答高通常 2 到 4 轮循环选型时先看问题的失败成本。同样是回答错误产品使用说明答错可以接受合同条款答错不可接受。反思回环比串行模式多出的延迟通常在 3 到 8 秒之间这个代价换的是对结论的二次确认。2024 年大模型 API 的单位成本下降后回环模式才真正具备了工业可用性这也能解释为什么反思去噪成了当年融合应用的主要卖点。2.3 Agent 补上的四种控制力路由、规划、反思与工具调用Agent 层对 RAG 的四个控制点正好对应四类工程判断。第一是路由问题要不要进知识库进哪个索引第二是规划一个复杂问题要拆成几步每步各自检索什么第三是反思生成的结果是否和召回片段矛盾需不需要重试第四是工具调用检索之外是否需要查数据库、算指标、调接口。这四个控制点有一个容易被忽略的次序问题。路由一定要先于检索执行规划可以先于检索执行也可以穿插在多轮检索之间反思一定在生成之后工具调用可能发生在任意位置。不要把所有判断都交给一段大 prompt 完成——常见做法是把路由单独抽成一个 LLM 调用输出结构化字段再用代码判断后续分支而不是让大模型自己一路“想”到底。这样每个环节都可观测、可回滚、可单独换模型排查问题时能直接定位是路由错了还是检索错了。3. 最小可复现的 AgentRAG 链路路由、召回、裁决三段式3.1 链路总览与数据准备先拆任务再开代码不管最终面对的是八大案例里的哪个场景落地的第一步都是把任务拆成三个模块路由模块判断要不要检索、检索哪个索引召回模块负责真正查库并排序裁决模块负责判断生成结果是否可信。下面这段代码按这个顺序展开对应一条最小可复现链路。数据准备阶段唯一要强调的点是索引划分。不要把所有资料灌进一个索引至少按“产品文档”“政策条款”“历史工单”三个维度切分路由输出直接定位到索引名。这样一份资料出了问题不会污染全库也是后面讲八大案例时的统一前提。3.2 模块一意图路由与 query 改写路由模块用一次结构化输出完成“判断要不要检索”和“改写检索语句”两件事。这是我通常能用的最短版本from pydantic import BaseModel, Field from openai import OpenAI client OpenAI(base_urlhttp://localhost:8000/v1, api_keylocal) class RouteResult(BaseModel): need_kb: bool Field(description是否需要进入知识库检索) kb_name: str Field(description目标索引名不检索则为空串) rewrite: str Field(description改写后的检索语句保留实体和限定词) route_prompt 你是路由引擎。判断用户问题是否需要检索资料库。 不需要检索的情况寒暄、请求说明自身能力、与业务无关闲聊。 检索时需要把问题改写为适合向量检索的单句不要丢失数字、型号、时间。 def route_question(query: str) - RouteResult: resp client.beta.chat.completions.parse( modelqwen2.5-14b, messages[ {role: system, content: route_prompt}, {role: user, content: query}, ], response_formatRouteResult, ) return resp.choices[0].message.parsed逻辑说明路由用response_format强制输出结构化结果而不是让模型自由生成文本这样后续代码可以直接读取字段。rewrite是容易被省略却最影响效果的一步用户口语“那款便宜的能不能干这个”必须改写成带型号和场景的检索句否则向量召回全跑偏。参数说明模型选择上可以用参数量偏小但指令遵循强的 7B 到 14B 模型路由不需要太强的推理能力。如果路由错误率偏高把need_kb的判断条件写得更具体例如枚举哪些业务词必须走检索。不要在这里加太多 few-shot三个例子就够多了模型容易照抄模板。3.3 模块二双路召回与重排召回阶段我一般用“稠密向量 稀疏关键词”双路召回再做一次重排。单独用向量召回对专有名词不敏感单独用 BM25 又扛不住语义改写融合是更稳的做法from FlagEmbedding import FlagModel from pyserini.search.lucene import LuceneSearcher embedder FlagModel(BAAI/bge-m3, query_instruction_for_retrieval为检索) bm25 LuceneSearcher.from_prebuilt_index(company_policy_index) def dual_recall(query: str, top_k: int 8): dense_vec embedder.encode_queries([query])[0] dense_hits vector_db.search(dense_vec, top_ktop_k) bm25_hits bm25.search(query, top_ktop_k) merged {hit[doc_id]: hit for hit in dense_hits bm25_hits} return list(merged.values())[: top_k * 2]逻辑说明dense_hits负责语义相近但表述不同的片段bm25_hits负责保证型号、编号这类精确词不丢。合并时按doc_id去重同一份材料被两种方式命中只保留一次。参数说明重排不能省。双路召回返回的候选集有大量噪声直接用会污染生成质量。我会在后面接一个 cross-encoder 重排例如bge-reranker-v2-m3对候选集中 score 排序取前 3 到 5 条进上下文。这里的top_k不是越大越好超过 8 条之后上下文里噪声比例上升生成的答案反而变差。小库场景下top_k8、重排保留 3 条是不错的起点大库场景可以放宽到top_k20、重排保留 5 到 6 条。3.4 模块三裁决与输出控制召回完成生成答案之后还需要一个裁决步骤。RAG 链路里最常见的虚假繁荣是召回结果根本没有支撑信息模型仍然编了一个合理答案。裁决模块的任务就是判断生成结论能否由召回片段支撑起来def verify_and_answer(query: str, passages: list[dict]) - str: numbered \n\n.join( f[{i}] {p[text]} (来源: {p[source]}) for i, p in enumerate(passages) ) final_prompt f基于资料回答用户问题。要求 1. 每个直接结论后标注资料编号如[1][2] 2. 资料中没有依据的判断明确写出“资料未覆盖” 3. 资料之间有冲突时不要自行折中列出冲突双方及编号。 资料如下 {numbered} 用户问题{query} resp client.chat.completions.create( modelqwen2.5-30b, messages[{role: user, content: final_prompt}], temperature0.2, max_tokens800, ) answer resp.choices[0].message.content if 资料未覆盖 not in answer and _coverage_check(answer, passages) 0.5: return 资料不足无法给出可靠结论。 return answer逻辑说明_coverage_check是一个启发式校验检查答案中出现的实体有多少出现在召回片段里。低于阈值就拒绝输出而不是让模型硬答。这相当于给生成结果加了一个最后的闸门。参数说明temperature必须压低这类任务 0.2 以下比较合适。max_tokens没必要给太大答案越长越容易滑向编造。裁决失败时的回退动作也很重要可以把原始问题再送进路由模块重新生成改写语句再做一次召回而不是直接失败返回这样能兜住改写不佳的情况。4. 八大案例的拆法按交互形态分类而不是按行业分类4.1 八个案例背后的同一套骨架标题里这八个案例横向覆盖客服、风控、办公、数据分析等方向但纵向拆开它们用的其实是同一套骨架。每个案例的差异只体现在三个变量上路由要不要拆多步、检索要不要接外部工具、生成之后要不要加反思回环。把这个变量关系想清楚八个案例的逐案分析就可以压缩成一张参数表读到任何新案例也能直接套进去。4.2 从案例形态推导 AgentRAG 配置常见案例大致落在四个形态上。第一种是单轮知识问答对应售后答疑、政策查询最简单的串行模式两个模块就够不需要反思。第二种是多轮上下文问答对应在线导购、故障排查需要把对话历史里的指代对象写进 rewrite每个问题先做指代消解再路由。第三种是跨文档综合求证对应竞品分析、多合同条款对比必须做并行检索与结果汇总反思回环基本不能省。第四种是检索接计算对应经营分析、数据看板提问检索到的片段不能直接作为答案要转成 SQL 或代码片段去执行返回值再生成最终结论。案例交互形态是否拆多步是否需要工具调用是否需要反思路由要点单轮知识问答否否否直接判断索引多轮上下文问答否否可省先消解指代再路由跨文档综合求证是否必须拆子查询并行出发检索接计算是是建议判断要先查数还是先算数这四列配置就是八案例和未来新案例真正的工程量所在。交互形态判断对了后面代码基本不用大改改的只是索引名、工具函数和反射轮上限。4.3 把 RAG 抽象成服务八个案例复用一个检索层八个案例如果每个都各自写一套检索代码维护成本很快失控。更常见的做法是把检索能力抽象成独立服务Agent 层不关心索引背后是向量库还是 ES只调一个统一的检索接口。几个案例共享同一套知识库服务只在 Agent 编排层区分行为这就是 RAG as a Service 的落地位置。实践上我把这个服务设计成只暴露两个接口一个是retrieve(index_name, query, top_k)返回带 score 和 source 的片段另一个是feedback(doc_id, helpful)把用户的显式反馈写回索引的权重表。所有 Agent 都通过接口调用不直接访问数据库。这个抽象带来的直接收益是案例之间新增或下线一个知识库不影响 Agent 代码只影响一个服务配置。5. 避坑清单AgentRAG 高发的五类故障与排查路径5.1 改写吞掉实体检索命中率低答案频繁说“资料未覆盖”现象用户问题里的型号、日期、合同编号在 rewrite 之后消失向量检索找不到精确目标回答质量骤降。原因路由模块的改写太自由模型把“BGP-2024-071 号合同”简化成了“合同”。这类专有名词恰恰是知识的索引键被压缩后检索必然落空。解决改写阶段引入实体保护。把问题中匹配到的型号、编号、产品名先抽取出来改写时用占位符替换检索完成后再恢复。一个正则或者一个小的实体识别模型就能完成不要依赖大模型自觉保留。5.2 路由过度自信问题与知识库无关仍然硬编答案现象用户问“你用的什么模型”Agent 没有走“无需检索”分支反而从一个不相关的索引里召回内容生成了完全不相干的答案。原因路由模块的need_kb判断只给了一个布尔值模型倾向默认走检索路径。这与大模型的指令遵循偏差有关模型倾向于执行更复杂的路径。解决给路由加一个显式的反例段把“寒暄、闲聊、自我介绍、与业务无关”的示例写进去。更稳的做法是加一个前置校验对路由输出的kb_name做一次索引存在性校验索引里没有对应领域就强制走无需检索分支。两处一起做路由错误率能压到可接受水平。5.3 反思回环死循环二次求证永远失败接口成本翻三倍现象反思模式下生成结果与召回片段不一致系统重写后再次检查仍然不一致循环直到超时。账单先爆了。原因反思循环的退出条件只判断“是否一致”没有判断“重试了几次”和“召回片段是否变化”。如果第一次召回就不充分重试只会用同样的片段不断生成同样的结果。解决死循环必须用代码规则而不是模型自觉来终止。我在反思循环外加上三个硬限制最大迭代次数固定为 3同一轮重试时把上一轮的答案拼进检索条件让“原文支持”成为检索目标若两次迭代召回结果完全一致直接退出循环。5.4 上下文塞满导致幻觉反弹召回越多越不准确现象为提高命中率把top_k调到 30重排后保留 12 条生成长度变长答案里开始出现片段拼接带来的虚假信息。原因RAG 的生成阶段对上下文长度存在一个敏感区间。片段数量超过 8 条后模型难以同时参考所有片段更容易受中间位置噪声片段影响。解决召回数量与生成模型窗口匹配。长上下文模型也不意味着可以无限塞保底做法是把重排后的片段按与 query 的相关度排序一次只保留前 5 条并在 prompt 中明确声明“优先参考编号靠前的资料”。如果担心信息遗漏把 5 条之外的片段单独做一次摘要再把摘要附在末尾而不是全部平铺。5.5 验证阶段走错指标命中率很高答案正确率依然垫底现象本地评测显示检索命中率超过 90%上线后用户投诉率居高不下反馈“回答看着像资料结论是错的”。原因命中率只验证了“相关片段被召回”没有验证“生成结论是否基于该片段”。RAG 的生成阶段完全可能忽略资料引用模型凭自身记忆回答答案看起来正确但事实上超出资料范围。解决评测拆成两条线并行。一条线测召回看 hit rate 和 MRR另一条线测生成用“答案中每个关键结论能否在给定片段中找到出处”作为判定口径。第二条线人工成本高可以通过 LLM 作为裁判但裁判 prompt 要明确要求逐句对齐防止裁判模型同样产生幻觉。6. 验证口径与可观测性一次排查记录胜过十次猜测AgentRAG 应用上线后最难的不是调路由而是出了问题不知道在哪一环。我现在的习惯是在链路每一跳都打结构化日志日志字段固定为用户原始问题、路由结果、改写后 query、召回片段 id 与 score、重排后的顺序、生成答案、裁决结论。一条请求对应一条完整记录存进时序表问题复现时先按链路回放而不是靠抓现场。{ session_id: s-8f2a, ts: 2024-11-03T10:22:11Z, route: {need_kb: true, kb_name: contract, rewrite: BGP-2024-071 合同履行期限}, retrieval: {hits: [{doc_id: d-331, score: 0.91}, {doc_id: d-287, score: 0.83}]}, answer: 合同履行期限为 2025 年 3 月 1 日[1], verify: {passed: true, coverage: 0.86} }日常验证用三组数字就够了路由错误率、召回 hit rate、端到端答案可溯源率。路由错误率低于 5%hit rate 不低于 70%可溯源率不低于 90%这三个数同时达标再谈优化效果。如果可溯源率低先改裁决模块如果 hit rate 低先查数据切片和 embedding如果路由错误率高先补路由的示例。条理清晰比反复调模型参数有效得多。这套日志和指标的习惯也是我从那八个案例里学到的最值钱的部分希望帮到你。本文还有配套的精品资源点击获取