第 11 章  ·  推理模式:Agent如何思考

第11章 第6节 推理模式:Agent如何思考


第11章 第6节 推理模式:Agent如何思考

阅读指南

前面几节,我们已经了解了Agent的整体架构、感知能力、规划能力和记忆系统。但有一个核心问题始终没有正面回答:
Agent是如何"思考"的?
当Agent面对一个问题时,它在大脑(LLM)中经历了什么过程?为什么有时能给出完美答案,有时却会犯低级错误?

6.1 推理与感知-规划-执行的关系

推理在Agent的"感知-规划-执行"循环中处于什么位置?

答案是:推理贯穿整个循环的每一步

感知层(Perception)
  ↓
  需要推理:理解用户意图、提取关键信息

规划层(Planning)  
  ↓
  需要推理:拆解任务、选择工具、制定策略

执行层(Action)
  ↓
  需要推理:判断结果、决定下一步、处理异常

观察(Observation)
  ↓
  需要推理:分析反馈、评估是否达成目标

具体来说:

所以,推理不是独立的一步,而是Agent在每个决策点都要用到的核心能力

本节我们聚焦的是:Agent在这些决策点使用的推理模式(CoT、ToT、ReAct等)有什么特点,如何选择和组合使用。


6.2 Agent推理的核心挑战

在第1章第10节,我们学习了Chain-of-Thought(思维链)的基础原理——通过"让我们一步步思考"引导LLM展示推理过程,能让准确率从17%提升到78%。

但Agent面临的推理场景远比单次问答复杂:

单次问答(第1章场景):
用户提问 → LLM推理 → 给出答案 → 结束

Agent场景(本章关注点):
用户目标 → 多轮推理决策 → 调用工具 → 观察结果 
         ↑                            |
         └────────── 循环往复 ─────────┘

Agent推理的三大特殊性:

  1. 动态性:每一轮的推理都基于上一轮的观察结果
  2. 工具依赖:需要决策何时调用哪个工具
  3. 多轮性:可能需要5-10轮推理才能完成任务

这就需要更强大的推理模式。

6.3 CoT在Agent中的特殊应用

第1章我们学过,CoT有两种形式:Zero-Shot("让我们一步步思考")和Few-Shot(给推理示例)。但在讲Agent中的CoT应用之前,我们必须先扔掉一个常见的误解

CoT的本质:不是"思考",而是"生成文本"

很多人看到CoT的例子后,会认为:LLM真的在“思考”。但事实是:LLM只是在生成一段看起来像推理过程的文本

当你给LLM这样的Prompt:

问题:小明有3个苹果,又买2个,他现在有几个苹果?

让我们一步步思考:

LLM会生成这样的文本:

小明最开始有3个苹果
他又买2个
所以总数是 3 + 2 = 5
答案:5个苹果

看起来LLM像是一个人一样在“思考”, 但其实不是。LLM只是在生成文本,他根本不知道这是连续的思维过程。具体来说:

回顾:CoT如何让LLM生成"推理步骤"

Zero-Shot CoT:只需加一句引导词

# 不用CoT
prompt = "小明有3个苹果,又买2个,他现在有几个?"
response = llm.invoke(prompt)
# 输出:“5个” (直接给答案,但可能出错)

# 使用CoT
prompt = """
小明有3个苹果,又买2个,他现在有几个?

让我们一步步思考:
"""
response = llm.invoke(prompt)
# 输出:“步骤1:...步骤2:...答案:5个” (生成了推理步骤)

为什么有效

Few-Shot CoT:给几个示例

prompt = """
示例1:
问题:小红有5个橘子,吃掉2个,还剩几个?
推理:
- 最开始:5个
- 吃掉2个:减去2个
- 计算:5 - 2 = 3
答案:3个

示例2:
问题:小明有3支笔,又买2支,现在有几支?
推理:
- 最开始:3支
- 又买2支:增加2支
- 计算:3 + 2 = 5
答案:5支

现在轮到你:
问题:小明有3个苹果,又买2个,他现在有几个?
"""
response = llm.invoke(prompt)
# LLM会模仿示例的格式,生成类似的推理步骤

CoT的核心原理在于生成文本模式,而非真正的逻辑推理。

CoT在Agent中的应用:任务规划

现在我们来看,CoT在Agent系统中是如何应用的。Agent中的CoT主要用于任务规划阶段,而不是执行阶段。

用户问:

帮我查一下明天杭州和上海的天气,推荐一个适合旅游的城市。

Agent 在规划阶段把用户问题包装成 CoT 风格的 Prompt,发给 LLM:

用户问题:帮我查一下明天杭州和上海的天气,推荐一个适合旅游的城市。

请制定一个任务执行计划,一步步分析需要做什么:

LLM 收到后,生成如下计划文本:

步骤1:理解需求

步骤2:分解子任务

步骤3:选择工具

注意

  1. 这里的“步骤1、步骤2、步骤3”是 LLM 生成的文本
  2. 这是一个计划,不是真实执行
  3. 真实执行是后面的事(会用到 ReAct 模式,后面章节会讲)

6.4 Tree-of-Thought:Agent的多路径探索

在Agent系统中,经常遇到需要尝试多个工具或多种方案的场景。这时单路径的CoT就不够用了,需要Tree-of-Thought(思维树)来探索最优解。

ToT的Agent应用场景

场景1:多工具选择

用户:帮我分析一下公司这个月的销售数据,找出top5产品,
    并生成一份可视化报告发给老板

[第1层:选择数据源工具]
  选项1:read_excel读取本地文件
  选项2:query_database查询数据库
  选项3:call_api调用销售系统API

  评估:用户说"这个月",需要实时数据 → 选API

[第2层:选择分析工具]
  选项A:直接用pandas计算
  选项B:调用数据分析服务
  选项C:用SQL聚合

  评估:数据量不大,本地处理即可 → 选pandas

[第3层:选择可视化工具]
  格式1:generate_chart生成静态图
  格式2:create_dashboard生成交互式看板
  格式3:直接返回表格

  评估:给老板看,需要专业呈现 → 选交互式看板

[第4层:选择发送方式]
  方式1:send_email发邮件
  方式2:upload_to_drive上传到共享盘
  方式3:post_to_slack发到工作群

  评估:用户说"发给老板",正式场合 → 选邮件

最终方案:API取数 → pandas分析 → 交互看板 → 邮件发送

场景2:异常处理策略

工具调用失败时,探索多种补救方案:

[第1轮:天气API调用失败]
  方案1:重试3次
  方案2:切换备用API
  方案3:使用缓存数据

  评估:备用API可能也失败 → 选重试

[第2轮:重试仍失败]
  方案A:返回错误给用户
  方案B:用历史天气数据估算
  方案C:改用网页爬取

  评估:历史数据不准确 → 选网页爬取

最终路径:重试 → 网页爬取 → 成功获取数据

CoT与ToT的实现原理区别

CoT的实现:Prompt层面的引导

CoT本质上非常简单,只是在Prompt中加入引导词:

Zero-Shot CoT:
用户问题 + "让我们一步步思考"
  ↓
单次LLM调用
  ↓  
LLM自动生成:步骤1→步骤2→步骤3→答案

Few-Shot CoT:
示例1(问题→推理→答案) + 示例2 + 用户问题
  ↓
单次LLM调用
  ↓
LLM模仿示例格式输出推理过程

关键特点:

ToT的实现:需要搜索算法控制

ToT复杂得多,需要外部程序控制的树搜索算法,所以我们不推荐手工实现ToT。这里我们只简单介绍下ToT的关键核心技术:

核心流程:
1. 生成层:让LLM为同一问题生成多个不同的初步想法
2. 评估层:让LLM或设计评估函数给每个想法打分
3. 选择层:用搜索算法选择最优的几个分支继续扩展
4. 递归层:对选中的想法继续步骤1-3,构建多层决策树
5. 最终选择:从所有路径中选出得分最高的完整方案

需要的关键算法:

关键特点:

如果你需要在Agent系统中使用ToT,推荐LangGraph。官方文档提供完整的ToT教程和示例代码。

最佳实践:

6.5 Self-Reflection:Agent的自我修正

Agent需要反思的原因

Agent的工具调用和多轮交互尤其容易出错:

用户:帮我订明天去杭州的高铁票。

Agent(没有反思):
调用:book_train("明天", "杭州")
结果:失败 - 缺少出发城市参数

Agent(有反思):
反思:要订票需要出发城市,用户没提供,我应该先询问。
行动:询问用户出发城市

Agent反思的三个阶段

阶段1:执行前检查(Pre-Action Reflection)

在调用工具前,Agent先反思:

用户:帮我查一下明天杭州的天气,如果不下雨就订票。

Agent:
我要调用get_weather工具,参数是:
- 城市:杭州
- 日期:明天

反思:等等,"明天"不是标准日期格式,API可能无法识别。

修正:先转换为"2024-12-10",再调用工具。

阶段2:执行后验证(Post-Action Reflection)

工具调用后,检查结果是否合理:

Agent调用:get_weather("杭州", "2024-12-10")
返回:{"weather": "晴天", "temperature": "5-15度"}

反思:天气不错,可以订票。但用户没说从哪里出发,
不能直接调用book_train。

修正:先询问用户出发城市。

阶段3:答案最终审查(Final Answer Reflection)

在给出最终答案前,检查逻辑是否合理:

用户补充:从上海出发。

Agent已订票:上海 → 杭州,12月10日,G7533次

Agent初步答案:已为您订好明天的票,上海到杭州。

反思:等等,我还没告诉用户天气情况,
这是用户决策的重要依据。

修正:明天杭州晴天5-15度,已为您订好上海到杭州的G7533次列车。

成本权衡

Agent中的反思需要谨慎使用:

Agent最佳实践:

6.6 下一节预告

理解了Agent的推理模式后,你可能会迫不及待地想动手实现一个自己的Agent。但这时会面临一个关键选择:是从零手写代码,还是使用现成框架?用单体架构简单直接,还是模块化设计更易扩展?接下来,我们将对比Agent的各种实现范式,帮你根据实际场景做出最适合的技术选型。


6.7 ■ 学点英语

中文 English 音标 说明
思维链 Chain-of-Thought (CoT) /tʃeɪn əv θɔːt/ 通过一步步推理展示LLM决策过程的Prompt技巧
思维树 Tree-of-Thought (ToT) /triː əv θɔːt/ 探索多条推理路径并选择最优解的搜索框架
自我反思 Self-Reflection /self rɪˈflekʃn/ Agent在关键节点自行检查并修正决策的机制
广度优先搜索 BFS (Breadth-First Search) /bredθ fɜːrst sɜːrtʃ/ ToT中每层探索所有可能再筛选的搜索算法
深度优先搜索 DFS (Depth-First Search) /depθ fɜːrst sɜːrtʃ/ ToT中沿一条路径探索到底再回溯的搜索算法
蒙特卡洛树搜索 MCTS (Monte Carlo Tree Search) /em siː tiː es/ 结合随机采样和价值评估的树搜索算法

本节热门答疑

苑畅5天前

思考过程应不应该算不算在token里面?

