【AI应用开发】RAG+Agent 组合架构怎么设计?什么时候先检索,什么时候先规划?
【AI应用开发】RAGAgent 组合架构怎么设计什么时候先检索什么时候先规划1. RAG Agent 的本质关系RAG 解决的是知识从哪来检索增强 Agent 解决的是事情怎么做自主决策与执行 RAG Agent 一个既知道怎么查资料、又知道怎么动手的 AI简单比喻角色能力对应图书管理员会查书、找资料RAG私人助理会思考、规划、执行Agent两者结合能查资料 能做事RAG Agent2. 四种组合架构模式模式A: Agent驱动RAG ──── RAG 是 Agent 工具箱里的一个工具 模式B: RAG驱动Agent ──── 先用检索结果决定 Agent 的规划 模式C: 并行双通道 ──── 检索和规划同时进行结果融合 模式D: 自适应路由 ──── 根据问题类型动态选择执行路径3. 模式一Agent 驱动 RAG检索为工具最常用的模式RAG 被视为 Agent 的一个 Tool用户: iPhone 15 的退货流程是什么 │ ▼ Agent 规划: Step1: search_knowledge_base(iPhone 15 退货流程) ← RAG 作为工具 Step2: 根据检索结果回答用户classAgentWithRAG:Agent 驱动 RAG —— RAG 作为工具def__init__(self,llm,vector_store):# RAG 检索工具self.rag_toolToolDefinition(namesearch_knowledge_base,description在知识库中搜索。适用产品FAQ、操作指南、政策文档等,handlerself._rag_search,parameters{...})# 其他业务工具self.tools[self.rag_tool,query_order_tool,create_ticket_tool,# ...]self.agentAgentOrchestrator(self.tools,llm)def_rag_search(self,query,top_k5):RAG 检索实现resultsself.vector_store.search(query,ktop_k)return{source:knowledge_base,results:[{content:r.content,score:r.score,metadata:r.metadata}forrinresults]}asyncdefrun(self,user_input):returnawaitself.agent.run(user_input)# 执行流程示例 用户: 订单到哪了顺便问下退货怎么操作 → Agent 自主决定: 1. query_order() 获取订单状态 2. search_knowledge_base(退货流程) 获取退货规则 3. 综合两个结果回答用户 适用场景Agent 需要同时使用多个工具RAG API 数据库且步骤间可能有依赖。4. 模式二RAG 驱动 Agent检索决定规划检索结果直接影响 Agent 的规划方向classRAGDrivenAgent:RAG 驱动 Agent —— 检索结果决定规划asyncdefrun(self,user_input):# 第一阶段先检索获取关键信息retrieval_resultawaitself._deep_retrieval(user_input)# 第二阶段基于检索结果进行规划planawaitself._plan_based_on_context(user_input,retrieval_result)# 第三阶段执行计划returnawaitself._execute_plan(plan,retrieval_result)asyncdef_deep_retrieval(self,user_input):深度检索不是简单搜一次而是多层次检索# 1. Query 改写扩展同义词、拆分子问题queriesawaitself._rewrite_queries(user_input)# 2. 多路召回all_results[]forqinqueries:resultsawaitself.vector_store.search(q,k5)all_results.extend(results)# 3. Rerank 精排rerankedawaitself._rerank(user_input,all_results)# 4. 结构化提取return{relevant_docs:reranked[:5],extracted_facts:awaitself._extract_facts(reranked,user_input),missing_info:self._identify_gaps(reranked,user_input),}asyncdef_plan_based_on_context(self,user_input,retrieval):基于检索结果制定计划plan_promptf用户问题:{user_input}知识库检索结果:{json.dumps(retrieval[extracted_facts],ensure_asciiFalse)}制定执行计划: 1. 如果检索结果已充分回答了用户问题 → 直接基于检索结果回答 2. 如果检索结果不够 → 确定还需要哪些信息选择合适工具 3. 如果需要多步操作 → 制定步骤顺序 输出 JSON 格式计划: {{ can_answer_directly: true/false, direct_answer: ..., // 如果可以直接回答 steps: [ // 否则列出步骤 {{tool: 工具名, args: {{}}, purpose: 目的}} ] }}returnawaitself.llm.chat(plan_prompt)适用场景用户问题需要深度理解背景知识才能规划时如技术排障、医疗问诊。5. 模式三并行双通道检索和规划同时进行最后融合importasyncioclassParallelAgent:并行双通道: RAG 和规划同时进行asyncdefrun(self,user_input):# 双通道并行rag_taskasyncio.create_task(self._rag_channel(user_input))plan_taskasyncio.create_task(self._agent_channel(user_input))rag_result,plan_resultawaitasyncio.gather(rag_task,plan_task)# 融合两个通道的结果returnawaitself._fusion(user_input,rag_result,plan_result)asyncdef_rag_channel(self,user_input):通道1: RAG 检索 → 初步答案docsawaitself.vector_store.search(user_input,k5)return{docs:docs,draft_answer:awaitself._generate_draft(user_input,docs)}asyncdef_agent_channel(self,user_input):通道2: Agent 规划 → 工具调用# Agent 在规划时也能调用 search_knowledge_base# 但这里的检索是另一个独立路径returnawaitself.agent.run(user_input)asyncdef_fusion(self,user_input,rag_result,plan_result):融合双通道结果fusion_promptf融合以下两个维度的信息给用户最终答案: 维度1 - 知识库检索结果:{rag_result[draft_answer]}维度2 - Agent 工具执行结果:{plan_result}融合原则: - 信息一致 → 合并给出统一答案 - 信息冲突 → 优先采用工具执行的实际数据 - 信息互补 → 整合呈现完整信息 - 标注每个信息来源知识库 / 实时数据returnawaitself.llm.chat(fusion_prompt)适用场景对响应速度要求高且检索和规划可以独立进行的场景。6. 模式四自适应路由根据问题类型动态选择处理路径classAdaptiveRouter:根据问题类型自适应路由ROUTING_RULES{simple_fact:{pattern:[什么是,定义,多少,什么时间],strategy:rag_only,# 只检索reason:简单事实查询不需要规划},procedure:{pattern:[怎么做,如何,流程,步骤],strategy:rag_then_agent,# 先检索再规划reason:需要参考文档后制定步骤},data_query:{pattern:[订单,库存,我的,状态],strategy:agent_only,# 只规划reason:需要调用API/DB不依赖知识库},complex_analysis:{pattern:[分析,对比,总结,评估],strategy:parallel,# 并行reason:需要知识背景数据分析}}defclassify(self,user_input:str)-str:对用户问题分类scores{}forcategory,ruleinself.ROUTING_RULES.items():scoresum(1forpinrule[pattern]ifpinuser_input)scores[category]score bestmax(scores,keyscores.get)returnself.ROUTING_RULES[best][strategy]ifscores[best]0elseparallelasyncdefdispatch(self,user_input:str):strategyself.classify(user_input)ifstrategyrag_only:returnawaitself.rag.answer(user_input)elifstrategyrag_then_agent:returnawaitself.rag_driven_agent.run(user_input)elifstrategyagent_only:returnawaitself.agent.run(user_input)else:returnawaitself.parallel_agent.run(user_input)7. 先检索 vs 先规划决策框架决策树: 问题类型是什么 ├── 知识型问题XXX是什么YYY怎么做 │ └── 先检索 → 检索结果够了直接答不够再规划 │ ├── 操作型问题帮我查XXX创建YYY │ └── 先规划 → 根据规划按需检索 │ ├── 混合型问题查XXX然后对比YYY最后给建议 │ └── 并行 → 检索提供知识背景Agent 规划执行 │ └── 未知类型 └── 默认并行 → 取两个通道最好的结果决策原则情况策略原因问题可能已有文档答案先检索避免 Agent 重复造轮子需要调用外部 API先规划确定需要什么数据需要知识操作结合并行最大化效率操作依赖检索结果先检索再规划检索是规划的前提8. 实战架构设计classRAGAgentSystem:生产级 RAG Agent 组合系统def__init__(self,llm,vector_store,tools):self.llmllm self.vector_storevector_store self.toolstools# 子模块self.query_rewriterQueryRewriter(llm)self.classifierIntentClassifier(llm)self.ragRAGModule(vector_store,llm)self.agentAgentOrchestrator(tools,llm)self.rerankerReranker(llm)self.routerAdaptiveRouter()# 工具集中包含 RAG 检索self.tools[search_knowledge_base]RAGSearchTool(self.rag)asyncdefprocess(self,user_input:str,session_id:str):完整处理流程# 1. 意图分类intentawaitself.classifier.classify(user_input)# 2. Query 改写总是执行提升检索质量rewrittenawaitself.query_rewriter.rewrite(user_input,session_idsession_id)# 3. 根据意图选择策略ifintent[type]simple_fact:# 简单事实 → 只检索docsawaitself.rag.search(rewritten,k5)returnawaitself._synthesize_answer(user_input,docs)elifintent[type]operation:# 操作型 → Agent 带 RAG 工具returnawaitself.agent.run(user_input,extra_context{rewritten_query:rewritten})elifintent[type]complex:# 复杂问题 → 检索 → 规划 → 执行retrievalawaitself._deep_retrieve(rewritten)ifretrieval[sufficiency]0.8:# 检索结果足够 → 直接回答returnawaitself._synthesize_answer(user_input,retrieval[docs])else:# 检索不够 → Agent 进一步处理returnawaitself.agent.run(user_input,extra_context{retrieval_context:retrieval[context],gaps:retrieval[missing]})else:# 未知类型 → 并行rag_taskasyncio.create_task(self.rag.answer(user_input,rewritten))agent_taskasyncio.create_task(self.agent.run(user_input))rag_result,agent_resultawaitasyncio.gather(rag_task,agent_task)returnawaitself._fusion(user_input,rag_result,agent_result)9. OpenAI Assistants RAG 参考实现# 结合 OpenAI Assistants API 的 RAGfromopenaiimportOpenAIclassAssistantsRAGAgent:使用 OpenAI Assistants API 构建 RAGAgentdef__init__(self,vector_store_id:str):self.clientOpenAI()self.assistantself.client.beta.assistants.create(name智能客服 Agent,modelgpt-4o,instructions 你是智能客服助手可以 1. 使用 file_search 检索知识库 2. 使用 function 工具查询订单/库存等业务数据 3. 综合分析后给出答案 ,tools[{type:file_search},# ← RAG 能力{type:function,function:{# ← Agent 工具name:query_order,description:查询订单信息,parameters:{...}}},{type:function,function:{name:query_inventory,description:查询库存,parameters:{...}}},],tool_resources{file_search:{vector_store_ids:[vector_store_id]}})asyncdefchat(self,user_message:str,thread_id:strNone):ifnotthread_id:threadself.client.beta.threads.create()thread_idthread.idself.client.beta.threads.messages.create(thread_idthread_id,roleuser,contentuser_message)runself.client.beta.threads.runs.create_and_poll(thread_idthread_id,assistant_idself.assistant.id)ifrun.statuscompleted:messagesself.client.beta.threads.messages.list(thread_idthread_id)returnmessages.data[0].content[0].text.valuereturnf处理失败:{run.status}10. 总结模式先检索/先规划适用场景延迟Agent 驱动 RAG先规划Agent 需多工具的复杂任务中RAG 驱动 Agent先检索需背景知识的操作中高并行双通道同时对速度要求高的混合问题低自适应路由动态选择通用客服系统灵活金句RAG 告诉 Agent “知道什么”Agent 决定做什么——两者不是二选一而是 112 的关系。

