很多 RAG 系统失败,并不是因为 LLM 不够聪明,而是因为它们的架构太简单。它们试图用线性的一次性方式,处理一个本质上循环、多步骤的问题。
许多复杂查询需要推理、反思,以及何时行动的聪明决策,这与我们面对问题时如何检索信息非常相似。这正是 RAG 流水线中引入“agent 驱动行为”的用武之地。下面看看一个典型的深度思考 RAG 流水线长什么样……
Deep Thinking RAG Pipeline (Created by Fareed Khan)
Deep Thinking RAG Pipeline (Created by Fareed Khan)
- Plan:首先,agent 将复杂用户查询拆解成结构化的多步骤研究计划,并决定每一步使用何种工具(内部文档搜索或 web 搜索)。
- Retrieve:对每一步,执行自适应的多阶段检索漏斗,由一个 supervisor 动态选择最佳搜索策略(vector、keyword 或 hybrid)。
- Refine:使用高精度 Cross-Encoder 对初始结果进行重排,并由 distiller agent 将最佳证据压缩为简洁的上下文。
- Reflect:每一步后,agent 总结当前发现并更新研究历史,逐步构建对问题的累积理解。
- Critique:随后,一个 policy agent 检查这段历史,策略性决策是继续下一步、遇到死胡同时修订计划,还是结束。
- Synthesize:研究完成后,最终的 agent 将来自所有来源的证据综合为单一、全面且可引用的答案。
在这篇文章中,我们将实现完整的“深度思考 RAG 流水线”,并与基础 RAG 流水线做对比,展示它是如何解决复杂的 multi-hop 查询的。
所有代码与理论都在我的 GitHub 仓库:
GitHub - FareedKhan-dev/deep-thinking-rag: A Deep Thinking RAG Pipeline to Solve Complex Queries
📘 目录
- 📘 目录
- 环境配置
- 知识库来源
- 理解多源、多跳查询
- 构建一个会失败的浅层 RAG 流水线
- 定义中央智能体系统的 RAG 状态
- 战略规划与查询制定
使用工具感知规划器分解问题
使用查询重写智能体优化检索
通过元数据感知分块提升精度
- 创建多阶段检索漏斗
- 使用监督器动态选择策略
- 利用混合、关键词与语义搜索进行广泛召回
- 使用交叉编码器重排器实现高精度
- 通过上下文蒸馏进行综合
- 使用网络搜索增强知识
- 自我评估与控制流策略
- 更新并反映累积研究历史
- B构建用于控制流的策略智能体
- 定义图节点
- 定义条件边
- 连接深度思考 RAG 机器
- 编译与可视化迭代工作流
- 运行深度思考流水线
- 分析最终高质量答案
- 并排对比
- 评估框架与结果分析
- 总结整个流水线
- 使用马尔可夫决策过程(MDP)学习策略
环境配置
在开始编写 Deep RAG 流水线前,我们需要打好基础,因为一个生产级 AI 系统不仅仅是最终算法,还包括在搭建时做出的深思熟虑的选择。
我们将要实现的每个步骤,都会直接影响最终系统的有效性和可靠性。
当开始开发流水线并不断试错时,最好把配置定义为一个简单的字典。等流程复杂起来,就可以直接回到这个字典,调整配置并观察对整体性能的影响。
复制这些键大都很好理解,但有三个值得强调:
- llm_provider:我们使用的 LLM 提供方,这里用的是 OpenAI。之所以选择 OpenAI,是因为在 LangChain 中我们可以很容易地切换模型和提供方;你也可以选择适合自己的,比如 Ollama。
- reasoning_llm:在整个系统里它必须是最强的,因为要承担规划与综合。
- fast_llm:用在更简单的任务上(比如 baseline RAG),应更快更省。
接下来导入流水线会用到的库,并把 API keys 设为环境变量,避免在代码中暴露。
复制我们同时启用了 LangSmith 的 tracing。在一个 agentic 系统里,工作流复杂且循环,tracing 并非可有可无,而是很重要。它帮助你可视化内部过程,更容易调试 agent 的思考路径。
知识库来源
一个生产级 RAG 系统需要既复杂又有挑战性的知识库,才能真正体现其有效性。我们将使用 NVIDIA 的 2023 年 10-K 报告(链接),这是一份超过百页的文件,详述公司的业务运营、财务表现和风险因素披露。
Sourcing the Knowledge Base (Created by Fareed Khan)
Sourcing the Knowledge Base (Created by Fareed Khan)
首先实现一个自定义函数,直接从 SEC EDGAR 数据库下载 10-K 报告,解析原始 HTML,并转换成干净、结构化的文本,供我们的 RAG 流水线摄取。
复制这段代码很直观,使用 beautifulsoup4 解析 HTML 并提取文本,可方便地在 HTML 结构中导航,获取有效信息,忽略脚本或样式等无关元素。
现在执行看看效果。
复制复制我们调用函数,把内容存到 txt 文件,作为后续 RAG 的上下文。运行上述代码后会自动下载,并可预览样例。
理解多源、多跳查询
为了测试我们实现的流水线,并与基础 RAG 对比,我们需要一个非常复杂的查询,覆盖我们所用文档的不同方面。
复制为什么这个查询会难倒标准 RAG 流水线?
- Multi-Hop 推理:它不能一步完成。系统必须先识别风险,再找 AMD 的新闻,最后把二者综合起来。
- 多源知识:所需信息在完全不同的地方。风险在内部静态文档(10-K)中,而 AMD 的新闻是外部的,需要实时 web 访问。
- 综合与分析:不是简单列出事实,而是要解释“后者如何加剧前者”,需要真正的综合推理。
下一节我们实现一个基础 RAG 流水线,看看它是如何失败的。
构建一个会失败的浅层 RAG 流水线
现在环境和挑战性知识库都准备好了,下一步是构建一个标准的“vanilla” RAG 流水线。这很重要……
先从最简单可行的方案开始,然后把复杂查询在其上运行,观察到底是如何以及为何失败。
我们将做如下事情:
Shallow RAG Pipeline (Created by Fareed Khan)
Shallow RAG Pipeline (Created by Fareed Khan)
- 加载并切分文档:读取清洗后的 10-K,并按固定大小切片——这是常见但语义上“天真”的方法。
- 创建 vector store:对这些切片做 embedding,并用 ChromaDB 建索引,支持基础语义搜索。
- 组装 RAG Chain:使用 LangChain Expression Language(LCEL)把 retriever、prompt 模板和 LLM 串起来,形成线性流程。
- 演示关键失败点:用我们的多跳多源查询去执行,分析其不充分的回答。
先加载清洗后的文档并切分。我们用 LangChain 的 RecursiveCharacterTextSplitter。
复制复制有了 378 个 chunk,下一步是让它们可检索——创建向量并存入数据库。我们用 ChromaDB 作为 vector store,并用 OpenAI 的 text-embedding-3-small 作为 embedding 模型(配置中已定义)。
复制复制Chroma.from_documents 会组织以上过程,把向量存入可检索的索引。最后用 LCEL 把它们装配成单一可运行的 RAG chain。数据流:用户问题 -> retriever -> prompt -> LLM。
复制注意第一步是个字典。context 由子链生成:输入问题 -> baseline_retriever -> format_docs;而 question 则原样透传(RunnablePassthrough)。
运行看看哪里会失败。
复制复制可以看到三个明显问题:
- 语境不相关:retriever 抓来一些“泛泛的 NVIDIA/competition/AMD”段落,却没有 2024 年 AMD 策略的具体细节。
- 信息缺失:2023 年的数据不可能覆盖 2024 年事件,系统没有意识到自己“缺关键信息”。
- 无规划与工具使用:把复杂问题当成简单问答,不能拆分步骤,也不会用 web 搜索来补齐。
系统失败不是因为 LLM 笨,而是因为架构过于简单。它用线性的一次性流程,试图解决一个循环的多步骤问题。
理解了基础 RAG 的问题后,接下来开始实现深度思考的方法论,看看如何解决复杂查询。
定义中央智能体系统的 RAG 状态
要构建推理 agent,首先需要管理它的“状态”。简单 RAG chain 的每一步都是无状态的,但……
智能的 agent 需要“记忆”。它需要记住最初的问题、它制定的计划、以及迄今为止收集到的证据。
RAG State (Created by Fareed Khan)
RAGState 将作为中央记忆,在我们的 LangGraph 工作流中在各节点之间传递。首先定义数据结构,从最基本的构件开始:研究计划中的单一步骤。
我们希望定义 agent 计划的原子单元。每个 Step 不仅要包含一个待回答的子问题,还要包含其背后的理由,尤其是指定要用的工具。这迫使 agent 的规划过程明确且结构化。
复制Step 类(基于 Pydantic BaseModel)为 Planner Agent 输出提供严格契约。tool: Literal[...] 强制 LLM 明确在内部知识(search_10k)与外部知识(search_web)之间做出选择。
这种结构化输出比解析自然语言计划可靠得多。
定义了单个 Step 后,需要一个容器保存整个步骤序列。创建 Plan 类,它是 Step 对象的列表,代表 agent 端到端的研究策略。
复制Plan 类为整个研究过程提供结构。调用 Planner Agent 时,我们会要求返回符合该 schema 的 JSON 对象。这样在任何检索行动前,agent 的策略都是清晰、按序的,且机器可读。
执行计划时,agent 需要记住自己学到了什么。定义 PastStep 字典,存储每个已完成步骤的结果,构成 agent 的“研究历史”或“实验手记”。
复制该结构对 agent 的自我批判(self-critique)循环至关重要。每一步后,我们填充这个字典并加入 state。agent 就能通过回顾这份逐步增长的摘要列表,理解自己已知/未知,决定是否已具备完成任务所需的信息。
最后,把这些拼装为主 RAGState 字典。它在整个图中流动,包含原始问题、完整计划、过往步骤历史,以及当前正在执行步骤的中间数据。
复制RAGState 就是 agent 的“心智”。图中的每个节点接受此字典为输入,并返回更新后的版本。
例如,plan_node 会填充 plan 字段,retrieval_node 会填充 retrieved_docs,以此类推。这个共享、持久的状态使复杂的迭代推理成为可能,这是简单 RAG 链所缺失的。
准备好 agent 的记忆蓝图后,开始构建第一个认知组件:Planner Agent。
战略规划与查询制定
Strategic Planning (Created by Fareed Khan)
本节分为三步工程:
- Tool-Aware Planner:构建 LLM 驱动的 agent,把用户查询分解为结构化 Plan,并为每步选择工具。
- Query Rewriter:创建专门 agent,把 planner 的简单子问题改写为高效检索的查询。
- Metadata-Aware Chunking:对源文档重新处理,增加 section 级 metadata,这是实现高精度过滤检索的关键。
使用工具感知规划器分解问题
Decomposing Step (Created by Fareed Khan)
不能把完整问题扔给数据库,指望运气。要教会 agent 将问题拆成更小、更易处理的部分。
为此,我们创建专门的 Planner Agent,并给出非常清晰的指令(prompt),告诉它该如何工作。
复制这里给 LLM 一个新 persona:expert research planner。明确告知它有两个工具(search_10k、search_web),以及各自适用场景——这就是“工具感知(tool-aware)”的部分。
我们要求它输出一个能直接映射到系统能力的计划,而不是模糊表述。
接下来初始化 reasoning 模型,并与 prompt 串接。关键是告诉 LLM 最终输出必须符合 Pydantic 的 Plan 类格式,确保结构化、可预测。
复制我们把 planner_prompt 通过 reasoning_llm,再用 .with_structured_output(Plan),让 LangChain 用函数调用能力,返回完全匹配 Plan schema 的 JSON 对象,比解析纯文本可靠得多。
测试输出如下:
复制可以看到,agent 不仅给了一个清晰的 Plan,还正确识别出问题包含两部分:
- 第一部分答案在 10-K 中,选了 search_10k,且正确猜测了可能的 section。
- 第二部分是“2024 年新闻”,10-K 中不可能有,正确选了 search_web。这说明我们的流程在“思考层面”已有希望。
使用查询重写智能体优化检索
目前我们有一个包含好子问题的计划。
但“有哪些风险?”这样的问法并不是好的检索查询,太笼统。无论是向量数据库还是 web 搜索,引擎更偏好具体、关键词丰富的查询。
Query Rewriting Agent (Creted by Fareed Khan)
为此我们构建一个小而专的 agent:Query Rewriter。它的唯一工作是,把当前步骤的子问题,结合已知上下文,改写为更适合检索的 query。
先设计 prompt:
复制我们让这个 agent 扮演“search query optimization expert”。它接收三类信息:sub_question、keywords、past_context,以此构造更强的查询。
初始化 agent:
复制结果如下:
复制原问题面向分析师;改写后的查询面向搜索引擎,包含更具体术语,如“MI300X”、“market share erosion”、“data center”等,这些都从关键词和过往上下文中归纳出来。这样的查询更可能检回准确文档,提升系统准确与效率。
通过元数据感知分块提升精度
Planner Agent 让我们有了“额外线索”:它不仅说“找风险”,还提示“看 Item 1A. Risk Factors 这一节”。
但当前 retriever 用不上这个提示。vector store 只是 378 个 chunk 的“扁平列表”,不知道什么是“section”。
Meta aware chunking (Created by Fareed Khan)
我们需要重建 chunks。这次,每个 chunk 都要加上“它来自 10-K 的哪一节”的 metadata 标签。这样 agent 就能执行更精确的“过滤检索”。
首先,需要在原始文本中程序化定位每个 section 的起始。观察文档格式,每个主 section 以 “ITEM”+编号开头(如“ITEM 1A”、“ITEM 7”),非常适合用正则。
复制这条 pattern 用于检测 section 标题,既要足够灵活以适配多种格式,又要足够具体避免误抓。
应用该 pattern,把文档切分为两个列表:section 标题列表、对应内容列表。
复制这是一种高效解析半结构化文档的方法。用一次 findall 获得所有 section 标题,再用一次 split 按标题切分全文。assert 是健全性检查,确保解析正确。
接着,将标题与内容逐一对应,生成最终带 metadata 的 chunks。
复制核心在于:为每个 chunk 附加 metadata,将 section_title 作为标签。输出如下:
复制看到 metadata 中的 'section': 'Item 1A. Risk Factors.' 了吗?现在,当 agent 需要找“风险”时,可以对 retriever 说:“只在 sectinotallow='Item 1A. Risk Factors' 的 chunks 中检索”。一个简单的改造,就让检索从“钝器”变成“手术刀”。这是构建生产级 RAG 的关键原则。
创建多阶段检索漏斗
到目前为止,我们已经做了智能规划,并为文档添加了 metadata。现在构建系统的核心:复杂的检索流水线。
简单的一次性语义搜索已经不够。生产级 agent 需要自适应、分阶段的检索流程。
Multi Stage Funnel (Created by Fareed Khan)
- Retrieval Supervisor:构建 supervisor agent 作为动态路由器,分析每个子问题并选择最佳检索策略(vector、keyword 或 hybrid)。
- 第一阶段(广覆盖 Recall):实现 supervisor 可选的不同检索策略,尽可能广泛地捕获潜在相关文档。
- 第二阶段(高精度 Precision):使用 Cross-Encoder 模型对初始结果进行重排,去噪并将最相关文档置顶。
- 第三阶段(综合 Synthesis):创建 Distiller Agent 将 top 文档压缩为单一、简洁的上下文。
使用监督器动态选择策略
并非所有查询都相同。比如“Compute & Networking 分部 2023 财年的 revenue 增长是多少?”包含非常具体的术语,keyword 搜索更合适;而“公司对市场竞争的整体态度如何?”则是概念性问题,semantic 搜索更优。
Supervisor Agent (Created by Fareed Khan)
我们不硬编码策略,而是构建一个小而智能的 agent——Retrieval Supervisor。它的职责就是分析查询,决定用哪种检索方式。
先定义其输出的结构:
复制然后是 prompt:
复制装配该 agent 并测试:
复制复制它能正确地为具体术语选 keyword_search,为概念性问题选 vector_search。动态决策比一刀切强得多。
利用混合、关键词与语义搜索进行广泛召回
有了 supervisor 选择策略,我们需要实现这些策略。第一阶段的目标是 Recall(广覆盖):尽可能捕获所有潜在相关文档,即使带入一些噪声也没关系。
Broad Recall (Created by Fareed Khan)
我们实现三种搜索函数:
- Vector Search:标准语义搜索,升级为支持 metadata filter。
- Keyword Search(BM25):传统且强大的算法,擅长匹配具体术语。
- Hybrid Search:结合二者,用 RRF(Reciprocal Rank Fusion)融合。
先用带 metadata 的 chunks 创建一个高级 vector store。
复制接着构建 BM25 的索引:
复制定义三个检索函数:
复制快速测试 keyword 搜索是否能精确命中目标 section:
复制复制如预期,BM25 能精确、迅速地检回 “Item 1A. Risk Factors” 相关文档。当查询包含具体关键词(如 section 标题)时,supervisor 就可以选择这一精准工具。
接下来进入高精度阶段,进行重排。
使用交叉编码器重排器实现高精度
第一阶段的 Recall 能拿到 10 个“潜在相关”的文档。
但“潜在相关”还不够,直接把这 10 个 chunk 全喂给主推理 LLM 会既低效又有风险——成本高,还可能被噪声干扰。
High Precision (Created by Fareed Khan)
我们需要 Precision 阶段,用 Reranker 来从这 10 个候选中挑出最相关的少数。区别在于模型工作方式:
- 初始检索用的是 bi-encoder(embedding 模型),分别对 query 与文档编码,速度快、适合海量搜索。
- Cross-Encoder 则将“query + 单个文档”作为一对,一起输入,做更深入的比较。它更慢,但更准。
我们要写一个函数,把 10 个文档用 Cross-Encoder 打分重排,只保留 config 里的 top 3。
初始化 Cross-Encoder 模型:
复制定义重排函数:
复制该函数用 cross-encoder 对每个(query, doc)对进行打分,排序后截取前 3,输出短小而高相关的文档列表,作为后续 agent 的完美上下文。这样的漏斗式处理(先高召回,再高精度)是生产级 RAG 的关键。
通过上下文蒸馏进行综合
现在我们有 10 -> 3 的高相关文档,但仍然是三个独立块。为进一步精炼,再加入最后一道“压缩”——Contextual Distillation:将前 3 个文档“蒸馏”为一个简洁、干净的段落,去除冗余,构建一段信息密度极高的上下文。
Synthesization (Created by Fareed Khan)
这一步是针对文本处理,不负责回答问题。我们创建 Distiller Agent:
复制在主循环中,每一步的流程将是:
- Supervisor:选择检索策略(vector/keyword/hybrid)。
- Recall:执行选择的策略,取 top 10 文档。
- Precision:用 rerank_documents_function 取 top 3。
- Distillation:用 distiller_agent 压缩为单段精华。
这样我们的证据质量达到最佳。下一步,给 agent “看向外部世界”的能力:web 检索。
使用网络搜索增强知识
目前的检索漏斗很强,但有一个致命盲点:
它只能看到 2023 年 10-K 中的内容。而我们的挑战需要“2024 年 AMD 的 AI 芯片策略”的最新新闻——这些在静态知识库中根本不存在。
真正的“深度思考” agent,必须意识到自身知识的边界,并能到别处找答案。我们需要给它一扇“窗”。
Augemtation using Web (Created by Fareed Khan)
这一步我们为系统增加一个新工具:Web Search,使其从“文档特定问答机器人”变成真正的多源研究助手。
我们使用 Tavily Search API——专为 LLM 构建的搜索引擎,返回干净、无广告、相关的结果,非常适合 RAG;同时与 LangChain 集成顺畅。
初始化 Tavily 搜索工具:
复制原始 API 响应需要包装为标准的 Document 列表,以便与我们的 reranker、distiller 无缝衔接。写一个小包装函数:
复制测试:
复制复制结果如愿,找到了 3 篇相关网页。摘要提到了 AMD “Instinct MI300X” 与 NVIDIA “H100”的对抗——正是解决第二部分问题所需的证据。现在 agent 拥有通往外部世界的窗口,planner 可以智能地决定何时使用它。下一步是让 agent 能够“反思”并决定何时结束研究。
自我评估与控制流策略
到目前为止,agent 能制定计划、选择工具,并执行复杂的检索漏斗。但还缺少一个关键能力:对自身进展进行“思考”。盲目照搬计划逐步执行的 agent 并非真正智能,需要一个自我批判机制。
Self Critique and Policy Making (Created by Fareed Khan)
每次研究步骤后,agent 都会停下来反思,比较新信息与既有知识,然后做出策略性决策:研究是否已完成,还是要继续?
这个自我批判循环让系统从脚本化工作流,跃升为自治 agent。它能判断自己是否已经收集到足够的证据,来有信心地回答用户问题。
我们将实现两个专门 agent:
- Reflection Agent:读取当前步骤的精炼上下文,写一条简洁的一句话摘要,加入“研究历史”。
- Policy Agent:作为总指挥,在反思之后,审视整个历史与最初计划,做出关键决策:CONTINUE_PLAN 或 FINISH。
更新并反映累积研究历史
每完成一步(例如:检索并蒸馏出 NVIDIA 的风险),不要直接进入下一步。需要把新知识整合到 agent 的记忆中。
Reflective Cumulative (Created by Fareed Khan)
构建 Reflection Agent:任务是读入当前步骤的精炼上下文,写一条事实性的一句话摘要,并把它添加到 RAGState 的 past_steps 中。
复制它是认知循环的重要组成:通过这些简洁摘要,构建干净易读的“研究历史”,为下一个、也是最重要的 agent——策略决策者,提供输入。
B构建用于控制流的策略智能体
这是 agent 自主性的“大脑”。在 reflection_agent 更新历史后,Policy Agent 上场,作为总调度,查看:原始问题、初始计划、已完成步骤摘要的全量历史,做出高阶策略决策。
Policy Agent (Created by Fareed Khan)
定义决策输出结构:
复制设计 prompt:
复制测试两个状态:
复制复制未完成状态时,正确选择 CONTINUE_PLAN;完成状态时,正确选择 FINISH。有了 policy_agent,我们具备自主系统的头脑。接下来用 LangGraph 把所有组件串起来。
定义图节点
我们已经设计好这些专门的 agent。现在要把它们变成工作流的“积木”。LangGraph 中的“节点(node)”就是干这事的:每个节点是一个 Python 函数,完成一项具体工作,接收 RAGState,更新并返回字典。
Graph Nodes (Created by Fareed Khan)
先写一个工具函数,把研究历史 past_steps 格式化成易读字符串,方便传给 prompt:
复制第一个节点:plan_node,调用 planner_agent 填充 plan 字段。
复制接着是两个检索节点:内部文档与 web。
复制复制然后是 Precision 与 Distillation 节点:
复制复制反思并更新历史:
复制最终答案生成:
复制节点齐备后,接下来定义“边”(edges),确定它们之间的连接关系与控制流。
定义条件边
我们需要两类关键的条件边:
- 工具路由器(route_by_tool):在 plan 之后,查看当前步骤应使用的工具,路由到 retrieve_10k 或 retrieve_web。
- 主控制循环(should_continue_node):每次反思后,调用 policy_agent 决定是继续下一步还是结束并生成答案。
工具路由器:
复制主控制循环:
复制有了节点(专家)与条件边(对话规则),我们就可以构建完整的 StateGraph。
连接深度思考 RAG 机器
现在用 LangGraph 的 StateGraph 来定义完整的认知架构,也就是 agent 的思维流程蓝图。
复制添加节点:
复制连接边与条件边:
复制流程回顾:
- 从 plan 开始;
- route_by_tool 决定走 retrieve_10k 还是 retrieve_web;
- 然后始终按 rerank -> compress -> reflect;
- reflect 后,通过 should_continue_node 决定:
- 若 CONTINUE_PLAN,回到 plan,路由下一步;
- 若 FINISH,进入 generate_final_answer;
- 生成最终答案后结束。
至此,我们完成了深度思考 Agent 的复杂、循环架构。下一步是编译与可视化。
编译与可视化迭代工作流
编译(.compile())会把抽象的节点与边定义,转化为可执行应用。我们还可以用内置工具生成图示,有助于理解与调试。
复制
Deep Thinking Simpler Pipeline Flow (Created by Fareed Khan)
你会看到:
- route_by_tool 选择内部或外部检索的分支;
- 每个研究步骤的线性处理(rerank -> compress -> reflect);
- 关键的反馈循环:should_continue 把流程送回 plan,开始下一轮;
- 研究完成后进入 generate_final_answer 的“出口”。
这就是一个“会思考”的系统。接下来实际运行。
运行深度思考流水线
我们要用相同的多跳多源查询来测试这个系统,看看它能否成功。
这里我们调用 .stream() 观察每个节点更新后的 state,实时追踪 agent 的“思考过程”。
复制复制可以看到系统完整执行了我们设计的流程:规划 -> 步骤 1 -> 自我评估继续 -> 步骤 2 -> 自我评估结束 -> 最终综合。
分析最终高质量答案
打印最终答案:
复制复制这是一次“完全成功”的综合性回答:
- 正确总结了 10-K 的风险;
- 正确总结了 2024 年 AMD 动向;
- 关键在“综合与影响”部分:完成了多跳推理,解释“后者如何加剧前者”;
- 并提供了来源溯源(内部 section 与外部 URL)。
并排对比
让我们把两种结果放在一起对比。
这个对比清晰地说明:采用循环、工具感知、自我批判的 agent 架构,在复杂真实查询上实现了显著且可量化的性能提升。
评估框架与结果分析
虽然我们在一个难题上取得了成功,但在生产环境中需要客观、量化、自动化的验证。
Evaluation Framework (Created by Fareed Khan)
我们使用 RAGAs(RAG Assessment)库,聚焦四个关键指标:
- Context Precision & Recall:衡量检索质量。Precision 问:检回的文档有多少真相关?Recall 问:所有相关文档中,我们找到了多少?
- Answer Faithfulness:答案是否扎根于提供的上下文,是防止 LLM 幻觉的主要检查。
- Answer Correctness:最终质量度量,与人工撰写的“ground truth”答案对比,评估事实准确性与完整性。
准备评估数据集(包含问题、两套系统的答案与上下文、以及 ground truth)并评测:
复制输出示例:
复制量化结果为 Deep Thinking 架构给出明确客观的优势:
- Context Precision(0.50 vs 0.89):baseline 只有一半相关,因为只能检回关于“竞争”的泛化信息;advanced agent 通过多步骤、多工具检索,显著提升精度。
- Context Recall(0.33 vs 1.00):baseline 完全错过了 web 信息,召回低;advanced 通过规划与工具使用,找齐全部必要信息,达到满分。
- Faithfulness(1.00 vs 1.00):两者都很忠实。baseline 正确指出自己没有信息;advanced 正确使用了找到的信息。忠实但不正确的答案也没意义。
- Answer Correctness(0.40 vs 0.99):最终质量指标。baseline 因缺失第二部分分析而低于 40%;advanced 接近完美。
总结整个流水线
本文中,我们从一个简单、脆弱的 RAG 流水线,构建到一个复杂的自治推理 agent:
- 先搭建 vanilla RAG,并演示它在复杂多源查询上的必然失败;
- 系统化地打造 Deep Thinking Agent,赋予其规划、多工具使用、与自适应检索策略的能力;
- 构建多阶段检索漏斗:先广召回(hybrid search),再高精度(cross-encoder reranker),最后综合(distiller agent);
- 使用 LangGraph 编排整个认知架构,创建循环、有状态的工作流,实现真正的多步推理;
- 加入自我批判循环,让 agent 能识别失败、修订计划、并在无法得到答案时优雅退出;
- 最后用 RAGAs 做生产级评估,客观量化证明 advanced agent 的优越性能。
使用马尔可夫决策过程(MDP)学习策略
目前,我们的 Policy Agent(决定 CONTINUE 或 FINISH)依赖于像 GPT-4o 这样的通用 LLM,每次都要调用。尽管有效,但在生产环境可能较慢且昂贵。学术前沿提出了更优的路径。
- 将 RAG 建模为 Decision Process:把 agent 的推理循环建模为 Markov Decision Process(MDP)。在这个模型中,每个 RAGState 是“状态”,每个 action(CONTINUE、REVISE、FINISH)会把系统带入新状态,并获得一定“奖励”(比如找到正确答案)。
- 从经验中学习:我们在 LangSmith 中记录的成千上万次成功/失败的推理轨迹,都是宝贵的训练数据。每条轨迹都是 agent 在这个 MDP 中的一个例子。
- 训练 Policy Model:利用这些数据,可以用 Reinforcement Learning 训练一个更小、更专门的 policy 模型。
- 目标:速度与效率。把像 GPT-4o 这样复杂模型的决策能力,蒸馏到一个更小(例如 7B)的模型里,使 CONTINUE/FINISH 的决策更快、更省,同时高度针对我们的领域。这是诸多研究(如 DeepRAG)的核心思想,也是自治 RAG 系统优化的下一阶段。