news 2026/7/27 17:36:57

智能体面试准备(五):规划与任务分解——从 Plan-and-Execute 到动态重规划的工程实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
智能体面试准备(五):规划与任务分解——从 Plan-and-Execute 到动态重规划的工程实现

智能体面试准备(五):规划与任务分解——从 Plan-and-Execute 到动态重规划的工程实现

Agent 面试里,"工具调用"考的是基本功,"规划能力"考的才是深度。面试官常用的开场是:"你的 Agent 拿到一个复杂任务,比如'调研三个竞品并输出对比报告',它怎么知道先做什么后做什么?"如果你的回答只有"让模型自己想",那基本就暴露了没做过复杂 Agent。这篇把任务规划的主流范式、Plan-and-Execute 的完整实现、动态重规划的触发机制讲透,配一段可直接运行的 planner 代码。

一、为什么需要显式规划:ReAct 的天花板

ReAct(每步"想一下→做一下→看结果")是 Agent 的入门范式,但它在复杂任务上有三个结构性缺陷:

  1. 短视:每步只基于当前观察决定下一步,缺乏全局视野,容易在中途偏离最终目标;
  2. 上下文膨胀:所有中间观察都塞进历史,长任务后期模型"忘了"最初目标,且 token 成本线性上涨;
  3. 错误累积:某一步走偏后没有全局参照,后续步骤在错误方向上越走越远。

显式规划(Planning)的思路是把"想清楚整体怎么做"和"逐步执行"分离:先生成任务分解(plan),再逐项执行(execute),执行中按需修订计划(re-plan)。这就是 Plan-and-Execute 范式,LangChain 的同名实现、BabyAGI 的任务队列、OpenAI Deep Research 的多步研究流程,内核都是它。

二、主流规划范式对比

