引言
在前面的文章中,我们分别探讨了AI Agent的响应生成(第33篇)、对话管理(第34篇)、工具调用(第35篇)和记忆系统(第36篇)。如果说记忆系统解决了AI Agent"记什么"的问题,工具调用解决了"怎么做"的问题,对话管理解决了"怎么说"的问题,响应生成解决了"说什么"的问题,那么还有一个更核心的问题需要回答:在行动之前,Agent在想什么?
规划系统(Planning System)是AI Agent的"大脑皮层",它负责将用户的模糊意图转化为可执行的行动计划,处理复杂任务的分解与编排,并在执行过程中动态调整策略。本文将深入解析AI Agent规划系统的完整工程实践。
一、规划系统的定位与核心价值
规划系统是AI Agent四大核心子系统(感知、推理、执行、记忆)中推理层的具体实现。它的核心使命是:
- 意图转译:将用户模糊的自然语言请求分解为可操作的步骤序列
- 策略选择:在面对多种可能的执行路径时,选择最优方案
- 资源编排:合理安排工具调用顺序,处理并行与串行的依赖关系
- 异常恢复:当某一步失败时,动态重规划并选择替代方案
在现代基于LLM的AI Agent中,规划不再依赖预先定义的规则库,而是利用大语言的推理能力进行实时、灵活、上下文感知的决策。
二、规划系统的理论基础
AI Agent的规划系统虽以LLM为引擎,但其设计思想深受经典AI规划理论的影响:
| 规划范式 | 核心思想 | 在LLM Agent中的映射 |
|---|---|---|
| STRIPS | 将行动表示为前提条件和效果的状态转移 | LLM理解工具的前置条件和输出 |
| HTN | 层次化任务分解,将复杂任务递归拆解为原子操作 | Plan-and-Execute中的子任务拆分 |
| PDDL | 用形式化语言描述规划问题 | 结构化Prompt中的任务描述格式 |
| MDP | 马尔可夫决策过程,状态-动作-奖励的序列优化 | ReAct中的行动-观察-奖励循环 |
经典规划算法强调精确的形式化建模和可证明的正确性;而基于LLM的规划则更强调灵活性、泛化能力和对开放域问题的适应能力。两者在工程实践中正走向融合。
三、基于LLM的规划范式:三大主流架构
3.1 CoT(Chain-of-Thought)规划
最基础的规划范式,通过在Prompt中引导模型"一步一步思考",让LLM自动生成推理链条。其形式如下:
用户请求:帮我订一张明天去上海的机票,价格不超过2000元
思考过程:
1. 首先需要确定出发城市、到达城市、出行日期
2. 然后调用航班搜索工具,传入参数
3. 查看搜索结果,筛选符合条件的航班
4. 询问用户确认选择
5. 调用订票工具完成预订
行动:询问用户出发城市
CoT规划实现简单,适合推理步骤少(不超过5步)、逻辑清晰的场景。其局限在于缺乏外部验证机制,推理链条一旦偏离方向难以自我纠正。
3.2 ReAct(Reasoning + Acting)规划
ReAct框架将推理与行动交替执行,每个思考步骤后紧跟一个行动,行动的观察结果反馈到下一步思考中:
Thought 1: 用户想知道北京的天气,我需要查询天气预报工具
Action: call_weather("北京")
Observation: 北京今日晴,最高温度28°C,最低温度15°C
Thought 2: 已获取到天气信息,其中温度信息完整但缺少空气质量
Action: call_air_quality("北京")
Observation: 北京空气质量指数AQI为85,良
Thought 3: 已有完整信息,可以回答用户了
Final Answer: 北京今天晴,温度15-28°C,空气质量良
ReAct的核心优势是观察闭环——每一步行动的真实结果都会修正后续推理,避免了"空想"。这使它成为构建可靠生产级Agent的首选范式。
3.3 Plan-and-Execute(规划后执行)
对于复杂任务(需要10+步骤),Plan-and-Execute采用两阶段策略:先制定完整计划,再逐步执行:
=== 规划阶段 ===
完整计划:
1. [调研] 搜索目标公司近3年的财务报告
2. [调研] 搜索同行业竞争对手数据
3. [分析] 对比营收增长率、利润率、市场份额
4. [分析] 评估技术护城河与团队背景
5. [生成] 输出结构化投资分析报告
=== 执行阶段 ===
Step 1 执行: 搜索目标公司财务报告
--> 完成,获取3份年报数据
Step 2 执行: 搜索竞争对手数据
--> 完成,获取5家竞对公司数据
Step 3 执行: 对比分析
--> 完成,生成对比表格
Step 4 执行: 评估护城河(发现需要补充数据)
--> 触发更新计划
Step 5 执行: 输出报告
--> 完成
Plan-and-Execute的优势在于全局视野——Agent在行动前就对整体任务有清晰认识,执行过程中也可以根据实际情况动态调整计划。
四、分层规划架构设计
成熟的AI Agent通常采用三层规划架构,从宏观到微观逐层细化:
+-------------------------------------------------+
| 战略目标层(Strategic Level) |
| 为用户完成年度税务申报准备 |
| 输出:Goal Objectives(目标列表) |
+-------------------------------------------------+
| 战术计划层(Tactical Level) |
| 收集收入凭证、整理抵扣项目、填写申报表、提交 |
| 输出:Task Graph(任务依赖图) |
+-------------------------------------------------+
| 原子执行层(Atomic Level) |
| 打开PDF、提取字段、调用计算工具、写入表格 |
| 输出:Tool Calls(工具调用序列) |
+-------------------------------------------------+
这种分层架构的价值在于:
- 关注点分离:每层只关心本层的决策逻辑,降低复杂度
- 可中断恢复:在任意层暂停和恢复,系统状态清晰可管理
- 渐进式执行:无需一次性生成所有步骤,降低Token消耗和认知负荷
五、动态重规划与异常处理
在实际执行中,规划不可能一成不变。动态重规划机制使Agent能够应对以下异常场景:
5.1 工具调用失败
场景:搜索API返回500错误
原始计划:搜索数据、分析、输出
重规划策略:重试 --> 降级到备用工具 --> 告知用户并提供替代方案
5.2 中间结果不满足预期
场景:搜索结果返回空数据
重规划策略:换关键词重搜索 --> 扩大搜索范围 --> 查询本地记忆缓存
5.3 用户需求变更
执行过程中用户修改了原始需求,Agent应暂停当前执行,评估变更影响,增量调整计划(而非从头开始),然后继续执行。
5.4 重规划的原则
- 最小改动原则:尽量保持已完成步骤的成果,只调整受影响的后继步骤
- 时效约束:重规划本身不能无限循环(设置最大重规划次数为3次)
- 降级优雅:当完美方案不可达时,提供局部最优解而非直接放弃
六、任务依赖图与执行状态机
复杂任务中各步骤间存在依赖关系,需要以有向无环图(DAG)建模:
TaskGraph:
A(收集需求) --> B(创建项目) --> C(分配资源)
|
D(开发模块) --> E(集成测试) --> F(部署上线)
^ |
G(代码审查) <------------+
(E完成后G依赖于测试结果)
基于DAG可以自动识别可并行执行的任务,提升执行效率。执行状态机为每个任务维护状态:PENDING(未开始)、READY(依赖已满足可执行)、RUNNING(执行中)、COMPLETED(成功)、FAILED(失败触发重规划)、SKIPPED(条件不符跳过)。
七、规划质量评估与安全性
7.1 可行性评估
在计划执行前,对每项操作进行评估:工具是否可用?参数是否满足前置条件?权限是否充分?预估耗时和Token消耗是否在预算内?
7.2 复杂度评估
根据任务图的节点数、深度、分支因子估算整体复杂度。超出预设阈值的任务需要拆分为多个子任务分批执行,避免上下文窗口溢出。
7.3 安全性审查
规划系统必须内置安全检查层:是否涉及不可逆操作(删除/转账/发邮件)?是否在用户授权范围内?是否可能产生副作用?这些检查确保Agent不会执行危险或超出权限的操作。
八、与记忆系统的协同
规划系统与记忆系统深度耦合:
- 历史规划复用:相似任务过往的执行方案可作为当前规划的参考起点
- 用户偏好的应用:从记忆中提取用户偏好(如用户偏好简洁输出),指导规划风格选择
- 执行经验积累:本次规划的成功/失败经验写入记忆,优化未来的规划策略
- 上下文保持:在多轮对话中,规划进度和中间结果通过记忆实现无缝衔接
这种协同使得记忆不再是被动的信息存储,而是主动驱动规划质量持续提升的核心资源。第36篇中建立的记忆系统为本文的规划能力提供了坚实的数据基础。
九、完整代码实现:Planner核心类
import uuid
from enum import Enum
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, field
class TaskStatus(Enum):
PENDING = "pending"
READY = "ready"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
SKIPPED = "skipped"
class PlanningMode(Enum):
COT = "cot"
REACT = "react"
PLAN_EXECUTE = "plan_execute"
@dataclass
class Task:
id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
name: str = ""
description: str = ""
tool: Optional[str] = None
params: Dict[str, Any] = field(default_factory=dict)
dependencies: List[str] = field(default_factory=list)
status: TaskStatus = TaskStatus.PENDING
result: Any = None
retry_count: int = 0
max_retries: int = 3
@dataclass
class Plan:
goal: str
tasks: Dict[str, Task] = field(default_factory=dict)
mode: PlanningMode = PlanningMode.REACT
context: Dict[str, Any] = field(default_factory=dict)
def add_task(self, task: Task) -> str:
self.tasks[task.id] = task
return task.id
def get_ready_tasks(self) -> List[Task]:
ready = []
for task in self.tasks.values():
if task.status != TaskStatus.PENDING:
continue
deps_met = all(
self.tasks[dep_id].status == TaskStatus.COMPLETED
for dep_id in task.dependencies
if dep_id in self.tasks
)
if deps_met:
task.status = TaskStatus.READY
ready.append(task)
return ready
def is_complete(self) -> bool:
return all(
t.status in (TaskStatus.COMPLETED, TaskStatus.SKIPPED)
for t in self.tasks.values()
)
class Planner:
"""AI Agent规划系统核心"""
def __init__(self, llm_client, tool_registry, memory_store=None):
self.llm = llm_client
self.tools = tool_registry
self.memory = memory_store
self.max_replan_attempts = 3
async def create_plan(self, user_goal: str, mode: PlanningMode = PlanningMode.REACT) -> Plan:
"""根据用户目标生成任务计划"""
plan = Plan(goal=user_goal, mode=mode)
if mode == PlanningMode.COT:
await self._plan_cot(plan)
elif mode == PlanningMode.REACT:
await self._plan_react(plan)
else:
await self._plan_and_execute(plan)
return plan
async def _plan_react(self, plan: Plan):
"""ReAct模式:交替进行推理和行动"""
context = {"goal": plan.goal, "steps_completed": [], "observations": []}
for turn in range(20):
thought = await self.llm.think(goal=plan.goal, context=context)
if thought.should_respond_to_user:
break
action = await self.llm.select_action(
thought=thought,
available_tools=self.tools.list()
)
task = Task(
name=action.tool_name,
description=thought.reasoning,
tool=action.tool_name,
params=action.parameters
)
plan.add_task(task)
observation = await self._execute_task(task, plan)
context["observations"].append(observation)
if observation.get("status") == "failed":
await self._replan(plan, context, task)
async def _execute_task(self, task: Task, plan: Plan) -> Dict:
"""执行单个任务"""
task.status = TaskStatus.RUNNING
try:
tool = self.tools.get(task.tool)
result = await tool.execute(**task.params)
task.result = result
task.status = TaskStatus.COMPLETED
return {"status": "success", "result": result}
except Exception as e:
task.status = TaskStatus.FAILED
task.retry_count += 1
return {"status": "failed", "error": str(e)}
async def _replan(self, plan: Plan, context: Dict, failed_task: Task):
"""动态重规划"""
if failed_task.retry_count >= failed_task.max_retries:
alt_task = await self._find_alternative(plan, failed_task)
if alt_task:
plan.add_task(alt_task)
else:
failed_task.status = TaskStatus.SKIPPED
else:
failed_task.status = TaskStatus.PENDING
async def execute_plan(self, plan: Plan) -> Dict[str, Any]:
"""执行完整计划"""
results = {}
while not plan.is_complete():
ready_tasks = plan.get_ready_tasks()
if not ready_tasks:
await self._resolve_deadlock(plan)
continue
for task in ready_tasks:
result = await self._execute_task(task, plan)
results[task.id] = result
return results
这段代码展示了一个完整的Planner实现,涵盖了三种规划模式、任务依赖管理、动态重规划和异常恢复机制,可以作为构建生产级AI Agent规划层的基础框架。
十、总结与方向展望
规划系统是AI Agent从"应答器"走向"执行者"的关键能力。本文完整覆盖了从理论基础到工程实现的全链路:
- CoT、ReAct、Plan-and-Execute三大主流规划范式的原理与适用场景
- 三层分层规划架构:战略目标、战术计划、原子执行
- 动态重规划机制:工具失败、结果不符、需求变更的应对策略
- 任务依赖图与执行状态机的工程建模
- 规划质量评估与安全性审查
- 规划系统与记忆系统的深度协同
- 完整的Planner核心类代码实现
至此,我们完成了AI Agent核心子系统的完整闭环:响应生成(说)、对话管理(沟通)、记忆系统(记)、规划系统(想)、工具调用(做)。它们共同构成了现代AI Agent的完整认知链条。
在后续文章中,我们将探讨AI Agent的安全与治理体系、多Agent协作架构、以及RAG增强下的知识工程实践,进一步拓展智能体的能力边界。

发表评论 取消回复