跳到主要内容

智能体规划模块:隐藏的架构缝隙

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数智能体系统在构建时都基于一个隐含的架构假设:LLM 在同一次推理调用中同时处理规划和执行。要求它完成一个包含十个步骤的任务,模型会决定做什么、去执行、检查结果、再决定下一步做什么——这一切都在一个连续的 ReAct 循环中完成。这看起来很优雅。但在实际工作负载下,它会以一种难以诊断的方式崩溃,因为其失败模式看起来更像是模型质量问题,而非设计问题。

智能体规划模块——即纯粹负责任务拆解、依赖建模和排序的组件——是大多数从业者都会跳过的接缝。只有当事情变得困难到无法忽视时,它才会显现出来。

为什么单体智能体在大规模应用时会失败

问题不在于 LLM 不擅长规划,而在于分步贪婪推理(step-wise greedy reasoning)在数学上与长程规划是不兼容的。单体智能体在每一步都选择局部最合理的下一个动作。这是一种贪婪策略,而贪婪策略已被证明在处理多步问题时并非最优——这种负面影响并非偶尔发生,而是以几何倍数叠加。

2026 年的一项研究将其正式化:在多跳问答基准测试中,贪婪推理智能体选择的短视动作在 55.6% 的情况下于第一个决策点就导致整个任务偏离轨道。浅层任务的准确率维持在 47% 左右;而在长程任务中,准确率接近于零。更宽的集束搜索(beam search)反而让情况变得更糟,将陷阱选择率推高至 71.9%。一旦智能体走错第一步,在贪婪策略下的恢复概率仅为 5% 左右。相比之下,即使是带有浅层预瞻(lookahead)的方法,恢复概率也会跃升至近 30%。

但还有第二个失败因素会加剧第一个:错误自调节(error self-conditioning)。当 LLM 在任务早期犯错时,它会随之将该错误视为事实。这个错误变成了上下文的一部分,影响随后的每一次推理调用。在重复执行任务的基准测试中发现,拥有数千亿参数的前沿模型在简单的顺序任务中,其准确率在 15 个轮次内就会降至 50% 以下。这种退化并非渐进的,而是随着错误历史的累积而加速。

而在这两者之下是上下文腐烂(context rot)。LLM 处理上下文窗口的方式并非均匀的。模型对第 10,000 个令牌的关注度与第 100 个令牌不同。随着单体智能体在数十个步骤中积累工具响应、观察历史和中间推理,可用于新决策的有效上下文会逐渐萎缩。针对这一现象的研究发现,即使是单一的干扰项也会显著降低准确率,且这种影响会随着上下文长度的增加而复合——甚至影响到最大的前沿模型。实际塑造模型行为的有效上下文可能只是标称窗口的一小部分。

将这三种失败——贪婪短视、错误自调节和上下文腐烂——结合在一起,你就会得到一个随着任务复杂度增加而可预见地退化的系统。在最近发布的最全面的长程规划基准测试之一中,表现最好的前沿模型得分仅为 0.343(总分 1.0)。所有受测模型的平均得分仅为 0.232。这些并非极端情况,而是当前行业的最前沿水平。

架构层面的修复:将规划与执行分离

尽管实现起来并不容易,但核心见解非常直接:规划和执行是认知上截然不同的操作,不应共享同一次推理调用。

规划器(Planner)接收高层任务并生成结构化的多步拆解。它负责推理目标、约束、步骤间的依赖关系以及执行顺序。它不执行任何操作。执行器(Executor)则从该计划中提取单个步骤,并将其转化为具体的工具调用。它不需要思考整个问题——它只需要完成一个规格明确的工作单元。

这反映了贯穿系统工程的关注点分离原则。执行器可以是一个更小、更便宜的模型,甚至是确定性的代码。它不承担整个任务的认知负担;它只需要步骤级的上下文和步骤级的工具访问。规划器是一个独立的、较慢的推理调用,它在前期或关键检查点运行,而不是在每一步都运行。

这种分离带来的实际影响是可衡量的。与 ReAct 风格的循环相比,预先规划所有工具调用并使用变量替换(即后续步骤通过名称引用早期输出,而不是重新阅读完整的观察历史)的架构,可减少约 65% 的令牌消耗,并带来显著的准确率提升。执行器永远不会看到臃肿的观察历史;它将 $E1$E2 视为输入,并产出 $E3 作为输出。上下文腐烂从结构上得到了预防。

当规划器生成依赖图而非扁平的顺序列表时,会出现进一步的提升:独立的任务可以并发运行。执行三个独立查找的顺序智能体只能一个接一个地执行。而具备任务调度功能的图形感知执行器会并行运行它们,仅在输入可用后才将结果代入依赖步骤。在生产基准测试中,与顺序 ReAct 风格的执行相比,这种方法使延迟缩短了 3-4 倍,成本降低了 6 倍,准确率提升了约 9%。

基于图的规划:不仅仅是优化

从有序列表向依赖图的转变不仅仅是性能上的提升——它代表了一种不同的正确性模型。

扁平的编号计划暗示了一种实际上可能并不存在的顺序。彼此独立的步骤被意外地序列化了。那些输出结果确实依赖于前序步骤的任务,虽然在计划中可能顺序正确,但这种依赖关系并没有编码在系统可以检查或强制执行的任何地方。

有向无环图(DAG)使依赖关系显性化。每个任务节点都指定了其工具、参数以及它所依赖的任务 ID 列表。任务调度器——本质上是一个带有并行调度的拓扑排序——在任务的依赖项得到满足后立即运行该任务。没有依赖项的任务会立即并发运行。处理第 3 步的执行器接收到的是已经解析好的 $E1$E2;它不需要思考这些值是什么或来自哪里。

在实践中,这看起来像是规划器输出的结构化内容:

任务 1: search("法国首都") → $E1 [依赖: 无]
任务 2: search("德国首都") → $E2 [依赖: 无]
任务 3: compare($E1, $E2, question="哪个更古老?") [依赖: 1, 2]
加载中…
References:Let's stay in touch and Follow me for more thoughts and updates