上一章我们聊了记忆系统——Agent怎么"记住"事。但记住只是基础,记住之后怎么做,才是Agent能不能干活的关键。
很多Agent演示看起来很酷:给它一个任务,它自己拆步骤、自己调工具、自己修正错误。但真到生产环境,"自由发挥"变成了"自由翻车"——死循环、偏题、忘了目标。
问题出在哪?没有规划,推理就是闭眼猜。
01 规划和推理,不是一回事
先说一个最常见的混淆:很多人把"规划"和"推理"当成同一件事。它们不是。
| ❌ 推理 Reasoning | ✅ 规划 Planning |
|---|---|
| "这一步该做什么?" | "整体该怎么完成?" |
| 局部的、即时的 | 全局的、前瞻的 |
| 基于当前上下文做判断 | 基于最终目标做分解 |
| 类似:走一步看一步 | 类似:看地图再出发 |
没有规划的推理,就是"应激反应"——每一步看起来都合理,但整体方向可能是错的。就像GPS只给你下一步转弯指令,但不告诉你全程路线,你走两步就迷路。
核心区别
推理回答"现在做什么",规划回答"怎么做到"。前者是执行层,后者是策略层。Agent需要两层都有,但规划的优先级更高——方向错了,推理越强跑得越偏。
02 为什么LLM天然不擅长规划
LLM是自回归模型——它只能从左到右生成token。这意味着它本质上是一个"单步预测器",不是一个"全局优化器"。
让它规划一个5步任务时,它是在生成第1步的时候,用对第2-5步的"猜测"来保证一致性。这个猜测经常不准,尤其是:
-
步骤间有依赖:第3步需要第1步的结果,但生成第1步时还没执行
-
目标约束复杂:要同时满足A、B、C三个条件,LLM容易顾此失彼
-
步骤多:超过5步的规划,LLM的准确率急剧下降
这就是为什么"让LLM自由发挥"的Agent,在简单任务上表现还行,复杂任务就开始飘。
03 规划的4种主流方法
业界不是没意识到这个问题。以下是4种主流的规划方法,各有适用场景:
方法1:单次规划(Plan-then-Execute)
最朴素的方法:先让LLM生成完整计划,再逐步执行。
plan = llm.generate_plan(task="帮我调研竞品并写报告")
for step in plan:
result = execute(step)
# 问题:如果第2步发现数据不够,计划怎么办?
优点:简单、可控、容易调试
缺点:不适应变化。执行中发现计划有问题,要么硬着头皮走,要么全盘重来
方法2:ReAct(推理+行动交替)
最流行的Agent范式:思考和行动交替进行。
while not done:
thought = llm.think(observation) # "我需要先查竞品列表"
action = llm.act(thought) # 调用search_competitors
observation = execute(action) # 得到结果
优点:灵活、能根据中间结果调整
缺点:没有全局约束,容易"跑偏"——搜索着搜索着开始研究无关话题
方法3:规划-执行-重规划(Plan-Execute-Replan)
结合前两者的优点:有全局计划,但允许中途调整。
plan = llm.generate_plan(task)
while not done:
step = plan.pop(0)
result = execute(step)
if need_replan(result):
# 根据新信息重新规划剩余步骤
remaining_plan = llm.replan(
original_goal=task,
completed=done_steps,
new_info=result
)
plan = remaining_plan
优点:兼顾全局和局部,是工程实践中最实用的方法
缺点:replan的触发条件需要仔细设计,过于频繁replan等于没有计划
⚠️ ⚠️ replan频率是个关键参数:太低→计划过时,太高→和没有计划一样。经验值:每3-5步replan一次,或在工具返回异常时触发。
方法4:树搜索(Tree of Thought / MCTS)
最"学术"的方法:把规划当成搜索问题,探索多条路径,选最优解。
优点:理论上最优,能处理多约束问题
缺点:token消耗巨大,延迟高,实践中很少用——除非你的任务真的值这个成本
方法选择指南
简单线性任务 → 单次规划 需要灵活应变 → ReAct 生产环境首选 → Plan-Execute-Replan 高价值复杂决策 → 树搜索(慎重)
04 规划最大的坑:目标漂移
目标漂移(Goal Drift)是Agent规划的头号杀手。表现:Agent开始执行任务A,中间发现有趣的B,转而去做B,最后忘了A。
听起来像个笑话?但在ReAct模式下,这是常态。原因:
-
LLM的注意力被新信息吸引:搜索结果里的"有趣"内容比原始目标更抓眼球
-
没有目标校验机制:每一步推理都是独立的,没有人问"这和原始目标还有关系吗?"
-
上下文稀释:随着对话变长,原始目标在上下文中的权重越来越低 gr
怎么对抗目标漂移?3个实战技巧:
技巧1:目标注入(Goal Injection)
不是在开头说一次目标就够了——每一步都提醒LLM原始目标是什么:
system = f"""
你的原始任务是:{original_goal}
当前进度:{completed_steps}/{total_steps}
请在思考时确认:我这一步是否服务于原始目标?
"""
技巧2:相关性检查(Relevance Check)
在执行任何工具调用之前,加一步轻量级检查:
def should_execute(action, original_goal):
check = llm.judge(
f"执行'{action}'是否有助于完成'{original_goal}'?只回答是或否"
)
return check == "是"
代价:每次判断多消耗几十个token。收益:避免浪费成百上千个token在无关操作上。
技巧3:步骤预算(Step Budget)
给Agent设定步骤上限。不是技术限制,是经济限制——超过N步还没完成,就停下来汇报当前进度,让人类决定是否继续。
MAX_STEPS = 10 # 根据任务复杂度设定
if step_count > MAX_STEPS:
return "已达到步骤上限,当前进度:..."
05 多步推理的幻觉问题
LLM做规划时有个很隐蔽的坑:它会"假装"推理。
让它规划一个5步任务,它可能写出看起来逻辑自洽的5步计划。但仔细检查会发现:第3步的输入需要第2步的输出,但第2步的输出根本不可能提供第3步需要的格式。
这不是"幻觉"(hallucination),更像是"推理幻觉"——推理过程看起来合理,但基于错误的因果假设。
| ❌ 错误示例 | ✅ 正确做法 |
|---|---|
| 步骤2: "调用API获取用户列表" | 步骤2: "调用API获取用户列表" |
| → 返回: [{name: "张三"}, ...] | 步骤2.5: "根据用户ID查询订单" |
| 步骤3: "从返回的订单数据中提取金额" | → 用步骤2的结果作为步骤2.5的输入 |
| → ❌ 步骤2没有返回订单数据! | → 确保每步的输入输出对齐 |
**怎么解决?**在规划阶段就做"输入输出对齐检查":
def validate_plan(plan):
for i in range(1, len(plan)):
# 检查步骤i的输入是否可以被步骤i-1的输出满足
input_ok = llm.judge(
f"步骤'{plan[i]}'的输入,能否由步骤'{plan[i-1]}'的输出提供?"
)
if not input_ok:
# 自动插入中间步骤或修改计划
plan = llm.fix_plan(plan, broken_step=i)
return plan
06 实战:一个可靠的Agent规划层设计
把上面的原则整合起来,一个生产可用的规划层应该长这样:
class AgentPlanner:
def __init__(self, task, max_steps=10, replan_interval=3):
self.task = task
self.max_steps = max_steps
self.replan_interval = replan_interval
self.completed = []
self.plan = self._initial_plan()
def _initial_plan(self):
# 1. 生成初始计划
plan = llm.generate_plan(self.task)
# 2. 输入输出对齐检查
plan = self._validate_io_alignment(plan)
# 3. 步骤预算校验
assert len(plan) <= self.max_steps
return plan
def next_step(self, observation):
# 目标注入:每步都带原始目标
context = {
"goal": self.task,
"completed": self.completed,
"observation": observation
}
# 相关性检查
if not self._check_relevance(observation):
return "检测结果偏离目标,正在重新对齐..."
if len(self.completed) % self.replan_interval == 0:
self.plan = self._replan(observation)
return self.plan.pop(0)
def _replan(self, new_info):
# 基于已完成步骤和新信息重新规划
remaining = llm.replan(
goal=self.task,
done=self.completed,
new_observation=new_info,
steps_left=self.max_steps - len(self.completed)
)
return self._validate_io_alignment(remaining)
07 规划层的成本账
规划不是免费的。每多一层规划,就多消耗token、增加延迟。算笔账:
无规划(纯ReAct): 每步1次LLM调用 × N步 = N次调用 总token ≈ N × 500(平均每步)
Plan-Execute-Replan: 初始规划1次 + 每步1次 + 每3步replan 1次 总token ≈ 1×1500 + N×500 + (N/3)×1000 ≈ N×833 + 1500
带相关性检查: 在Plan-Execute-Replan基础上,每步多1次轻量判断(≈100 token) 总token ≈ N×933 + 1500
看起来多了不少?但比起目标漂移导致的无效执行(可能浪费10+步),规划层的开销是值得的。
成本取舍原则
规划层的成本,取决于任务失败的成本。如果一步错就浪费大量token(如调用了付费API、修改了数据),规划层越重越好。如果每步成本很低(只是搜索),轻量规划就够。
08 推理模型:从"不擅长规划"到"规划即推理"
上面整篇文章建立在一个前提上:LLM天然不擅长规划。
这个前提正在动摇。
什么是推理模型
推理模型(reasoning model)——OpenAI的o4/GPT-5.5 Thinking、DeepSeek的R3、Qwen的QwQ-32B——的共同特征:在给出最终回答前,先做一段隐式的思维链(Chain-of-Thought)推理。
传统模型(GPT-5.1、Claude Sonnet)是"脱口而出"——收到问题,直接生成答案。
推理模型是"先想再说"——收到问题,先在内部推理几百到几千个token,然后给出答案。这段内部推理对用户不可见(OpenAI称之为"reasoning tokens"),但模型在推理过程中可以自我纠错、回溯、验证。
这和Agent规划有什么关系?关系大了。
推理模型天然更擅长规划
回到02节讲的"LLM不擅长规划的3个原因":
- 步骤间有依赖 → 推理模型在内部推理时可以模拟执行结果,提前发现依赖问题
- 目标约束复杂 → 推理模型的内部CoT可以逐一检查约束,减少遗漏
- 步骤多时准确率下降 → 推理模型的thinking token可以"延展"推理深度,虽然仍然有上限,但比直接生成强得多
实际数据:在SWE-bench(软件工程任务)上,o4的通过率是传统模型的2-3倍。这本质上是因为软件工程任务需要"先理解代码结构→制定修改计划→分步执行→验证结果",这正是规划能力的体现。
推理模型+Agent的3种融合模式
模式1:推理模型作为规划器
# 用推理模型做规划,普通模型做执行
planner = ReasoningModel("o4") # 擅长全局规划
executor = ChatModel("gpt-5.1") # 擅长快速执行
plan = planner.generate_plan(task) # o4的内部CoT会做深度规划
for step in plan:
result = executor.execute(step) # GPT-5.1快速执行单步
if need_replan:
plan = planner.replan(task, done, result)
优点:规划质量高,执行成本低。o4的reasoning token虽然贵(约$15/M input),但规划调用次数少(1-3次),执行用便宜的GPT-5.1。
缺点:规划和执行脱节——推理模型生成的计划可能假设了不存在的工具能力。
模式2:推理模型全链路
# 整个Agent循环用推理模型
while not done:
thought = GPT-5.5 Thinking.think(observation) # 内部自动做深度推理
action = GPT-5.5 Thinking.act(thought)
observation = execute(action)
优点:最简单,每一步推理模型都会自己"想清楚"再行动。
缺点:太贵了。o4每次调用的reasoning token可能消耗5K-50K tokens。一个10步的Agent任务,光reasoning就50K-500K tokens,成本7.5。加上output token,单任务成本轻松超过$10。
模式3:推理模型按需激活(推荐)
# 默认用普通模型,遇到复杂决策时切换到推理模型
class HybridAgent:
def __init__(self):
self.fast_model = ChatModel("gpt-5.1") # 日常执行
self.thinking_model = ReasoningModel("o4-mini") # 复杂决策
def plan_step(self, context):
complexity = self._assess_complexity(context)
if complexity == "simple":
return self.fast_model.think(context)
elif complexity == "moderate":
return self.thinking_model.think(context)
else: # complex
return self.thinking_model.deep_think(context) # 更多reasoning budget
def _assess_complexity(self, context):
"""评估当前决策的复杂度"""
# 简单:单步可完成,工具调用明确
# 中等:需要2-3步推理,有约束条件
# 复杂:多约束、多依赖、需要回溯
...
优点:成本可控。90%的步骤用便宜模型,只在关键决策点用推理模型。
缺点:复杂度评估本身可能不准——你怎么知道当前步骤是"简单"还是"复杂"?
实践建议:用一个简单的启发式——凡是需要replan的步骤,都用推理模型。正常执行用普通模型。这天然实现了"普通模型执行 + 推理模型兜底"。
DeepSeek R3:推理模型的性价比标杆
DeepSeek R3的特殊之处在于:它的推理能力接近o4,但成本只有o4的1/20。
- DeepSeek R3 API定价:约15/M)
- 在数学推理、代码生成等任务上,DeepSeek R3接近o4的80-90%水平
- 开源,可以本地部署(671B参数,需要多卡,但DeepSeek R3-Distill版本可以单卡跑)
对Agent规划的影响:DeepSeek R3让推理模型不再是"高端玩家专属"。以前只有高价值任务才用得起o4做规划,现在中等价值任务也可以用DeepSeek R3做推理了。
但DeepSeek R3有个坑:它的reasoning token虽然是隐式的,但API仍然计费。而且DeepSeek R3的reasoning过程有时会"跑偏"——在CoT中开始讨论无关话题,浪费大量reasoning token。需要设置max_tokens限制来控制。
推理模型的"规划陷阱"
推理模型更强了,但不是万能的。实战中有3个陷阱:
陷阱1:过度推理
推理模型倾向于"想太多"——一个3步就能搞定的任务,o4可能在内部CoT中推理了20步。这不是质量问题,是成本问题。一个简单的查询任务,用o4比用GPT-5.1贵10倍,但结果可能只好了5%。
解法:根据任务类型选择模型,不要无脑用推理模型。简单查询→GPT-5.1,复杂推理→o4/o4-mini。
陷阱2:推理与工具的断裂
推理模型在内部CoT中做了一个完美的计划,但到了实际调用工具时,可能发现:
- 工具的参数格式和推理模型假设的不一样
- 工具的返回结果和推理模型预期的不一样
- 推理模型"以为"某个工具存在,但实际没有
解法:推理模型的plan必须经过"工具可用性校验"——在执行前,检查计划中涉及的每个工具是否存在、参数是否匹配。
陷阱3:推理延迟
推理模型的thinking时间可能是普通模型的5-10倍。o4处理一个复杂问题可能需要30-60秒的思考时间。在Agent交互场景中,用户等待1分钟是很差的体验。
解法:推理模型适合后台任务和批量处理,不适合实时交互。面向用户的Agent,用推理模型做规划、普通模型做交互。
更新后的规划方法选择指南
| 任务类型 | 推理模型方案 | 普通模型方案 | 原因 |
|---|---|---|---|
| 简单线性任务 | 单次规划 | 单次规划 + 普通模型 | 不需要推理模型 |
| 灵活应变任务 | ReAct | ReAct + 推理模型按需激活 | 关键决策用推理模型 |
| 生产环境 | Plan-Execute-Replan | Plan-Execute-Replan + 混合模型 | 规划用推理模型,执行用普通模型 |
| 高价值复杂决策 | 树搜索 | 推理模型全链路 或 树搜索+推理模型 | 推理模型的CoT部分替代了树搜索 |
一句话总结:推理模型没有消除规划问题,但把"LLM不擅长规划"的天花板抬高了。以前需要复杂的规划框架来弥补LLM的不足,现在推理模型可以承担更多规划职责,框架可以更轻。但目标漂移、多步幻觉等老问题仍然需要工程手段兜底。