规划与反思
第 25 课:规划与反思
上一课我们把「知道什么」交给了记忆与检索;但一个长任务光有知识还不够——规划该怎么做、反思到底值不值?这一课从「一步错、步步错」的错误累积讲起,把计划—执行—反思三件套、分解粒度、树搜索式分解(Tree of Thoughts)与语言化反思(Reflexion)一路算清,最后回到最关键的边界:反思什么时候会白转、甚至有害。它上承第 24 课《记忆与 RAG 工程化》(RAG 即「检索增强生成」),下启第 26 课《多智能体与协议》。
② 用 b^d 估分解方案的搜索代价(3³=27、5³=125、5⁴=625),并说清「每步可独立验证」才是粒度下限
③ 用 Tree of Thoughts 的 4%→74% 与 Reflexion 的 80%→91% 两个数字,说清结构化探索与语言化反思各自的收益与代价
一个 Agent 要跑完长任务,为什么常常「一步错、步步错」?
因为长任务要求每一步都对,成功率是每步正确率的连乘(p^N);更糟的是,一处错误一旦写进 context(即「模型每一步能看到的全部文字」),后面每一步都会带着它继续推理。就像没有图纸就盖楼:砌错一堵承重墙,上面所有楼层都得拆掉重来。所以先把「错从哪来、规划值多少」算清楚。
| 任务步数 N | 全对成功率 p^N(p=0.95) | 至少错一步 |
|---|---|---|
| 5 步 | 0.95⁵ ≈ 0.774 | 约 23% |
| 10 步 | 0.95¹⁰ ≈ 0.599 | 约 40% |
| 20 步 | 0.95²⁰ ≈ 0.359 | 约 64% |
| 做法 | 单步正确率 | 10 步全对 |
|---|---|---|
| 不规划,直接做 | 0.95 | 0.95¹⁰ ≈ 0.599 |
| 先花 1 步做计划,再执行 | 0.99 | 0.99¹⁰ ≈ 0.904 |
| 项 | 数值 |
|---|---|
| 总步数 | 10 |
| 出错位置 | 第 3 步 |
| 被影响的后续步数 | 10 − 3 = 7 步 |
长任务的第一原则是先想再做:规划不是装饰,而是把每步正确率抬上来的杠杆;而错误一旦写进 context 就会被后续继承。记住这个量级——规划花 1 步,救回的是整条链的成功率。
上一张卡片说明长任务要先规划。但「有计划」还不够——计划会错、执行会失败,所以为什么还要有反思这一环?
因为三步缺任何一步,循环都会退化成「重复劳动」:没有计划就没有方向,没有执行就只剩空想,没有反思就会在同一个坑里反复摔。就像考完试整理错题本:不改脑子,只改下一次的答题策略。所以先看清三件套的分工,再算它值多少。
| 组件 | 做什么 | 缺了会怎样 |
|---|---|---|
| Plan 计划 | 把任务拆成可执行步骤 | 执行没有方向 |
| Act 执行 | 调用工具、拿到观察 | 只剩空想,世界不变 |
| Reflect 反思 | 评估结果、把教训写回 context | 同一个错反复犯 |
| 环节 | 调用次数(以 5 步任务为例) |
|---|---|
| 计划 | 1 |
| 执行 | 5 |
| 反思 | 1 |
| 合计 | 1 + 5 + 1 = 7 次 |
| 情形 | 3 轮里的执行步数 |
|---|---|
| 无反思,每轮重试 5 步 | 5 × 3 = 15 步,错误照旧 |
| 有反思,第 2 轮换策略 | 5 × 2 = 10 步,第 3 轮不再重试 |
三件套的判据是「闭环」:没有执行的反思是空想,没有反思的循环是重复。缺哪一环,循环都会退化成白转圈——所以要算清每一环的调用账,也要算清缺一环的浪费账。
上一张卡片把三件套讲清楚了,其中「计划」这一步要把任务拆开。那——拆得更细,会带来什么?
因为拆得越细、分支越多,可能路径按「分支数 b 的深度 d 次方」(b^d)爆炸,tokens(即「模型处理的文字最小单位」)成本跟着涨;拆得太粗,又等于没拆、计划里没有可执行的信息。就像导航:只给「去上海」没用,给「每个路口怎么打方向盘」又太啰嗦。所以先算清搜索空间,再定粒度。
| 分支数 b | 深度 d | 可能路径 b^d |
|---|---|---|
| 3 | 3 | 3³ = 27 |
| 4 | 3 | 4³ = 64 |
| 5 | 3 | 5³ = 125 |
| 5 | 4 | 5⁴ = 625 |
| 粒度 | 步数 | 问题 |
|---|---|---|
| 太粗 | 2–3 步 | 计划本身没信息量 |
| 适中 | 5–9 步 | 每步可独立验证 |
| 太细 | 20 步以上 | 节点爆炸、context 塞满 |
| 方案 | 每步 token | 总 token |
|---|---|---|
| 拆成 10 步 | 2,000 | 20,000 |
| 拆成 20 步 | 2,000 | 40,000 |
分解粒度的判据是「每一步能否被独立验证」:可验证是下限,成本是上限。拆得越细,路径数按 b^d 涨、token 也跟着涨——粒度要算清,不是越细越好。
上一张卡片说分解粒度要算清;而让模型自己「先展开几条候选再挑」,正是把粒度落到搜索上的做法。为什么「先想几个方案再选」比「一条路走到黑」好?
因为一条链是从左到右写下去的,开头错了后面再对也白搭;树搜索允许模型在中间停下、评估这一步有没有希望、没希望就回溯。就像写方案:先列 3 个提纲,比闷头写 30 页更容易发现「这个大方向不对」。所以先看搜索空间,再算它值多少 token。
| 方法 | Game of 24 成功率 |
|---|---|
| CoT(单链) | 4% |
| ToT(b = 1,每步只展开 1 条) | 45% |
| ToT(b = 5,每步留 5 条) | 74% |
| 项 | 数值 |
|---|---|
| 分支数 b | 5 |
| 搜索步数 T | 3 |
| 被评估的中间想法(量级) | b × T = 5 × 3 = 15 |
| 方法 | 相对推理次数 | 成功率 |
|---|---|---|
| CoT | 1× | 4% |
| ToT(b = 5) | 明显更高(多次前向) | 74% |
树搜索的有效性来自「结构化的探索」:允许模型在中间评估、回溯,而不是一条链走到黑。ToT 的 4%→74% 是真的,但它用 token 换来的——愿不愿付账,决定了该不该把推理拆成树。
上一张卡片讲了「先分支再选路」,而选完之后还得看结果。反思为什么能把成绩抬上去?它又贵在哪?
因为反思把「这次错在哪、下次怎么改」写成一句话,放进下一轮的 context,等于不改权重就换了一次策略。就像导航发现前方堵车后,改用一句「绕开那段路」重新规划,而不是原路再开一遍。所以先看收益数字,再算它的账单。
| 方法 | HumanEval pass@1 |
|---|---|
| GPT-4 单次 | 80% |
| Reflexion(带语言反馈重试) | 91% |
| 差值 | 91 − 80 = 11 个百分点 |
| 项 | 数值 |
|---|---|
| 最多试错轮数(示意:本课假设,论文按任务设不同预算) | 5 |
| 每轮新增 | 1 次反思 + 1 次重试 |
| 反思长期保留 | 滑动窗口最近 3–5 条(示意) |
| 项 | 计算 |
|---|---|
| 失败率(GPT-4) | 100% − 80% = 20% |
| 失败率(Reflexion) | 100% − 91% = 9% |
| 失败率降到 | 9 ÷ 20 = 0.45(少了约一半失败) |
反思是一种「便宜」的强化学习:只动上下文、不动权重。它用 +11 个百分点(80%→91%)证明了价值,但要清楚账单是「多轮试错 + 反思文本本身占上下文」。
上一张卡片看到反思能涨分,但它的前提是「反思真的带来新信息」。反思什么时候没用,甚至有害?
因为当模型自己判断不了对错、又没有外部信号时,反思只会自我确认或反复改同一处——空转还多烧 tokens。就像考试时趴桌上反复检查同一道题:不改草稿,只把卷面抄得更工整。所以先算清空转的账,再定反思该停在哪。
直觉上更自然的做法是让模型自查自纠、不加任何外部信号;Huang 等的实测显示这条路会掉分——调用从 1 次加到 5 次,GSM8K 正确率反而从 95.5 降到 89.0。所以反思的前提不是「多想几遍」,而是「这一轮多了什么新信息」。
| 设置(论文报告) | 调用次数 | GSM8K 正确率 |
|---|---|---|
| GPT-4 标准提示 | 1 | 95.5 |
| 自纠第 1 轮 | 3 | 91.5 |
| 自纠第 2 轮 | 5 | 89.0 |
| 模式 | 机制 | 后果 |
|---|---|---|
| 自我确认 | 模型认定自己没错 | 可能把对的改成错的 |
| 反复改同一处 | 没有新信息,只换措辞 | 答案不变、白烧 token |
| 空转 | 无终止条件地重试 | 调用越多越差 |
| 情形 | 调用次数 |
|---|---|
| 不反思,1 次作答 | 1 |
| 反思 3 轮,答案不变 | 1 + 3 = 4 次 |
| 浪费 | 多出的 3 次(约 3 ÷ 4 = 75%) |
本课收口:反思的价值不在「多想几遍」,而在「引入新信息、换掉旧策略」。没有外部信号、只改同一处的反思是空转——判断反思有没有用,先问「这一轮比上一轮多了什么新信息」。下一课我们把视线从「单个 Agent 怎么想」移到「多个 Agent 怎么协作」,讲多智能体与协议。