相关新闻

AutoDock Vina完整指南:5分钟掌握分子对接的核心技能

AutoDock Vina完整指南:5分钟掌握分子对接的核心技能

AutoDock Vina完整指南:5分钟掌握分子对接的核心技能 【免费下载链接】AutoDock-Vina AutoDock Vina 项目地址: https://gitcode.com/gh_mirrors/au/AutoDock-Vina 想要在药物发现和虚拟筛选中获得专业级能力吗?AutoDock Vina正是你需要的开源分子…

2026/10/13 19:17:14 阅读更多 →
免费远控软件怎么选?三款主流产品实测对比

免费远控软件怎么选?三款主流产品实测对比

谁是零门槛、不限速、无广告的免费远控之王?热门软件对比横测对绝大多数普通用户来说,选择远程控制软件哪个好用无延迟之前,第一个问题往往是:免费版到底能用吗?这正是远程控制电脑最佳方案必须回答的核心问题。本文以…

2026/10/13 20:09:57 阅读更多 →
Godot 4 集成 Lua 脚本引擎:实现热更新与模块化游戏逻辑

Godot 4 集成 Lua 脚本引擎:实现热更新与模块化游戏逻辑

1. 项目概述 如果你正在用 Godot 4 做项目,尤其是那种需要快速迭代、热更新,或者想让策划和美术也能参与一部分逻辑编写的游戏,那你肯定不止一次想过:要是能用 Lua 写脚本就好了。GDScript 固然优秀,但 Lua 的轻量、灵…

