第6章:规划与任务分解
面对"帮我策划一场生日派对"这样的复杂任务,优秀的智能体不会一头扎进去盲目执行,而是先思考:"这个任务需要哪些步骤?"这就是规划(Planning)能力。本章将教你如何让智能体像项目经理一样有条不紊地完成任务。
6.1 什么是规划(Planning)
规划就是把大任务拆成小步骤,然后逐个完成的过程。
规划的三个关键问题:
- 要做什么 - 明确最终目标
- 怎么做 - 分解成可执行的步骤
- 何时做 - 确定步骤的执行顺序
规划 vs 无规划:
❌ 无规划(盲目执行):
用户: 帮我策划一场生日派对
AI: 好的!我推荐你去XXX餐厅...
(没有了解预算、人数、时间等关键信息)
✅ 有规划(系统思考):
用户: 帮我策划一场生日派对
AI: 好的!让我先规划一下这个任务:
步骤1:了解基本信息(预算、人数、时间)
步骤2:确定派对主题和风格
步骤3:选择场地
步骤4:安排餐饮
步骤5:准备娱乐活动
步骤6:发送邀请
让我们从步骤1开始:请问您的预算是多少?
6.2 为什么需要规划
规划的好处:
- 降低复杂度 - 把大问题变成小问题,逐个击破
- 减少错误 - 每一步都经过思考,避免遗漏关键信息
- 提高成功率 - 有计划的执行更有可能达成目标
- 便于调试 - 出问题能快速定位到具体步骤
- 支持回溯 - 某步失败可以重新规划该步骤
⚠️ 没有规划的常见问题:
- 遗漏关键步骤(忘记确认预算就推荐场地)
- 步骤顺序混乱(先发了邀请还没定时间地点)
- 重复劳动(多次询问同样的问题)
- 陷入死胡同(执行到一半发现前提条件不满足)
6.3 任务分解策略
任务分解有多种方法,我们介绍三种最常用的策略。
6.3.1 目标分解
把最终目标拆成若干子目标,每个子目标相对独立。
目标分解示例:写一份市场调研报告
写市场调研报告
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│收集资料 │ │分析数据 │ │撰写报告 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│•搜索行业│ │•数据清洗│ │•撰写摘要│
│ 新闻 │ │•统计分析│ │•正文内容│
│•查找报告│ │•制作图表│ │•结论建议│
│•采访专家│ │ │ │ │
└─────────┘ └─────────┘ └─────────┘
6.3.2 步骤分解
把子目标进一步拆成具体可执行的动作。
步骤分解示例:预订餐厅
子目标:选择并预订合适的餐厅
步骤1:询问需求
├─ 1.1 确认用餐日期和时间
├─ 1.2 确认用餐人数
├─ 1.3 确认预算范围
└─ 1.4 确认 cuisine 偏好
步骤2:搜索餐厅
├─ 2.1 调用餐厅搜索API
├─ 2.2 根据条件筛选
└─ 2.3 获取餐厅详情(评分、菜单、位置)
步骤3:推荐选择
├─ 3.1 排序候选餐厅
├─ 3.2 展示Top 3选项
└─ 3.3 解释推荐理由
步骤4:完成预订
├─ 4.1 确认用户选择
├─ 4.2 调用预订API
└─ 4.3 发送确认信息
6.3.3 层次分解
用树状结构组织任务,从抽象到具体逐层细化。
层次分解:电商订单处理系统
┌─────────────┐
│ 处理订单 │ ← 第一层:总任务
└──────┬──────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│验证订单 │ │处理库存 │ │安排物流 │ ← 第二层:子任务
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│检查用户 │ │查询库存 │ │选择快递 │
│ 信息 │ │ 数量 │ │ 公司 │ ← 第三层:具体步骤
│验证支付 │ │锁定库存 │ │生成运单 │
│ 状态 │ │更新库存 │ │通知发货 │
└─────────┘ └─────────┘ └─────────┘
6.4 规划的方法
如何让AI进行有效的规划?介绍三种主流方法。
6.4.1 Chain of Thought(思维链)
让AI一步步思考,把思考过程显式地写出来。
Chain of Thought 示例:
问题:用户想要一本关于Python编程的书,预算200元以内。
AI的思考过程:
1. 用户需要什么类型的书?
→ Python编程书
2. 有什么限制条件?
→ 预算200元以内
3. 我需要做什么?
→ a. 搜索Python编程书籍
→ b. 筛选价格≤200元的
→ c. 按评分排序
→ d. 推荐Top 3
4. 第一步做什么?
→ 调用图书搜索API,关键词"Python编程"
执行动作:[调用搜索API...]
6.4.2 Tree of Thoughts(思维树)
探索多种可能路径,选择最优方案。
Tree of Thoughts 示例:规划旅行路线
从北京到上海
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│方案A: │ │方案B: │ │方案C: │
│ 高铁 │ │ 飞机 │ │ 自驾 │
│ 4.5小时 │ │ 2.5小时 │ │ 12小时 │
│ ¥553 │ │ ¥800 │ │ ¥600 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
▼ ▼ ▼
评价:性价比 评价:最快 评价:自由度高
高,推荐! 但较贵 但耗时太长
AI决策:选择方案A(高铁),向用户推荐。
6.4.3 反思与重规划
执行中遇到问题时,重新评估并调整计划。
反思与重规划示例:
原 plan:
1. 询问用户预算 ✓
2. 询问用户时间 ✓
3. 搜索餐厅 → 执行中...
执行步骤3时发现问题:
❌ 用户所在区域没有符合预算的餐厅
反思:
- 为什么失败?预算限制太严格
- 有什么替代方案?
a) 扩大搜索范围到邻近区域
b) 建议用户稍微提高预算
c) 推荐其他类型的餐饮
重规划:
3a. 向用户说明情况
3b. 询问是否接受邻近区域或调整预算
3c. 根据用户选择重新搜索
新 plan 继续执行...
6.5 规划的表示
如何存储和展示规划?常见的表示方式有:
6.5.1 列表表示
// JSON格式表示规划
{
"task": "策划生日派对",
"steps": [
{
"id": 1,
"name": "确定预算",
"status": "completed",
"dependencies": [],
"result": "预算2000元"
},
{
"id": 2,
"name": "选择场地",
"status": "in_progress",
"dependencies": [1],
"action": "search_venues",
"parameters": { "budget": 2000 }
},
{
"id": 3,
"name": "准备餐饮",
"status": "pending",
"dependencies": [2],
"action": "arrange_catering"
},
{
"id": 4,
"name": "发送邀请",
"status": "pending",
"dependencies": [2, 3],
"action": "send_invitations"
}
]
}
6.5.2 流程图表示
用户咨询 → 理解意图 → 需要规划?
│
┌─────────┴─────────┐
│ │
是 否
│ │
▼ ▼
分解任务 直接回答
│
▼
检查依赖关系
│
▼
确定执行顺序 ──→ 生成执行计划
│
▼
执行步骤 ←────── 完成?──┐
│ │
└───────────────┘
│
▼
反思结果 ──→ 需要重规划?──┐
│ │
否 是
│ │
▼ └──────────┐
完成任务 ←─────────────────────────┘
6.6 执行与调整
规划只是第一步,更重要的是执行并根据实际情况调整。
规划执行循环:
┌─────────────────────────────────────┐
│ │
▼ │
┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ 规划 │───→│ 执行 │───→│ 观察 │ │
│ Planning│ │ Execute │ │ Observe │ │
└─────────┘ └─────────┘ └────┬────┘ │
▲ │ │
│ ▼ │
│ ┌─────────┐ │
└─────────────────────────│ 反思 │─┘
│Reflect │
└─────────┘
这个循环叫做"观察-思考-行动"循环(Observe-Reflect-Act Loop)
6.6.1 代码实现示例
class TaskPlanner {
constructor() {
this.plan = null;
this.currentStep = 0;
this.results = {};
}
// 生成规划
async createPlan(goal, context) {
const prompt = `
目标:${goal}
上下文:${JSON.stringify(context)}
请将这个目标分解成具体的执行步骤。
每个步骤包含:步骤名、需要执行的动作、依赖的前置步骤。
以JSON格式返回。
`;
this.plan = await callAI(prompt);
this.currentStep = 0;
return this.plan;
}
// 执行下一步
async executeNextStep() {
if (this.currentStep >= this.plan.steps.length) {
return { done: true, message: "所有步骤已完成" };
}
const step = this.plan.steps[this.currentStep];
// 检查依赖是否满足
const dependenciesMet = step.dependencies.every(
dep => this.results[dep]
);
if (!dependenciesMet) {
return { error: "前置步骤未完成" };
}
try {
// 执行步骤
const result = await this.executeAction(step.action, step.parameters);
// 保存结果
this.results[step.id] = result;
step.status = "completed";
this.currentStep++;
return { step: step.name, result };
} catch (error) {
step.status = "failed";
step.error = error.message;
// 触发重规划
return await this.replan(step, error);
}
}
// 重规划
async replan(failedStep, error) {
const prompt = `
步骤"${failedStep.name}"执行失败:${error.message}
当前计划:${JSON.stringify(this.plan)}
已执行结果:${JSON.stringify(this.results)}
请重新规划,提供替代方案。
`;
this.plan = await callAI(prompt);
return { replanned: true, newPlan: this.plan };
}
}
6.7 完整示例:策划生日派对
让我们实现一个能规划生日派对的智能体。
6.7.1 规划结构
目标:策划生日派对
分解树:
策划生日派对
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 预算 │ │ 场地 │ │ 餐饮 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│询问预算 │ │确定人数 │ │计算数量 │
│ │ │ │ │ │
│记录预算 │ │搜索场地 │ │选择餐品 │
│ │ │ │ │ │
└─────────┘ │对比选择 │ │下单预订 │
│ │ │ │
│确认预订 │ └─────────┘
└─────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 装饰 │ │ 活动 │ │ 邀请 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│确定主题 │ │设计游戏 │ │列出名单 │
│ │ │ │ │ │
│采购装饰 │ │准备道具 │ │制作邀请 │
│ │ │ │ │ │
└─────────┘ │安排流程 │ │发送邀请 │
│ │ │ │
└─────────┘ └─────────┘
6.7.2 完整代码
class PartyPlanner {
constructor() {
this.context = {
budget: null,
guestCount: null,
date: null,
preferences: {}
};
this.tasks = [
{ id: 'budget', name: '确定预算', done: false, fn: this.askBudget },
{ id: 'guests', name: '确认人数', done: false, fn: this.askGuestCount },
{ id: 'date', name: '选择日期', done: false, fn: this.askDate },
{ id: 'venue', name: '预订场地', done: false, fn: this.searchVenue },
{ id: 'catering', name: '安排餐饮', done: false, fn: this.arrangeCatering },
{ id: 'invite', name: '发送邀请', done: false, fn: this.sendInvites }
];
this.currentTaskIndex = 0;
}
// 主循环
async chat(userMessage) {
// 更新上下文
this.updateContext(userMessage);
// 找到下一个未完成的任务
const currentTask = this.tasks[this.currentTaskIndex];
if (!currentTask) {
return "🎉 生日派对策划完成!祝您派对愉快!";
}
// 执行任务
const response = await currentTask.fn.call(this, userMessage);
// 标记完成并前进
if (this.isTaskComplete(currentTask, userMessage)) {
currentTask.done = true;
this.currentTaskIndex++;
// 告诉用户下一步
const nextTask = this.tasks[this.currentTaskIndex];
if (nextTask) {
response += `\n\n📋 接下来:${nextTask.name}`;
}
}
return response;
}
// 显示当前进度
getProgress() {
const completed = this.tasks.filter(t => t.done).length;
const total = this.tasks.length;
const percent = Math.round(completed / total * 100);
let progress = `📊 当前进度:${percent}%\n`;
progress += `┌${'─'.repeat(20)}┐\n`;
progress += `│${'█'.repeat(completed * 20 / total)}${' '.repeat(20 - completed * 20 / total)}│\n`;
progress += `└${'─'.repeat(20)}┘\n`;
this.tasks.forEach((task, i) => {
const icon = task.done ? '✅' : (i === this.currentTaskIndex ? '⏳' : '⬜');
progress += `${icon} ${task.name}\n`;
});
return progress;
}
// 各个任务执行函数
async askBudget(message) {
if (!this.context.budget) {
return "🎂 让我们开始策划生日派对吧!\n\n首先,请问您的预算是多少?(比如:2000元)";
}
return `好的,预算${this.context.budget}元,我会根据这个预算来推荐。`;
}
async askGuestCount(message) {
if (!this.context.guestCount) {
return "请问大约有多少位客人参加?";
}
return `收到,${this.context.guestCount}位客人。`;
}
async askDate(message) {
if (!this.context.date) {
return "派对计划在哪一天举办?";
}
return `${this.context.date},记住了。`;
}
async searchVenue(message) {
// 模拟场地搜索
return `🔍 正在为您搜索适合${this.context.guestCount}人、预算内的场地...\n\n推荐场地:\n1. 星光派对馆 - 可容纳30人,费用1500元\n2. 欢乐谷餐厅 - 包间可容纳20人,费用1800元\n\n您倾向哪个?`;
}
async arrangeCatering(message) {
const perPerson = Math.floor(this.context.budget * 0.4 / this.context.guestCount);
return `🍽️ 餐饮安排:\n按预算40%用于餐饮,人均约${perPerson}元\n推荐套餐:\n- 自助餐形式\n- 包含蛋糕、饮料\n\n需要我帮您联系餐饮供应商吗?`;
}
async sendInvites(message) {
return `📧 邀请函模板已生成:\n\n"亲爱的朋友,\n诚挚邀请您参加我的生日派对!\n时间:${this.context.date}\n地点:[已预订场地]\n期待与您相聚!"\n\n您可以直接复制发送,需要我帮您通过邮件发送吗?`;
}
// 辅助方法
updateContext(message) {
// 简单提取数字作为预算
const budgetMatch = message.match(/(\d+)元?/);
if (budgetMatch && !this.context.budget) {
this.context.budget = parseInt(budgetMatch[1]);
}
const countMatch = message.match(/(\d+)人/);
if (countMatch && !this.context.guestCount) {
this.context.guestCount = parseInt(countMatch[1]);
}
}
isTaskComplete(task, message) {
// 简单判断:如果关键信息已获取,认为任务完成
if (task.id === 'budget') return this.context.budget !== null;
if (task.id === 'guests') return this.context.guestCount !== null;
if (task.id === 'date') return this.context.date !== null;
return message.includes('好') || message.includes('可以') || message.includes('确定');
}
}
6.7.3 对话演示
实际对话效果:
用户: 帮我策划一场生日派对
AI: 🎂 让我们开始策划生日派对吧!
📋 整体规划:
1️⃣ 确定预算
2️⃣ 确认人数
3️⃣ 选择日期
4️⃣ 预订场地
5️⃣ 安排餐饮
6️⃣ 发送邀请
首先,请问您的预算是多少?
─────────────────────────────────
用户: 大概3000元
AI: 好的,预算3000元,我会根据这个预算来推荐。
📋 接下来:确认人数
请问大约有多少位客人参加?
─────────────────────────────────
用户: 15个人
AI: 收到,15位客人。
📋 接下来:选择日期
派对计划在哪一天举办?
─────────────────────────────────
[继续执行后续步骤...]
6.8 常见规划模式
常用的任务执行模式:
1. 顺序执行(Sequential)
步骤1 → 步骤2 → 步骤3 → 步骤4
适用场景:有明确依赖关系的任务
示例:写报告(先收集资料 → 再分析 → 最后撰写)
2. 并行执行(Parallel)
┌→ 步骤2a ─┐
步骤1 ┼→ 步骤2b ─┼→ 步骤3
└→ 步骤2c ─┘
适用场景:子任务相互独立,可同时执行
示例:数据分析(同时查询多个数据源)
3. 条件分支(Conditional)
条件判断
/ \
是 否
/ \
分支A 分支B
\ /
└→ 汇合 ←─┘
适用场景:根据中间结果选择不同路径
示例:客服(根据问题类型转接不同部门)
4. 循环迭代(Iterative)
┌─────────────────┐
│ │
▼ │
步骤 → 检查条件 ──┤
↓ 不满足 │
满足 │
↓ │
退出 ←──────┘
适用场景:需要反复优化的任务
示例:代码审查(修改 → 检查 → 再修改)
本章小结
核心知识点回顾:
- 规划 - 把大任务拆成小步骤,逐个完成
- 任务分解 - 目标分解、步骤分解、层次分解三种策略
- 规划方法 - Chain of Thought(一步步思考)、Tree of Thoughts(多路径探索)、反思重规划
- 规划表示 - 列表、树状图、流程图等多种形式
- 执行与调整 - 观察-思考-行动循环,根据实际情况动态调整
- 执行模式 - 顺序、并行、条件分支、循环迭代
至此,你已经掌握了智能体开发的核心技能:记忆管理让智能体能记住用户,规划能力让智能体有条不紊地完成复杂任务。继续学习,你将能构建出真正强大的AI智能体!