Agent AtlasAI Agent 知识库
03.03架构模式 · Architecture

规划与任务分解

显式计划与隐式计划、分解粒度、依赖管理、重规划,以及 Plan-and-Execute 的完整取舍。

规划不是让模型写一份漂亮的待办清单,而是让它在动手前想清楚:目标是什么、需要哪些中间状态、哪些步骤可以并行、什么情况下要重来。

隐式规划与显式规划

隐式规划:模型在推理中自己决定下一步,不输出计划。ReAct 就是典型。灵活,但人看不见、系统管不了。

显式规划:模型先输出一份结构化计划,再由执行器逐步完成。好处是:

  • 人可以审查、修改;
  • 系统可以并行调度;
  • 进度可追踪、可恢复;
  • 失败时知道该重跑哪一步;
  • 评估可以同时看计划质量与执行质量。

代价是额外的 token、可能的过度规划,以及计划过时需要重规划。

经验法则

任务超过 5 步、或需要跨多个工具/数据源时,用显式计划;简单问答和短循环用隐式规划。

计划的最小结构

不要只让模型输出一串自然语言步骤。给它一个可执行的 Schema:

json
{
  "goal": "评估 ACME 2025 年财务风险并给出三条建议",
  "assumptions": ["以审计后的 10-K 为准", "同行取三家可比公司"],
  "steps": [
    {
      "id": "s1",
      "action": "获取 ACME 2025 年 10-K",
      "tool": "search_filings",
      "depends_on": [],
      "done_when": "拿到包含利润表与资产负债表的文件"
    },
    {
      "id": "s2",
      "action": "抽取关键财务指标",
      "tool": "extract_financials",
      "depends_on": ["s1"],
      "done_when": "得到营收、毛利率、经营现金流、负债率"
    },
    {
      "id": "s3",
      "action": "对比三家同行毛利率",
      "tool": "search_filings",
      "depends_on": ["s2"],
      "done_when": "得到三家同行同年数据"
    },
    {
      "id": "s4",
      "action": "撰写风险简报",
      "tool": "write_report",
      "depends_on": ["s2", "s3"],
      "done_when": "含三条风险、每条附数据与来源"
    }
  ]
}

几个关键字段:

  • id:稳定的步骤标识,用于重试和引用;
  • depends_on:依赖关系,决定并行与顺序;
  • done_when:完成判据,避免「做了一半就算完成」;
  • tool:预期使用的工具,便于提前做权限检查;
  • assumptions:假设条件,重规划时需要重新审视。

分解到什么粒度

太粗:一步里包含多个不确定动作,失败无法定位。 太细:步骤爆炸,协调成本超过收益。

一个实用标准:每个步骤应该有一个可验证的完成状态。

  • 「调研市场」太粗,无法判断完成;
  • 「打开第 3 页」太细,没有决策价值;
  • 「收集三家同行 2025 年毛利率,并记录来源」合适。

另一个标准是单一责任:一步只产出一类结果。如果一步既检索又计算又写作,失败时你不知道是哪一环。

Plan-and-Execute 循环

图 1 · 规划—执行—重规划
Planner拆解目标,输出步骤与依赖
→
Executor按依赖执行,记录结果
→
Verifier检查完成判据与质量
→
Replanner失败或新信息时调整计划
Verifier 是容易被省略、却最影响可靠性的一环。

伪代码:

python
def plan_and_execute(goal, max_replans=2):
    plan = planner(goal)
    state = {"goal": goal, "facts": [], "artifacts": {}}

    for attempt in range(max_replans + 1):
        for step in ready_steps(plan, state):
            result = executor(step, state)
            state = merge(state, step, result)

            if not verify(step, result, state):
                plan = replanner(goal, plan, state, failed=step)
                break
        else:
            if all_done(plan, state) and verify_goal(goal, state):
                return finalize(state)
            plan = replanner(goal, plan, state, failed=None)

    return escalate_to_human(state)