2026/10/13 20:09:54 阅读更多 →

最新新闻

TypeScript协议适配:将Claude Code前端无缝对接Deepseek模型

TypeScript协议适配:将Claude Code前端无缝对接Deepseek模型

1. 这不是“换壳”,而是一次精准的协议层手术“80行 TypeScript Mods,把 Claude Code 改造成 Deepseek Harness”——这个标题乍看像极了某些技术圈里常见的“魔改教程”,但实际操作中,我很快意识到:它根本不是在 UI 上…

2026/10/14 19:57:05 阅读更多 →
高效贡献开源Hermes agent:从源码阅读到PR合入的完整路线

高效贡献开源Hermes agent:从源码阅读到PR合入的完整路线

1. 为什么值得把精力花在贡献 Hermes agent 上先说一个很多人的误解:贡献开源项目不等于闷头写代码,尤其像 Hermes agent 这类项目,它是一个持续推进的工程产物,有设计取舍、有兼容负担、也有社区协作的规范。第一次接触时容易觉得…

2026/10/14 19:57:05 阅读更多 →
DOM遍历不是for循环:深度优先与广度优先的工程选型指南

DOM遍历不是for循环:深度优先与广度优先的工程选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 19:57:05 阅读更多 →
ESP32-S3开发板入门:从环境搭建到GPIO、PSRAM与USB应用全解析

ESP32-S3开发板入门:从环境搭建到GPIO、PSRAM与USB应用全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 19:57:05 阅读更多 →
FPGA现货采购避坑指南:从型号解读到验货实战

FPGA现货采购避坑指南:从型号解读到验货实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 19:57:05 阅读更多 →
手写负载均衡:从轮询到一致性哈希的算法与工程实践

手写负载均衡:从轮询到一致性哈希的算法与工程实践

手写负载均衡这件事,听起来像是业务代码写多了自娱自乐,但真把它当回事做一遍的人,对分布式流量的理解完全不一样。很多时候我们一直在用现成组件——Nginx、LVS、各种注册中心自带的负载策略——出了问题只能对着文档调参数,根本…

2026/10/14 19:56:03 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →