Agent 的规划能力是怎么实现的?

进阶原理实践约 6 分钟读完

一句话回答

规划就是把目标拆成可执行的步骤,并在执行中根据结果调整。常见做法有两类:先规划后执行(Plan-and-Execute),先生成完整计划再逐步执行,遇到变化时重新规划;边做边规划(如 ReAct),每一步只决定下一步。实践中常把两者结合:先列粗粒度的计划,执行中按结果修正。长任务里要把计划写成待办清单并持续更新,防止模型迷失;失败后让模型反思原因再重试(Reflexion 的思路),在有测试结果、报错信息这类外部反馈时最有效。

详细解析

两种规划方式

边做边规划(ReAct) 先规划后执行(Plan-and-Execute)
过程 每一步根据当前结果决定下一步 先生成完整步骤,再逐步执行
优点 灵活,能及时利用新信息 有全局视角;计划可以先给用户审核;具体步骤可以交给更便宜的模型执行
缺点 只看眼前,容易绕路或跑偏 计划基于不完整的信息,情况变化时容易僵化
适合 步骤少、探索性强的任务 步骤多、结构相对清楚的任务
文本
Plan-and-Execute:
目标 → 规划器生成步骤 [1, 2, 3, 4]
     → 执行器完成步骤 1(内部可以是一个小的 ReAct 循环)
     → 重新规划:根据结果更新剩余步骤,或判断任务已经完成
     → 执行下一步 …… → 汇总结果

根据执行结果重新规划

计划不是一次性的。需要重新规划的情况:

  • 某一步失败了,比如接口报错、找不到预期的文件
  • 执行结果推翻了计划的前提,比如原以为是前端问题,日志却显示是数据库超时
  • 发现了更好的路径,或者部分步骤已经不需要了

重新规划时,把目标、已完成的步骤和结果、剩余计划一起交给模型,让它输出更新后的剩余计划。

待办清单:让计划始终留在视野里

长任务中,最初的计划会被大量工具结果挤到上下文的中间,模型容易忘记做到哪了、还剩什么。常见做法是给模型一个维护待办清单的工具,或者让它在文件里维护清单:

  • 开始复杂任务时先列出步骤
  • 每完成或调整一步就更新清单,标记状态
  • 每次更新后,最新的清单会出现在上下文的末尾附近,相当于不断提醒模型当前的目标和进度

编程 Agent 处理多文件修改这类任务时,常用这种方式。

反思和自我纠错

Reflexion 的思路是:任务失败后,让模型根据反馈写一段反思,说明哪里做错了、下次应该怎么做;把反思保存下来,下次尝试时放进上下文。

  • 有外部反馈时最有效:测试没通过、编译报错、接口返回错误,模型能据此找到真正的原因
  • 只靠模型自我评价时效果不稳定:它可能找不出自己的错,甚至把对的改错
  • 反思和重试的次数要有上限,避免在同一个问题上无限循环

规划过细或过长的问题

  • 过细:拆出几十个琐碎步骤,每一步都要调用一次模型,成本高,计划也更容易和实际脱节
  • 过长:后面的步骤建立在前面还没验证的假设上,越往后越不可靠
  • 建议:顶层计划保持粗粒度,执行到某一步时再细化;每一步写清"怎样算完成",便于验证

代码示例

一个维护待办清单的工具(通用格式,state 是当前会话的状态):

TypeScript
const updateTodos = {
  name: 'update_todos',
  description:
    '维护当前任务的待办清单。开始多步骤任务时先列出步骤;每完成、新增或调整一步时调用,传入完整的最新清单。同一时间只有一项是 in_progress。',
  parameters: {
    type: 'object',
    properties: {
      todos: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            content: { type: 'string', description: '这一步要做什么,以及怎样算完成' },
            status: { type: 'string', enum: ['pending', 'in_progress', 'done'] },
          },
          required: ['content', 'status'],
        },
      },
    },
    required: ['todos'],
  },
  async execute({ todos }: { todos: { content: string; status: string }[] }) {
    state.todos = todos // 保存到会话状态,前端也可以据此展示进度
    return todos.map((t) => `[${t.status}] ${t.content}`).join('\n')
  },
}

面试官可能追问

Plan-and-Execute 能省钱吗?

有可能。规划和重新规划用能力强的模型,具体步骤交给更便宜的模型或固定代码,省掉了每一步都让大模型从头思考的开销。但如果频繁重新规划,调用次数反而更多。是否省钱要用真实任务测一下。

计划要不要先给用户确认?

长任务、高风险的任务建议要:用户在执行前就能发现方向错误,这时纠正的代价最低。不少编程 Agent 都有"先出方案,确认后再动手"的模式。简单任务没必要,多一次交互反而拖慢速度。

执行中发现情况和计划不符,模型却不调整,怎么办?

在系统提示里明确要求"发现前提不成立时先更新计划";每完成一步,让模型对照目标和清单检查一次进度;再用规则兜底,比如同一步骤失败多次、步数超出预期时,强制触发重新规划。路径本身能预先确定的部分,干脆用代码固定下来,见 工作流和 Agent 怎么选。

易错点

  • 认为计划越详细越好。过细的计划成本高,也更容易过时
  • 生成计划后就不再更新,执行结果和计划脱节
  • 把"反思"当万能药。没有外部反馈的自我反思,可能越改越错

AI 模拟面试官

用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮

登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录

这道题你掌握了吗?

选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。

学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。