规划:Agent的核心能力
AI Agent与聊天机器人的本质区别在于规划能力——将复杂目标分解为可执行步骤并动态调整的能力。从简单的ReAct循环到复杂的树搜索规划,Agent规划算法经历了快速演进。
ReAct:推理与行动的交错
基本循环
ReAct(Reasoning + Acting)是Agent规划的基石,核心思想是交错推理和行动:
Thought: 用户要查北京天气,我需要调用天气API
Action: search_weather(city="北京")
Observation: 北京今天晴,25°C
Thought: 获取到天气信息,可以回答用户了
Answer: 北京今天天气晴朗,气温25°C,适合外出活动。
实现细节
class ReActAgent:
def __init__(self, llm, tools, max_steps=10):
self.llm = llm
self.tools = tools
self.max_steps = max_steps
def run(self, task):
trajectory = []
for step in range(self.max_steps):
# 生成下一步思考和行为
prompt = self._build_prompt(task, trajectory)
response = self.llm.generate(prompt)
thought, action = self._parse(response)
trajectory.append({"thought": thought, "action": action})
if action["type"] == "finish":
return action["answer"]
# 执行工具
if action["type"] == "tool":
result = self.tools[action["name"]](**action["params"])
trajectory.append({"observation": result})
return "达到最大步数限制"
def _build_prompt(self, task, trajectory):
prompt = f"""任务:{task}
可用工具:{list(self.tools.keys())}
历史:
"""
for item in trajectory:
if "thought" in item:
prompt += f"Thought: {item['thought']}\n"
prompt += f"Action: {item['action']}\n"
elif "observation" in item:
prompt += f"Observation: {item['observation']}\n"
prompt += "Thought:"
return prompt
ReAct的局限
- 无记忆反馈:失败的经验不会影响后续尝试
- 线性思维:无法回溯到之前的选择点尝试其他路径
- 容易陷入循环:在复杂任务中反复尝试相同的失败方案
Reflexion:从失败中学习
核心改进
Reflexion在ReAct基础上增加了自我反思机制。当任务执行失败时,Agent会生成反思并存储到长期记忆中:
class ReflexionAgent(ReActAgent):
def __init__(self, llm, tools, max_steps=10, max_trials=3):
super().__init__(llm, tools, max_steps)
self.max_trials = max_trials
self.reflections = []
def run(self, task):
for trial in range(self.max_trials):
result = super().run(task)
if self._is_success(result):
return result
# 生成反思
reflection = self._reflect(task, self.trajectory, result)
self.reflections.append(reflection)
# 带着反思重新尝试
task_context = f"""
任务:{task}
过去的尝试和反思:
{self.reflections[-1]}
避免重复之前的错误。
"""
task = task_context
return result
def _reflect(self, task, trajectory, result):
prompt = f"""分析以下失败的执行过程,总结经验教训:
任务:{task}
执行过程:{trajectory}
结果:{result}(失败)
请反思:
1. 哪一步出了问题?
2. 为什么会出错?
3. 下次应该怎么避免?
"""
return self.llm.generate(prompt)
反思的效果
在HotpotQA多跳推理任务上:
- ReAct:成功率48%
- Reflexion(3次尝试):成功率65%
- 反思带来的提升:+17%
LATS:树搜索规划
核心思想
Language Agent Tree Search(LATS)将Agent规划建模为蒙特卡洛树搜索(MCTS):
根节点(初始状态)
/ | \
子节点A 子节点B 子节点C
/ \ | |
A1 A2 B1 C1
|
A11
实现架构
class LATSAgent:
def __init__(self, llm, tools, n_expansions=5, depth_limit=5):
self.llm = llm
self.tools = tools
self.n_expansions = n_expansions
self.depth_limit = depth_limit
def run(self, task):
root = StateNode(task=task, state=None, parent=None)
for _ in range(self.depth_limit):
# 1. 选择:UCB选择最有前景的节点
node = self._select(root)
# 2. 扩展:生成可能的行动
children = self._expand(node)
# 3. 评估:用LLM评估每个子节点的价值
for child in children:
child.value = self._evaluate(child)
# 4. 模拟:快速估算该路径的最终收益
for child in children:
child.reward = self._simulate(child)
# 5. 回溯:更新路径上所有节点的值
self._backpropagate(children)
# 检查是否找到解
best = max(children, key=lambda c: c.value)
if best.is_terminal and best.is_success:
return self._extract_path(best)
# 返回最优路径
return self._extract_best_path(root)
def _expand(self, node):
"""生成多个可能的下一步行动"""
prompt = f"""当前状态:{node.state}
任务:{node.task}
历史:{node.get_path()}
生成{self.n_expansions}个不同的下一步行动方案:
"""
responses = self.llm.generate_multiple(prompt, n=self.n_expansions)
return [StateNode(
task=node.task,
state=self._execute(r),
parent=node,
action=r
) for r in responses]
def _evaluate(self, node):
"""用LLM评估节点价值"""
prompt = f"""评估当前状态距离完成任务的距离:
任务:{node.task}
当前状态:{node.state}
已完成步骤:{node.get_path()}
评分(0-10):"""
return float(self.llm.generate(prompt))
LATS的优势
在复杂推理任务上,LATS显著优于ReAct和Reflexion:
| 方法 | HotpotQA | ALFWorld | WebShop |
|---|---|---|---|
| ReAct | 48% | 65% | 55% |
| Reflexion | 65% | 75% | 62% |
| LATS | 72% | 82% | 70% |
代价是计算开销大——每个决策点需要多次LLM调用。
Plan-and-Execute:先规划后执行
分离规划与执行
与前述方法的交错式规划不同,Plan-and-Execute先生成完整计划再执行:
class PlanExecuteAgent:
def __init__(self, planner, executor):
self.planner = planner
self.executor = executor
def run(self, task):
# 1. 生成初始计划
plan = self.planner.generate_plan(task)
while not plan.is_complete():
# 2. 执行下一步
step = plan.current_step()
result = self.executor.execute(step)
# 3. 评估是否需要重新规划
if self._needs_replan(task, plan, result):
plan = self.planner.replan(task, plan, result)
else:
plan.advance()
return plan.get_final_result()
动态重规划
def needs_replan(self, task, plan, result):
# 检测执行结果是否与预期不符
if not result.success:
return True
if result.side_effects:
return True
# 检测剩余步骤是否仍然可行
remaining = plan.remaining_steps()
feasibility = self.llm.evaluate(
f"给定当前状态{result.state},以下步骤是否可行:{remaining}"
)
return not feasibility
规划能力的评估
规划质量评估框架
class PlanningEvaluator:
def evaluate(self, task, plan, execution_result):
return {
"completeness": self._completeness(task, plan),
# 计划是否覆盖了任务的所有方面
"correctness": self._correctness(plan),
# 计划的逻辑是否正确
"efficiency": self._efficiency(plan, execution_result),
# 是否存在冗余或可合并的步骤
"adaptability": self._adaptability(plan, execution_result),
# 遇到意外时的调整能力
"granularity": self._granularity(task, plan),
# 步骤粒度是否合适——太粗无法执行,太细浪费时间
}
实践建议
选择规划方法的决策树
任务步骤 < 5?
→ ReAct(简单高效)
任务步骤 5-15?
→ Plan-and-Execute(先规划再执行)
任务步骤 > 15 或有多条可能路径?
→ LATS(树搜索)
任务需要多轮尝试?
→ Reflexion(从失败中学习)
结语
规划能力是Agent从"工具使用者"到"问题解决者"的关键跃升。当前最好的Agent在简单任务上已接近人类水平,但在需要深度推理和创造性规划的任务上仍有差距。随着推理时计算扩展技术的发展——特别是类似o1的隐式推理能力——Agent的规划能力将迎来下一个突破。