范式核心机制优点缺点适用场景
ReAct逐步交错推理与行动实现简单、灵活应变短视、上下文膨胀短链任务(≤5步)
Plan-and-Execute先全局分解再逐项执行全局一致、可并行、省 token计划可能过时中长任务、可预估结构
ReWOO计划中用变量引用未来结果(#E1、#E2)一次规划零中断,token 最省完全无法应变步骤确定的流水线
LLMCompiler生成任务 DAG,无依赖任务并行执行延迟最低实现复杂多工具可并行场景
Tree of Thoughts树状展开多分支+回溯探索性最强成本爆炸解谜、搜索类问题

面试高频追问:ReWOO 的变量引用机制是什么?答:planner 一次性生成所有步骤,用占位符(#E1)表示"第一步的执行结果",后续步骤直接引用占位符;executor 按序执行并做变量替换,最后 solver 汇总。全程只调用两次 LLM(规划+汇总),token 消耗远低于 ReAct 的 N 次调用。代价是中途无法根据实际结果调整——所以它只适合结构确定的任务。

任务分解的两个正交维度也值得记住:分解粒度(粗粒度里程碑 vs 细粒度动作)和分解时机(一次性全部分解 vs 递归按需分解)。递归分解(把大任务拆成子任务,子任务执行时再拆)更接近人类做法,也是 Manus、Devin 这类长程 Agent 的实际策略。

三、Plan-and-Execute 的工程要素

一个生产可用的 planner 至少要处理四件事:

计划的结构化表示。不能是自然语言段落,必须是结构化对象:每个步骤有 id、描述、依赖(depends_on)、状态(pending/running/done/failed)、产出。有了依赖关系,无依赖的步骤可以并行,失败可以精确定位影响范围。

执行器与规划器分离。planner 用强模型(规划质量决定上限),executor 可以用便宜模型或纯代码。executor 只看到"当前步骤+相关上下文",而非全部历史——这是控制上下文膨胀的关键手段。

重规划触发机制。三种标准触发条件:步骤执行失败且重试无效;执行结果与计划假设不符(比如"搜索竞品A的财报"发现竞品A已被收购);用户中途修改需求。重规划时把"原计划+已完成步骤+失败原因"喂给 planner,生成修订计划,已完成的工作要保留。

终止与预算控制。最大步数、最大 token 预算、最大重规划次数三道保险,防止 Agent 无限循环烧钱——这是面试官特别爱听的工程意识。

四、可运行代码:带依赖管理与重规划的迷你 Planner

下面用纯 Python 标准库实现一个可运行的 Plan-Execute 框架:DAG 依赖调度 + 失败重试 + 重规划钩子。真实项目里把fake_llm_planexecute_step换成 LLM 调用即可,骨架完全一致。

import json from dataclasses import dataclass, field from enum import Enum class Status(Enum): PENDING = "pending" DONE = "done" FAILED = "failed" @dataclass class Step: id: str desc: str depends_on: list = field(default_factory=list) status: Status = Status.PENDING result: str = "" retries: int = 0 def fake_llm_plan(goal: str) -> list: """模拟 planner LLM:返回结构化计划(真实场景换成 LLM+JSON 输出)。""" return [ Step("s1", "搜索竞品A的公开资料"), Step("s2", "搜索竞品B的公开资料"), Step("s3", "提取两家竞品的定价与功能", depends_on=["s1", "s2"]), Step("s4", "生成对比报告", depends_on=["s3"]), ] def execute_step(step: Step, context: dict) -> str: """模拟 executor:s2 第一次执行会失败,用于演示重试与重规划。""" if step.id == "s2" and step.retries == 0: raise RuntimeError("竞品B官网无法访问") return f"[{step.desc}] 的执行结果" def replan(goal: str, steps: list, failed: Step) -> list: """模拟重规划:把失败步骤换成替代方案,保留已完成的工作。""" print(f" >> 触发重规划:{failed.desc} 失败原因已提交 planner") failed.desc = "改用第三方数据库查询竞品B信息" failed.status = Status.PENDING return steps def run(goal: str, max_rounds: int = 10, max_retries: int = 1): steps = fake_llm_plan(goal) context = {} for round_i in range(max_rounds): # 找出所有依赖已满足的待执行步骤(真实场景可并行) ready = [s for s in steps if s.status == Status.PENDING and all(next(x for x in steps if x.id == d).status == Status.DONE for d in s.depends_on)] if not ready: break for step in ready: try: step.result = execute_step(step, context) step.status = Status.DONE context[step.id] = step.result print(f" [OK] {step.id}: {step.desc}") except Exception as e: step.retries += 1 print(f" [FAIL] {step.id}: {e} (第{step.retries}次)") if step.retries > max_retries: step.status = Status.FAILED steps = replan(goal, steps, step) done = all(s.status == Status.DONE for s in steps) print(f"任务{'完成' if done else '未完成'},共 {round_i+1} 轮调度") return context if __name__ == "__main__": result = run("调研竞品A和B并输出对比报告") print(json.dumps(result, ensure_ascii=False, indent=2))

运行后可以看到完整过程:s1/s2 并发就绪 → s2 失败重试 → 重试再失败触发重规划 → 替代方案执行成功 → 依赖满足后 s3、s4 顺序完成。这段代码覆盖了面试手撕 planner 的全部得分点:DAG 依赖调度、失败重试、重规划、预算控制

五、规划质量的评估与提升

评估:规划是中间产物,直接评估的常用维度是——计划可执行率(每步是否对应可用工具)、步骤冗余率、依赖正确率;端到端则看任务成功率与平均步数。学术界有 PlanBench 等基准,工业界更多用人工抽检 + 端到端 A/B。

提升手段(按性价比排序):

  1. Few-shot 计划示例:在 planner prompt 里放 2~3 个高质量计划范例,是最便宜有效的手段;
  2. 结构化输出约束:JSON Schema 强制输出步骤对象,杜绝自然语言计划的解析失败;
  3. 工具清单注入:规划时把可用工具及其能力描述给 planner,避免规划出"无法执行的步骤"——计划与工具脱节是新手 Agent 最常见的失败模式;
  4. 计划评审(plan critique):让另一个 LLM 调用审查计划的完整性与可行性再执行,成本换质量;
  5. 微调专用 planner:积累了足够的(任务,优质计划)数据后,微调小模型做规划,降本增效。

六、面试答题框架与高频题

"设计一个能完成'订机票+订酒店+生成行程单'的 Agent",推荐作答结构:

  1. 范式选择:结构较确定,Plan-and-Execute 优于纯 ReAct;机票和酒店查询无依赖可并行,行程单依赖前两者;
  2. 计划表示:JSON 步骤对象 + depends_on 字段,DAG 调度;
  3. 异常路径:航班无票→重规划改时间;酒店与航班日期冲突→触发一致性校验步骤;
  4. 人机交互点:支付前必须人工确认(高风险动作卡点);
  5. 预算控制:最大步数与重规划次数上限。

其他高频题速答要点

  • "ReAct 和 Plan-and-Execute 怎么选?"——任务步数少、探索性强用 ReAct;步骤可预估、要控成本用 P&E;实践常用混合:全局 P&E,单步内部 ReAct。
  • "计划过时怎么办?"——答重规划三触发条件(失败、假设不符、需求变更)+ 保留已完成工作。
  • "怎么防止 Agent 死循环?"——步数/token/重规划次数三重预算 + 重复动作检测(同一工具同参数连续调用 N 次强制终止)。

自检清单:能说清 ReAct 的三个结构性缺陷吗?能手写带依赖的任务调度吗?知道 ReWOO 的变量引用机制吗?能列出重规划的三个触发条件吗?这四点齐了,规划环节就能答出区分度。

下一篇讲记忆系统:短期记忆、长期记忆、向量化检索记忆的设计与代码实现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/27 17:35:28

LM8330外设控制器:嵌入式键盘扫描与PWM调光实战解析

1. 项目概述与核心价值在嵌入式系统,尤其是那些基于微控制器(MCU)的产品开发中,我们常常会遇到一个经典矛盾:主控芯片的I/O引脚数量有限,但产品功能需求却在不断膨胀。一个典型的例子就是带背光键盘的便携式…

作者头像 李华
网站建设 2026/7/27 17:35:06

LM10524EVM评估板实战指南:从硬件解析到电源性能测试

1. 项目概述与核心价值如果你正在为固态硬盘(SSD)、嵌入式存储模块或者任何需要多路、高效、可编程电源的SOC/ASIC系统选型电源管理单元(PMU),那么LM10524这款芯片以及它的评估板(LM10524EVM)绝…

作者头像 李华
网站建设 2026/7/27 17:33:21

Next.js-Prisma-Boilerplate扩展指南:集成第三方服务与自定义功能

Next.js-Prisma-Boilerplate扩展指南:集成第三方服务与自定义功能 【免费下载链接】nextjs-prisma-boilerplate Full stack boilerplate with Next.js, Prisma, Tailwind, TypeScript, Docker, Postgres, documentation, frontend and backend unit and integration…

作者头像 李华
网站建设 2026/7/27 17:32:43

3分钟掌握Pock:让MacBook Touch Bar变身高效生产力中心

3分钟掌握Pock:让MacBook Touch Bar变身高效生产力中心 【免费下载链接】pock Widgets manager for MacBook Touch Bar 项目地址: https://gitcode.com/gh_mirrors/po/pock 想让你的MacBook Touch Bar不再只是个装饰品吗?Pock就是那个能让Touch B…

作者头像 李华
网站建设 2026/7/27 17:31:21

如何快速入门Perl开发?Awesome Perl精选10大入门必备工具与框架

如何快速入门Perl开发?Awesome Perl精选10大入门必备工具与框架 【免费下载链接】awesome-perl A curated list of awesome Perl frameworks and libraries. Come on Pull Requests! 项目地址: https://gitcode.com/gh_mirrors/aw/awesome-perl Perl作为一门…

作者头像 李华