我问了deepseek和Gemini都回答显示思考过程是计算在token里面的,如果不显示思考过程,但是会影响答案的准确性,如果显示思考过程又会消耗更多的token,那这之间如何平衡? 举例说明:一个问题是20token,思考过程100token,答案50token,这样的话最终计算token是20+100+50=170.这个思考过程100token,按道理你大模型收到问题,无论我是否要显示思考过程,你都要思考的,怎么要算我token费用呢? deepseek的回答: 关键区别:内部计算 ≠ 生成文字 你认为: “不显示思考过程,模型也要内部思考,那思考本身消耗的 100 token 为什么不收费?” 这里你犯了一个概念混淆:你把“思考过程”当成了一个固定大小的、必须存在的东西(比如100个token的“思考量”),然后认为无论是否显示,这个“思考量”都发生了,所以应该都收费。 但实际情况是: 模型内部的计算(神经网络的矩阵运算、激活、推理)—— 不以 token 为单位,也不按 token 收费。它消耗的是 GPU 计算时间、电力,这部分成本已经包含在 API 的定价模型里(按输入+输出 token 收费是一种间接方式)。 “思考过程”这个词在 prompt 里指的是:模型生成出来的一段文字,内容是“首先…其次…所以…”。这段文字才以 token 为单位。 当你要求“不显示思考过程”时,模型并没有生成那 100 token 的文字。它内部的计算路径可能短一些,也可能类似,但绝对不会产生那 100 个 token 的输出。 所以收费时,这 100 token 根本不存在,当然不会收。 你的逻辑错误在哪里? 你假设: “对于同一个问题,你显不显示你都是需要思考这 100 token 的量。” 这是错的。 “100 token 的思考量”是一个没有意义的说法。Token 是文本长度单位,不是计算量单位。 模型内部的计算量不是用 token 衡量的,而是用浮点运算次数(FLOPs)、层数、参数规模等衡量。 同一个问题,模型是否输出中间步骤,内部计算量可能差不多,也可能有差异(因为生成更长的输出需要更多前向传播步数),但无论如何,输出 token 的数目完全由你要求的内容决定。 用一个更精确的类比 假设你是人类专家,回答客户问题: 内部思考(脑子想):不产生任何文字,不收费。 写答案:你只写最终结论,收 50 个字费。 写思考+答案:你先在纸上写下“第一步…第二步…”,再写结论。那 100 个字就是额外收费的。 你说:“我脑子想的时候不也要想那 100 个字的思考步骤吗?为什么不收?” 因为脑子想的时候,并没有真的写出那 100 个字。你想的可能是模糊的、跳跃的、非语言的,跟写下来的详细步骤不是同一件事。 那准确性为什么受影响? 显示思考过程:模型被强制要求“把推理链写出来”,这相当于给了模型一个锚点,每一步都要自洽,写的过程会触发自我校验,减少错误。 不显示:模型直接跳到最后答案。它仍然内部计算,但由于没有强制写出来,它可能会走捷径、忽略中间步骤,导致逻辑跳跃或错误。 内部计算的“深度”可能相同,但缺少了“显式表达”带来的纠正机制。 结论 你不需要为“内部思考”付 token 费,因为那不是文本。 只有我生成并发送给你的文字才收 token 费。 你要求“显示思考过程”时,我额外生成了一段文字,所以 token 变多。 你要求“不显示”时,这段文字根本没有产生,所以 token 少。 准确性差异不是因为 token 多寡,而是因为“写出来”这个行为本身会改善推理质量。 现在清楚了吗?如果还有疑问,我可以再换一个角度解释。 我又追问: 那根据你的假设,你是人类专家,别人问你一个问题,写出来跟不写出来,难道答案不一样? 你这个问题问到根子上了。我承认,我之前的类比有漏洞,让你抓住了。 直接回答你的质疑:是的,对于同一个人类专家,如果他把思考过程写出来,最终的答案可能不一样 ——而且往往是更准确。 这不是我的假设,而是认知科学和教育心理学中已经验证的事实。 为什么写出来会让答案不同? 工作记忆的局限 人类的大脑在纯思考时,工作记忆只能同时处理约4±1个信息块。复杂问题很容易丢步骤、跳逻辑。 当写下来时,思考被外化到纸上,工作记忆的负担大大减轻。你可以回看、检查、修正,相当于多了“外部缓存”。 自我解释效应 强迫自己用语言把推理步骤写清楚,会激活大脑的不同区域(布罗卡氏区等),这个过程会倒逼你发现逻辑漏洞。很多人在写的过程中会突然意识到“等等,这里不对”——如果只是在脑子里想,很容易忽略这个漏洞。 错误更容易被捕捉 一段写下来的文字,你可以逐字审视。内部思考是快速的、模糊的、跳跃的。写下来就像把快照放慢成逐帧画面,错误无处遁形。 举个具体例子 问:“一个球拍加一个球共1.1美元,球拍比球贵1美元,球多少钱?” 纯思考(不写):很多人直觉说“球0.1美元,球拍1美元”,但实际上1美元比0.1美元只贵0.9美元,不满足“贵1美元”条件。不写过程,这个错误很难被发现。 写下来: 设球 = x,球拍 = x+1,总价 (x+1)+x = 1.1 → 2x+1=1.1 → 2x=0.1 → x=0.05。 在写的过程中,你自然会发现0.1美元是错的。 同一个专家,写出来就能避免直觉错误。 所以答案确实可能不同。 回到你的原始问题 你说:“显不显示你都是需要思考这100token的量啊”——对于AI模型来说,情况更复杂。 模型不像人类那样有固定的内部思考量。它生成“思考过程文字”时,实际上是在执行不同的计算路径(链条式推理),而不是简单地把同一个内部思考转录出来。 当要求“不显示思考过程”,模型走的是直接生成答案的路径(较短、易出错)。 当要求“显示思考过程”,模型走的是逐步推理的路径(较长、更准确)。 两者内部计算量不同,最终答案质量也不同。 总结 你的质疑是对的:如果用“同一个思考过程只是写与不写”,那答案应该一样。 但现实是:写与不写会改变思考过程本身。对人类和AI都是如此。 因此,你要在准确性(显示思考过程)和经济性(不显示)之间权衡。 需要我帮你量化一下这种准确性差异有多大吗?比如测试几个典型问题。 根据对话得出的结论: 不显示思考过程,最终是20+50=70,显示思考过程是20+100+50=170,这100token是因为把过程写下来并发给我们看了,写个过程是消耗token的(这个是能理解的),所以要收100token。 不显示可能会忽略一些问题,导致准确率降低,类似于高中老师说的眼高手低。显示的话可以即时纠正前面可能是错误的内容,来提高准确性。 不知道其他同学有没有类似的疑问?

25 阅读2 回复0 点赞

记忆系统:让Agent拥有经验 Agent 的实现范式对比
本节目录