Part 4 · Agent Design Patterns 智能体设计

4.2 Planning Loop 何时循环,何时一把梭

难度 ★★★ 阅读 ~15 min 面试出现频率 高 前置 4.1 Tool Use
Core Concept 核心概念

循环的本质:用多轮换取「看到中间结果再决定」

不带循环的调用是一次性的:给出问题,模型一次生成完整答案。它的根本局限是模型必须在信息不足时就把话说完——它不知道搜索会返回什么、代码能不能跑通、数据库里有没有这条记录。

循环解决的正是这件事:让模型执行一步、看到真实结果、再决定下一步。每一轮,它掌握的信息都比上一轮多。这个「行动 → 观察 → 再决策」的结构(即 ReAct 循环的雏形),就是 agent 与普通 LLM 调用的分界线。

但循环不是免费的,代价有三个,且都随轮数放大:

循环的三重代价(自行推导)

① 延迟 ≈ 单轮延迟 × 轮数  → 8 轮 × 1.5s = 12 秒,用户全程在等
② 成本 ≈ Σ 每轮上下文(且上下文逐轮累积,非线性增长)
③ 可靠性 ≈ pn (p = 单步成功率,n = 步数)
  p=0.95, n=10 → 0.60  p=0.90, n=10 → 0.35

→ 第三条最致命:单步表现很好的 agent,长链条上会系统性崩溃

第三条值得停下来体会。95% 的单步成功率听起来很不错——但走满 10 步,端到端成功率只剩 60%。这解释了一个普遍现象:demo 里表现惊艳的 agent,一放到真实任务上就不断失败。不是模型退步了,是链条变长了。

因此 agent 设计的第一原则是:能不循环就别循环,必须循环就尽量缩短链条。每减少一步,可靠性都是乘法级的改善。

三种循环模式

① ReAct — 边想边做,每步都可调整 思考 行动 观察 灵活、能纠错;但缺乏全局视野,容易兜圈子 ② Plan-and-Execute — 先规划全局,再逐条执行 一次性规划 步1 步2 步3 全局最优、可并行、可预估成本 但计划在中途失效时难以调整 ③ Reflection — 做完之后自我批评并重做 产出 批评/检验 修订 有外部检验信号时非常有效 纯自我批评则收益有限 三者可组合:plan-and-execute 定框架,单步内用 ReAct 应对意外,关键产出后加一轮 reflection。
图 1 · 三种模式的结构与适用面。选择的依据是任务的不确定性来自哪里:步骤未知选 ReAct,步骤已知但要保证全局最优选 plan-and-execute,产出质量需要把关选 reflection。

关于 reflection 的一个重要限定

「让模型检查自己的输出并改进」听起来是免费的质量提升,但它的效果高度依赖一个条件:是否存在外部的、客观的检验信号。

有外部信号时效果显著:代码能不能编译、测试是否通过、JSON 能不能解析、SQL 有没有报错、检索结果是否为空——这些反馈是模型自己产生不了的新信息,据此修订是真正的迭代改进。

纯自我批评时收益有限:让模型「检查这段文字写得好不好」,它用的还是那套判断标准、那些知识。如果它当初能发现这个问题,它一开始就不会犯。这时的反思容易退化成换个说法重写一遍,消耗了成本却没有实质改善,有时甚至把对的改错。

设计 reflection 时先问:这一轮批评引入了什么模型原先不知道的信息?答案是「外部执行结果」「另一个模型的意见」「检索到的新材料」——值得做。答案是「让它再想想」——多半不值得。这条判断能省掉大量无效的循环。

循环必须有刹车

没有终止条件的循环在生产环境里是事故。四道闸门缺一不可:

① 最大轮数——硬上限,超出即终止并明确报告失败。不要让它「尽力而为」地无限跑下去。
② 死循环检测——检测重复的动作序列(连续三轮调用相同工具和相同参数),立即中断。这是 agent 最常见的失控形态。
③ 预算上限——累计 token 或调用成本的上限,防止单个请求烧掉不成比例的资源。
④ 失败上报——终止时要给出它做到了哪一步、卡在哪里,而不是一句「无法完成」。这既是用户体验,也是排查的关键素材。