注意:

  • ready_steps 按依赖调度,独立步骤可并行;
  • 每次执行后都更新 state,而不是只追加消息;
  • 验证失败触发重规划,而不是盲目重试;
  • 重规划有次数上限,避免无限循环。

什么时候重规划

不是每次失败都值得重规划。触发条件应该是:

  1. 关键假设被推翻:文件不是 10-K 而是新闻稿;
  2. 工具持续失败:换路径,而不是重试同一个;
  3. 出现新信息:发现还有子公司需要合并报表;
  4. 完成判据无法满足:数据缺失,需要换指标;
  5. 预算/时间接近上限:缩减范围。

不该触发的:

  • 单次超时(先重试);
  • 格式错误(先修复);
  • 模型「觉得」计划不够好(容易陷入无限优化)。

计划的验证

计划质量可以从四个维度检查:

维度问题检查方式
完整性是否覆盖目标的所有必要条件?人工或 LLM 对照目标清单
可执行性每步是否有明确工具与输入?Schema 校验、工具存在性检查
依赖正确是否有循环依赖或缺失前置?拓扑排序
可验证每步是否有完成判据?检查 done_when 非空且可观察

一个低成本的自动检查:

python
def validate_plan(plan, available_tools):
    ids = {s["id"] for s in plan["steps"]}
    for s in plan["steps"]:
        assert s["id"] in ids
        assert set(s["depends_on"]) <= ids
        assert s["tool"] in available_tools
        assert s["done_when"].strip()
    assert not has_cycle(plan)  # 拓扑排序检测

如果计划里引用了不存在的工具,直接让规划器重写,而不是在执行时才发现。

规划提示的写法

text
你是任务规划器。根据目标生成一份可执行计划。

要求:
1. 每个步骤只做一件事,且有可观察的完成判据。
2. 标明依赖关系;无依赖的步骤应可并行。
3. 只使用给定工具;不要发明工具。
4. 步骤数控制在 3–8 个;超过 8 个时先合并相似步骤。
5. 如果目标本身不清晰,先输出需要澄清的问题,不要硬编计划。
6. 输出 JSON,符合给定 Schema。

目标:{goal}
可用工具:{tools}
已知信息:{context}

注意最后一条:允许规划器说「需要澄清」。很多错误计划的根源是目标本身模糊,而模型不敢问。

常见失败模式

过度规划

把「查天气」拆成五步:识别城市、调用 API、解析、格式化、回复。步骤越多,失败点越多。简单任务直接做。

计划一成不变

执行中发现数据不存在,仍然按原计划走,最后编造结果。必须在关键步骤后检查假设。

计划不可执行

模型发明了 get_sec_filing 这种不存在的工具,执行时才报错。规划后先做工具存在性与依赖校验。

只有计划,没有验证

每步都「完成」了,但最终结果不对。done_when 必须是可观察的,最好由代码或独立评审检查。

重规划风暴

每次小失败都重写整份计划,成本和延迟爆炸。限制重规划次数,并优先局部替换失败的步骤。

与 ReAct 的取舍

维度ReActPlan-and-Execute
全局视野弱强
适应性强,随时调整需要重规划
成本低–中中–高(规划 + 执行)
可审查性低高
适合探索、短任务多步骤、可分解、需审批

一个混合方案:先做轻量规划(3–5 步),执行时用 ReAct 处理每步内部的探索。这样既有全局方向,又保留局部灵活性。

小结

  • 显式计划让 Agent 可审查、可调度、可恢复,但会增加成本。
  • 好的步骤有单一责任、明确工具、可观察的完成判据。
  • 用依赖图调度,独立步骤可并行。
  • 验证失败才重规划,且要有次数上限。
  • 规划器必须被允许说「目标不清晰」。

下一篇讲如何让 Agent 检查自己的输出——以及为什么大多数「自我反思」其实没用。

读完了?进度会保存在本地浏览器。
内容会持续修订。发现错误或想补充,欢迎反馈。 遇到问题?查排查手册 →