Notes

Agent 核心能力 ③:Planning(规划能力)

摘要:工具让 Agent 有“手脚”,记忆让它能“长期工作”,规划让它能处理 复杂、多步、会出错 的任务。Planning 的本质是:把“一句话需求”变成可执行的步骤,并在执行中持续修正。


1. 为什么需要 Planning

没有 planning 的 LLM 往往会:

  • 直接输出一个看似完整但不可执行的答案
  • 遇到错误时卡住或胡编
  • 无法把大任务拆成可验证的小步骤

Planning 的目标:

  • 可分解:把复杂任务拆成小步
  • 可验证:每步都有观测结果(observation)
  • 可恢复:出错时能调整策略而不是重来

2. 三种经典模式

2.1 ReAct(Reason + Act)

循环结构:

  • Thought:我该做什么
  • Act:调用哪个工具
  • Observation:工具返回了什么
  • 再 Thought...

它适合:

  • 信息不确定、需要边查边做
  • 工具链比较长(搜索 -> 打开 -> 再搜索 -> 再打开)

最小伪代码:

for (step = 0; step < maxSteps; step++) {
  const msg = await llm(messages, tools)
  if (!msg.tool_calls) return msg.content
  const obs = await runTools(msg.tool_calls)
  messages.push(msg, obs)
}
throw new Error("maxSteps exceeded")

工程要点:

  • 你要把每次 Observation 清晰喂回模型(别给一坨日志)
  • 必须设置 maxSteps 防止死循环

2.2 Plan-and-Solve(先计划,再执行)

结构:

  1. 先让模型输出计划(Plan)
  2. 再逐步执行计划(Execute)

它适合:

  • 任务边界清晰(例如“实现一个功能并改 3 个文件”)
  • 你希望对过程可控、可审计

推荐的计划格式:

  • Step 1:定位文件与相关代码位置(search + read)
  • Step 2:提出修改方案
  • Step 3:应用补丁
  • Step 4:回读自检

执行策略:

  • 每步执行后都把结果回传
  • 如果某步失败,允许模型“重写计划”或“只修正当前步”

2.3 Reflection(反思/自我修正)

Reflection 用来处理:

  • 工具调用失败
  • 输出不符合格式
  • 修改引入 bug

常见做法:

  • 当出现 error observation 时,追加一个“反思提示”
  • 让模型输出:失败原因、下一次行动、避免重犯的规则

示例反思 prompt:

你刚才的操作失败了。请输出:
1) 失败原因(基于 observation,不要猜)
2) 下一步最小修正动作
3) 为避免重复失败,需要加入的约束

3. 规划的护栏(让它能在生产跑)

3.1 步数与预算

  • maxSteps
  • maxToolCalls
  • maxTokens
  • 成本预算(例如超过 1 元就停止并请求用户确认)

3.2 任务分级

把任务拆成:

  • low-risk:只读、只总结(自动执行)
  • medium-risk:写文件但可回滚(自动 + 强自检)
  • high-risk:删库/发邮件/生产发布(必须人工确认)

3.3 输出可验证

让模型输出“可验证”的中间产物:

  • 文件路径
  • 行号范围
  • patch/diff
  • 执行命令

不要只要“我已经完成了”。


4. 一个可复用的 Agent Prompt(规划版)

你可以把这段放到 system prompt(按你的项目调整):

你是一个可执行的工程 Agent。
工作方式:
- 先给出 3~6 步计划(每步要可用工具验证)
- 按步骤执行:需要信息时必须调用工具,不允许凭空猜
- 每次写文件前先读文件;写完后必须回读自检
- 遇到错误先反思,再提出最小修正动作
- 如果超过 8 步仍未完成,停止并汇报阻塞点

5. 下一步

到这里,第二阶段(Tools / Memory / Planning)的核心概念齐了。 接下来进入第三阶段:RAG。 我们会从“向量库与 embedding”开始,把文档外挂成 Agent 的知识库。

cd ..