Case Study 真实案例

ReAct:把推理和行动交错起来

ReAct: Synergizing Reasoning and Acting in Language Models (ICLR 2023)

Yao 等人指出,在此之前,模型的推理(如 chain-of-thought)与行动(如生成动作计划)基本是分开研究的两个主题。ReAct 的做法是把二者交错生成——一段推理,一个动作,一次观察,再一段推理。

论文对这种协同的解释很清晰,值得原样记住:推理轨迹帮助模型归纳、追踪和更新行动计划,并处理异常;而行动让它能与外部知识源或环境交互,获取额外信息。两者互相补足了对方的短板——纯推理会脱离现实(幻觉、错误累积),纯行动则缺乏纠偏能力。

+34%
ALFWorld 上相对模仿学习/强化学习方法的绝对成功率提升
+10%
WebShop 上的绝对成功率提升
可解释
生成类人的任务求解轨迹,比无推理轨迹的基线更易理解

在 HotpotQA 与 Fever 上,ReAct 通过与一个简单的 Wikipedia API 交互,缓解了 chain-of-thought 中普遍存在的幻觉与错误传播问题。这一点尤其值得注意:解决幻觉的手段不是更强的推理,而是让模型能去查——与 3.1 中 RAG 的思路完全一致。

条件:这些数字来自 2023 年的特定基准与当时的基线方法,不能直接外推到今天的任务。可迁移的是那个结构性洞察:推理与行动交错,比先想完再做或边做不想都更稳健——因为它让每一步的决策都建立在真实反馈之上。今天几乎所有 agent 框架的主循环,本质上都是 ReAct 的变体。

顺带一提它的局限:ReAct 是逐步贪心的,没有全局计划,因此在需要通盘权衡或可并行的任务上容易绕远路——这正是 plan-and-execute 类模式补位的地方。

来源:Yao, Zhao, Yu, Du, Shafran, Narasimhan, Cao, "ReAct: Synergizing Reasoning and Acting in Language Models", ICLR 2023. 数字与结论引自论文摘要。
Tooling Sidebar 工具层
循环实现的实操要点(会过期,正文不依赖本区块) 截至 2026-08

先手写主循环:agent 的主循环通常不到一百行——发请求、解析工具调用、执行、把结果追加回消息列表、重复。先手写一遍再决定要不要上框架,否则出问题时你会不知道该在哪一层排查(与 3.1 对 RAG 框架的建议相同)。

并行化能大幅压缩延迟:若一轮内返回多个独立的工具调用,务必并发执行(4.1)。此外 plan-and-execute 模式下,计划中互不依赖的步骤也应并行——这是把 8 轮串行压成 3 轮的主要手段。

上下文会逐轮膨胀:每一轮的工具返回都会累积进上下文,长循环下 token 成本呈超线性增长,还会撞上「lost in the middle」(3.4)。需要主动做上下文压缩,这是 4.3 的主题。

流式反馈很重要:多轮循环意味着用户要等很久。把「正在搜索…」「已找到 3 份文档,正在分析…」这类中间状态流式推给前端,能极大改善等待体验——这不是锦上添花,而是长循环 agent 的必需品。

必须记录完整轨迹:每一轮的输入、模型输出、工具调用与返回、耗时。这是排查与 4.5 轨迹评估的唯一依据。只记录最终答案的 agent 是不可调试的。

Quiz 自测

章末自测

估算题某 agent 单步成功率 92%,完成典型任务需 12 步。端到端成功率是多少?若要把它提到 80% 以上,有哪些手段、各自需要做到什么程度?

端到端 = 0.9212 ≈ 37%。近三分之二的任务会失败——尽管每一步看起来都「挺可靠」。

要达到 80%,两个方向:

① 提高单步成功率:需要 p12 ≥ 0.8,即 p ≥ 0.81/12 ≈ 98.2%。从 92% 提到 98.2% 是非常艰难的——这通常意味着换更强的模型加大量的 schema 与 prompt 打磨,且收益递减。

② 减少步数(通常更有效):需要 0.92n ≥ 0.8,即 n ≤ ln(0.8)/ln(0.92) ≈ 2.7 步。也就是说要把 12 步压到 3 步以内。

怎么压步数——这才是本题的重点:
• 用代码固化确定性流程:12 步里若有 8 步是固定顺序,就把它们写成一个组合工具,模型只在真正需要判断处介入(4.1 案例的做法)。
• 并行化:互不依赖的步骤同时执行,虽不改变乘法关系,但大幅降低延迟。
• 提高单步信息密度:一个返回完整信息的工具,胜过三个要拼装的工具。

③ 第三条路:加入检验与重试。若某步失败可被检测并重试,该步的有效成功率从 p 升到 1−(1−p)r(r 为尝试次数)。p=0.92 重试一次 → 99.4%。但前提是失败必须可检测——静默的错误答案无法重试,这也是为什么工具应尽量返回可校验的结构化结果。

结论:面对长链条 agent,「缩短链条」几乎总是比「提高单步质量」更有效,因为前者作用在指数上。

场景判断四个任务各选哪种模式?A. 把一段中文翻译成英文;B. 排查一次线上故障;C. 生成一份季度报告(需查 5 个固定数据源);D. 写一个函数并保证测试通过。

A 翻译 → 不要循环,一次调用。任务确定、无需外部信息、无中间决策。给它套 agent 循环只会增加延迟和成本,且没有任何收益。「这是不是 agent 该做的事」应该是设计的第一个问题。

B 排查故障 → ReAct。典型的高不确定性任务:下一步查什么完全取决于上一步看到了什么(日志异常 → 查该服务指标 → 发现依赖超时 → 查下游)。事先无法规划,必须边看边定。务必配好轮数上限与死循环检测——排查任务最容易陷入反复查同一个指标的循环。

C 季度报告 → Plan-and-Execute,甚至直接用代码编排。5 个数据源是固定且已知的,根本不需要模型来规划。正确做法是代码并行拉取全部数据,模型只负责最后的分析与撰写——一次调用,零循环。这是「确定性流程不该交给模型规划」的典型例子。

D 写函数 + 测试通过 → Reflection,且是它的最佳场景。因为存在客观的外部检验信号:测试跑不跑得过,不是模型说了算。循环是「写代码 → 跑测试 → 读报错 → 修改」,每一轮都引入了模型自己产生不了的新信息。注意设上限——若连续三轮测试仍不过,通常是理解偏差而非细节错误,继续循环只是烧钱,应该终止并把情况报给人。

面试题改编「什么时候不该用 agent?」

这道题考的是克制。四类明确不该用的情形:

① 流程是确定的。如果步骤固定、分支有限,那就是一个工作流,用代码写死。让模型每次重新「规划」一遍已知流程,是用不确定性替换了确定性——更慢、更贵、更容易错。agent 的价值在于处理未知,不在于执行已知。

② 延迟要求严格。多轮循环的延迟是单次调用的数倍。语音交互、实时补全这类场景,agent 的延迟结构从根上不匹配。

③ 错误代价高且不可逆。资金转移、数据删除、对外发布——这些场景需要的是确定性与审批流,而不是一个成功率 90% 多的自主循环。可以让 agent 起草,但执行必须由人确认(4.1)。

④ 链条太长而单步可靠性不够。pn 的乘法效应决定了,当任务需要十几步而单步成功率只有九成出头时,端到端成功率会低到没有产品价值。此时应该拆分任务、缩短链条,或干脆改成人机协同——而不是寄希望于「下一代模型会更好」。

加分回答:给出一个正向判断标准——agent 适合「步骤未知、需要根据中间结果决定下一步、且单步可验证」的任务。三个条件同时满足时它才是对的工具。