第九章 Planning:解空间的显式建模
核心命题:在行动之前先规划(Plan),是将问题从”在状态空间中随机游走”转变为”在解空间中有目标地导航”的关键跃迁。Plan 是对解空间的主动建模,也是在行动发生之前对 Q/T/C 预算的显式分配——它同时扮演三个角色:解空间搜索的启发式函数、行动成本的前置审计工具,以及人机协作的天然接口。
9.1 Plan 的工程价值
当 Agent 输出一个计划,它做的是一件事:将隐式的解空间转化为显式的、可检验的结构。这让 Harness 得以在执行之前介入验证,在实际成本发生之前识别不可行方案——在计划层纠正方向性错误,代价远低于在执行层纠正具体错误。
Plan 的三个功能角色
三个角色共享同一个底层逻辑:将原本只能在执行中暴露的信息提前到执行前显式呈现,从而把高代价的事后修正转化为低代价的事前调整。
角色一:解空间搜索的启发式函数。第四章将 Harness 的目标定义为同时压缩分支因子 和路径深度 (§4.3)。Plan 是实现”压缩 “的核心机制:一个好的计划相当于提供了高质量的启发式函数 ——在每个状态 处, 估计到目标状态的剩余代价,引导搜索优先探索”更接近目标”的路径。无计划的 Agent 等价于无启发式的盲目搜索(BFS/DFS),其搜索效率在深度任务中呈指数级恶化。
角色二:Q/T/C 预算的前置分配。Plan 中每个步骤都携带预估成本(token、时间)。整个 Plan 因此等价于一份 Q/T/C 预算承诺——在执行开始前,Harness 可以逐项验证:
- 预估总 token 成本是否在 以内?(C 轴)
- 预估总时延是否满足 ?(T 轴)
- 预设的
success_criteria是否足以验证 ?(Q 轴)
如果任一答案是否定的,在计划层纠正(修改步骤、调整粒度)的代价远低于在执行层纠正(回滚操作、重新执行)。Plan Schema 的 estimated_cost 与 success_criteria 字段,正是这一前置验证的承载结构。
角色三:行动前报告(委托代理视角)。第三章建立了委托代理理论作为 Harness 的分析框架——委托人(人类)与代理人(Agent)之间存在信息不对称,监督成本高昂。Plan-before-Act 是解决这一不对称的结构性机制:Agent 在采取任何不可逆行动之前,先向委托人提交一份”行动意图报告”。委托人在信息成本极低的时刻(审查计划比审查执行轨迹便宜一到两个数量级)完成对代理人行为的对齐验证。
标准 Plan Schema:
{
"goal": "...",
"steps": [
{
"id": 1,
"action": "...",
"expected_output": "...",
"fallback": "...",
"estimated_cost": { "tokens": 500, "time_sec": 10 }
}
],
"success_criteria": "...",
"abort_conditions": ["..."]
}
Schema 中的每个字段对应一个明确的工程功能,并直接映射到 Q/T/C 三轴:
goal+success_criteria:将目标 显式化为可验证条件(对应 §4.5 的第一类目标,承载 Q 轴的可观察化)steps[].estimated_cost:将 token 与时间成本结构化预申报(承载 C 轴与 T 轴的前置分配)abort_conditions:使”提前终止”有明确触发条件,避免在不可达状态中继续消耗预算(承载 C 轴的止损机制)steps[].fallback:使每个步骤都有失败处理路径(对应 §5.5 的概率视角:失败状态是解空间的正式组成部分,而非例外)
好的 Plan vs. 坏的 Plan
一个 Plan 的质量取决于它对解空间结构的建模是否准确。常见的坏计划特征:
- 步骤无验证点:步骤只描述”做什么”,不描述”如何判断做对了”——这使 Hook 无法在步骤边界做质量检查
- 无 fallback 设计:假设所有工具调用都会成功,没有为失败路径预留处理方式——这是 §5.5 描述的”过度乐观的计划”的反模式
- 目标描述模糊:
success_criteria是自然语言意图而非可验证条件——这将 退化为 §4.5 的第二类目标,需要语义型评估,增加监督成本
计算复杂性视角:Plan 的理论必然性
规划问题本质上是经典的 PSPACE-complete 问题(当状态转换存在不确定性时甚至更难)。这一事实赋予了 Plan 的分解设计以理论必然性——分解不是工程品味的选择,而是在有界计算资源内求可行解的必然要求:穷举所有可能行动序列在指数时间内不可行,Plan 因此成为将 PSPACE 问题通过启发式分解转化为多个多项式子问题的机制。
“Plan 减少回溯”是经验描述;更精确的表述是:Plan 是在有界计算资源内从 PSPACE 规划问题中提取可行近似解的启发式框架。每一个 Plan 步骤对应一个在多项式时间内可独立求解的子问题;步骤边界的设计,本质上是在问题的自然分解结构处切割 PSPACE 实例,使各子问题的搜索空间可被独立管理。
边界说明:PSPACE 复杂性描述的是最坏情况的理论下界;实际 LLM 的规划行为是概率性的,不符合经典确定性复杂性假设。此处将其作为”为何必须分解”的理论支撑,不用于定量预测 Plan 的性能。
9.2 计划粒度的设计决策
粒度是步骤边界的位置——它决定了每个子问题的规模、验证频率和错误恢复成本。粒度不是”越细越好”或”越粗越好”的单调权衡,而是一个有最优点的设计空间。
自然分解单元:粒度的基准参照
第四章 §4.6 给出了分解粒度的可操作判断标准:如果子问题的结果可以被简洁的结构化消息表达,则分解是合适的;如果子步骤需要传递大量中间状态才能衔接,则分解粒度过细,耦合度过高。这个标准同时适用于 Plan 的步骤边界设计。
最优粒度的判断标准:每个 Plan 步骤应满足以下三个条件:
- 可独立验证:步骤有明确的
expected_output,可以被 Hook 在步骤边界处自动检查(对应 §4.5 的第一类可验证目标) - 成本有界:步骤的预估 token 消耗和时间在单步预算内可承受——若单步执行成本过高,错误恢复的代价也成比例放大
- 结构化输出:步骤的结论可以用简洁的结构化消息(JSON、列表)表达,不需要传递完整的中间推理过程给下一个步骤
粒度权衡矩阵
| 维度 | 粗粒度(步骤少) | 细粒度(步骤多) |
|---|---|---|
| 错误发现时机 | 晚:步骤执行大量工作后才验证 | 早:验证频率高,错误早期可见 |
| 错误恢复成本 | 高:需要回滚大量已完成的操作 | 低:每步骤成本小,回滚代价小 |
| 规划成本 | 低:步骤少,Plan 生成快 | 高:步骤多,依赖关系复杂 |
| 执行灵活性 | 高:步骤内 Agent 有更大自由度 | 低:步骤间约束多,Agent 受限 |
| 适用场景 | 低风险任务、熟悉环境 | 高风险任务、不确定环境 |
过粗粒度的失败模式:步骤”完成所有数据迁移”——这个步骤在中途发现异常时,已消耗大量 token 和时间,回滚代价高昂;expected_output 也无法在步骤内部被验证,只能在步骤结束后才发现问题。
过细粒度的失败模式:为每一行 SQL 语句定义一个步骤——这使 Plan 本身的 token 成本超过执行成本;且步骤间的依赖关系爆炸性增长,任何一步的失败都需要追溯全部依赖链,协调成本超过分解的收益。
粒度的环境相关性:同一任务类型在不同 Q/T/C 约束下,最优粒度可以不同。在 T 主导的交互式场景(§3.1),Plan 的生成本身就是时延的一部分——应倾向于粗粒度(步骤少,规划快);在 C 主导的批量场景,有充裕预算执行细粒度的预检和验证,应倾向于细粒度(步骤多,错误恢复成本低)。
9.3 动态修正:计划不是合同
计划在生成时基于对环境的某种假设。当执行过程中这些假设被证伪,Plan 应当更新——这不是计划”失败”,而是计划在新信息下的自然演化。强行继续是以沉没成本为理由继续消耗预算,反理性;立即放弃则浪费了已完成的步骤结果。动态修正是两者之间的正确选择:利用已知信息,以最小的调整使计划重新可行。
触发动态修正的三类条件
条件一:连续工具失败超过阈值。若同一步骤连续失败 次,说明问题不在于偶发的随机错误,而在于步骤设计与实际环境的结构性不匹配——步骤的前提假设错误,或操作集不包含完成这个步骤所需的工具。继续重试是低效的;此时应触发修正,检查当前步骤的设计假设。工程经验: 是常见阈值——第一次失败可能是噪声,第二次发现规律,第三次确认是结构性问题。
条件二:步骤超时超过预估成本的倍数。若步骤执行时间超过 estimated_cost.time_sec 的 2 倍,说明 Plan 的成本模型与实际环境存在显著偏差。继续等待可能导致总任务超出 ;此时应触发修正,重新估算剩余步骤的成本,判断是否需要压缩后续步骤或调整执行策略。
条件三:发现计划外的意外状态。若工具返回了 Plan 生成时未预期的状态信息(如数据量比预估大一个数量级、存在未预知的数据格式异常、依赖服务不可用),当前计划的其余步骤可能建立在已失效的假设上。此时应触发修正,重新评估后续步骤的可行性。
修正协议:局部更新、全局重规划与终止
收到触发信号后,修正的范围取决于问题的定位:
局部更新:触发条件只影响当前步骤或少数后续步骤的假设。修正方式——替换或插入新步骤,保留已完成步骤的结果,更新受影响步骤的 action、expected_output 或 fallback。这是代价最小的修正,保留了已完成工作的价值。
全局重规划:触发条件涉及对整体任务架构的假设(如发现初始状态 建模有误,或目标状态 实际上不可达)。修正方式——保存已完成步骤的结论,以更准确的 为起点,重新生成完整的 Plan。成本较高,但避免了在错误方向上继续消耗预算。
执行终止:若新发现的信息表明 在当前操作集 下不可达(§4.3 的连通性条件),或继续执行的预期成本已超过 ,则触发 abort_conditions,主动终止并上报给人类。主动终止优于耗尽预算后的被动终止——前者保留了有用的中间状态和诊断信息,后者把最后的预算浪费在注定失败的尝试上。
与收敛性判别的联系(§5.3)
动态修正是反馈回路的”方向校正机制”。第五章的收敛性分析表明:发散的早期信号是”相似的失败信号重复出现,每轮 token 消耗增大而无进展”(§5.3)。这个早期信号与动态修正的触发条件一一对应——连续工具失败(相似失败重复)、步骤超时(token 消耗增大无进展)。动态修正的工程价值,是在发散趋势被确认之前就主动干预,而非等到 token 预算耗尽才被动终止。
修正的判断本质上是一个决策理论问题(§3.2 决策理论视角):在当前已积累的失败信号下,继续按原计划执行的期望成本,与触发修正并调整计划的期望成本,哪个更低?当失败信号提供了足够的证据说明原计划的可行性假设已经不成立,修正的期望收益为正。
9.4 Plan 作为人机协作接口
Plan 是人类监督最自然、最高效的介入点——不是因为”人类应该审查一切”,而是因为 在 Plan 阶段介入的杠杆率远高于在执行阶段介入。
监督杠杆率的量化论证
设一个包含 个步骤的 Plan,每个步骤的平均执行成本为 (时间 + token + 潜在清理成本)。若计划在第 步因方向性错误导致失败,则已浪费的成本为 ,加上失败后的清理和恢复成本 。
若同样的方向性错误在 Plan 审查阶段被发现(成本 ,通常为人类阅读几十秒至几分钟),节省的成本为 。当 较大(方向性错误在深层步骤才显现)时,监督杠杆率 可以轻易超过 10:1 甚至 100:1。
工程结论由此确立:Plan 审查是单位人类注意力成本中杠杆率最高的监督行为。批准一个计划所花的 2 分钟,可以避免随后 20 分钟的执行错误和 2 小时的清理工作。
分级审批机制
监督不等于”每个 Plan 都需要人工审批”——这会使人类注意力成本成为系统瓶颈(§3.1 中 C 的第三个子维度)。分级审批根据 Plan 的风险特征自动路由:
自动执行(Auto-approve):Plan 的所有步骤同时满足——操作可回滚、成本低于阈值、任务类型曾经成功执行过。这类 Plan 的风险足够低,人类审查的边际价值低于审查成本。
选择性审批(Selective-approve):Plan 包含任一风险信号——不可逆操作(数据删除、外部 API 调用、生产环境写入)、成本估算超过阈值、任务类型首次执行。这类 Plan 需要人类确认关键步骤的设计假设。
全量审批(Full-approve):Plan 涉及高风险或高不确定性任务——新的系统集成、涉及多个服务的联动变更、成本估算置信度低。人类在执行开始前审查完整 Plan 并批准。
委托代理理论的工程落点
第三章将 Plan-before-Act 标识为委托代理问题的核心干预机制(§3.2):System Prompt 是激励合约(定义 Agent 的行为边界),Plan 是行动前报告(Agent 向委托人展示其行动意图),Hook 是执行后审计(检查行动是否符合合约)。三者构成一个完整的监督链——合约定义规则,行动前报告允许预防性干预,执行后审计关闭反馈回路。
在这条监督链中,Plan 的位置决定了它的角色:处于 System Prompt(静态合约)和 Hook(动态监控)之间,作为任务级的 临时合约——描述这次具体任务的预期行为路径,比静态 System Prompt 更具体,比 Hook 的实时监控成本更低。Plan 的粒度和 abort_conditions 的设计,正是委托人(人类)在最小化监督成本的同时保持行为对齐的工程手段。
Plan 的制度化:从任务级计划到跨任务模板
当同一类任务反复出现,Plan 可以升格为 计划模板(Plan Template)——可复用的步骤框架,只需在任务开始时填充具体参数。计划模板是 §7.5 中 AGENTS.md 制度化思路在规划层的对应:将一次精心设计的规划方案分摊到每一次同类任务的执行成本上,边际成本趋近于零。
计划模板的适用条件——任务类型足够相似(同类数据迁移、同类代码审查、同类测试执行),核心步骤序列相对稳定(变化的只是具体目标和参数,而非步骤的逻辑结构)。模板不应过度参数化:如果模板有太多”填空项”,实际上是在重新规划而非复用计划。
章末案例剖析
同一个数据库迁移任务,经历了两种截然不同的执行路径——一种没有显式计划,另一种以 Plan-before-Act 为架构。两种路径在相同的环境约束下,遭遇了完全相同的”中途意外”,却走向了完全不同的结果。差距并不来自 Agent 能力,而来自有无计划所决定的三件事——意外被多早发现、修正成本有多高、人类在哪个时刻介入。
任务设定:将一个生产 PostgreSQL 数据库中 users 表的 preferences_json 列(JSON blob,约 4,200,000 行)迁移到独立的 user_preferences 规范化表中。数据库运行中,平均 QPS 约 400。要求:零停机、迁移后数据完整性 100%、不影响现有查询。
已知的任务复杂性:preferences_json 列的数据质量未经审计——历史导入数据可能存在格式异常,但比例和类型不明。这是任务中唯一已知的不确定因素。
策略 A:无计划直接执行
Agent 收到任务描述,立即开始生成并执行 SQL:
第 1 轮:创建 user_preferences 目标表结构,DDL 执行成功(约 200 tokens,15 秒)。
第 2 轮:执行全量迁移 INSERT:
INSERT INTO user_preferences (user_id, key, value, created_at)
SELECT
id,
pref.key,
pref.value,
created_at
FROM users,
jsonb_each_text(preferences_json) AS pref(key, value)
WHERE preferences_json IS NOT NULL;
语句开始执行,数据库报告进度:约 100 万行/分钟。执行到第 8 分钟时(约 380 万行已处理),数据库抛出错误:
ERROR: invalid input syntax for type jsonb
DETAIL: Token "null" is invalid.
CONTEXT: line 1: {preferences: null}
事务自动回滚,8 分钟的执行成果全部丢失。380 万行的进度归零。
第 3–4 轮:Agent 识别到 NULL 值问题,修改查询加入 jsonb_typeof(preferences_json) = 'object' 过滤条件,重新执行。10 分钟后执行完成,但 Agent 随即发现数据行数异常:
SELECT COUNT(*) FROM user_preferences;
-- 结果:4,063,200
SELECT COUNT(*) FROM users WHERE preferences_json IS NOT NULL;
-- 结果:4,117,800
差值 54,600 行——这些行被过滤条件静默丢弃,其中包含格式可以被清洗的数据(空 JSON {} 和 null 字段可以被转换为默认值),而非全部都是无效数据。
第 5–8 轮:Agent 尝试识别被丢弃的行,重新处理可清洗部分:
- 第 5 轮:查询异常行分布,输出约 2,800 tokens 的分析结果
- 第 6–7 轮:针对不同异常类型写入修复逻辑,但发现部分修复逻辑与已完成的迁移行产生主键冲突
- 第 8 轮:尝试添加外键约束,失败——已迁移数据中存在
user_id不在users表中的孤儿记录(历史数据问题,未被预先发现)
结果:执行 8 轮,耗时约 3.5 小时,数据迁移部分完成(约 97% 行成功),54,600 行未处理,外键约束未能添加,任务 (100% 完整性)未满足。期间发生 1 次全量回滚,生产数据库的锁竞争在第 2 轮全量执行期间使 QPS 下降约 35%。
失败的结构性分析:此案例中的三个问题——JSON 格式异常、数据丢失、孤儿记录——都可以通过数据质量预检提前发现。无计划执行等价于将 (初始状态)的假设验证推迟到执行层——代价是:当假设被证伪时,大量不可逆的操作成本已经发生。
策略 B:Plan 生成 + 动态修正
Agent 收到任务后,首先生成 Plan 而非立即执行:
{
"goal": "将 users.preferences_json(约 420 万行)迁移至 user_preferences 规范化表,零停机,完整性 100%",
"steps": [
{
"id": 1,
"action": "数据质量预检:扫描 preferences_json 的格式分布,统计异常类型和比例",
"expected_output": "JSON 格式验证报告:有效行数、异常行数、异常类型分类及示例",
"fallback": "若异常率 > 1%,暂停并上报异常分布,等待人工决策清洗规则",
"estimated_cost": { "tokens": 800, "time_sec": 45 }
},
{
"id": 2,
"action": "创建目标表 DDL + 小批量测试迁移(1000 行样本)",
"expected_output": "DDL 执行成功;样本迁移行数与预期匹配;约束校验通过",
"fallback": "若样本校验失败,修正 DDL 后在 staging 环境重新测试",
"estimated_cost": { "tokens": 600, "time_sec": 30 }
},
{
"id": 3,
"action": "分批迁移(每批 100K 行,含行数校验和约束检查)",
"expected_output": "每批完成后行数匹配、无约束违反、无主键冲突",
"fallback": "单批失败 → 仅回滚该批次,记录失败行 ID,调整批次大小后重试",
"estimated_cost": { "tokens": 400, "time_sec": 2400 }
},
{
"id": 4,
"action": "添加外键约束 + 创建查询覆盖索引",
"expected_output": "约束创建成功,EXPLAIN 验证索引被关键查询使用",
"fallback": "若外键失败,执行孤儿记录查询,输出待人工处理的异常清单",
"estimated_cost": { "tokens": 300, "time_sec": 120 }
},
{
"id": 5,
"action": "切换读路径 + 双写验证(新旧表数据一致性检查)",
"expected_output": "随机抽样 1 万行,新旧表数据 100% 一致;QPS 无显著波动",
"fallback": "若一致性低于 99.9%,回滚读路径至旧表,输出差异清单",
"estimated_cost": { "tokens": 500, "time_sec": 300 }
}
],
"success_criteria": "user_preferences 行数 == users 中 preferences_json IS NOT NULL 的行数,且所有外键约束创建成功",
"abort_conditions": [
"任意批次出现主键冲突(非重试可恢复)",
"迁移期间 QPS 下降超过 20%(锁竞争过大)",
"孤儿记录数量超过 1000 行(数据质量问题超出预期)"
]
}
人类审查(2 分钟):工程师审查 Plan,发现步骤 1 的 fallback(异常率 > 1% 则暂停)是正确的风险控制决策——批准。
步骤 1 执行结果(数据质量预检,耗时 38 秒):
总行数:4,200,000
有效 JSON(可直接迁移):4,117,800(98.0%)
异常行分布:
- NULL 值(preferences_json IS NULL):无(已在 WHERE 条件排除)
- 格式异常(JSON 解析失败):3,200 行(0.08%)
- 空 JSON {}:18,400 行(0.44%)
- 顶层字段为 null({preferences: null}):61,200 行(1.46%)
异常总计:82,800 行(1.97%)
步骤 1 的 fallback 条件触发(异常率 1.97% > 1%)。Plan 暂停,上报人类。
动态修正:工程师查看异常分布,确认清洗规则:
- 格式异常(3,200 行)→ 跳过,记录到审计表
- 空 JSON(18,400 行)→ 迁移为空记录(插入行但无偏好键值对)
- 顶层字段为 null(61,200 行)→ 视同空 JSON,迁移为空记录
同时发现:异常中有 1,200 行的 user_id 在当前 users 主键列表中不存在(历史孤儿记录)——这是策略 A 第 8 轮才发现的问题,在策略 B 的步骤 1 中已被捕获。
在步骤 1 和步骤 2 之间插入新步骤 1.5:
{
"id": "1.5",
"action": "异常数据预处理:按清洗规则分类处理 82,800 行异常行",
"expected_output": "清洗规则应用后:3,200 行写入审计表、79,600 行转换为空记录格式、1,200 孤儿行隔离至审查队列",
"fallback": "若清洗后总可迁移行数与预期不符,暂停并输出差异清单",
"estimated_cost": { "tokens": 700, "time_sec": 90 }
}
人类批准这一局部修正(30 秒),修正后的 Plan 继续执行。
步骤 2–5 执行轨迹:
- 步骤 1.5(90 秒):异常数据预处理完成,79,600 行转换成功,1,200 行孤儿记录隔离,3,200 行写入
migration_audit表 - 步骤 2(25 秒):DDL 创建成功,1000 行样本迁移验证通过
- 步骤 3(42 批次,每批 100K 行,合计约 40 分钟):分批执行,每批验证通过,无单批失败
- 步骤 4(85 秒):外键约束创建成功(孤儿记录已在步骤 1.5 隔离,不阻塞约束创建)
- 步骤 5(4 分钟):双写一致性检查通过(100% 一致),QPS 波动 < 5%
结果:执行 7 轮(含步骤 1.5),耗时约 1 小时,数据完整性 100%(4,117,600 行成功迁移 + 3,200 行审计记录 + 1,200 行孤儿记录隔离),外键约束成功添加,任务 满足。生产数据库 QPS 波动始终低于 5%。
两种策略的量化对比
| 维度 | 策略 A(无计划) | 策略 B(Plan + 动态修正) |
|---|---|---|
| 数据质量问题发现时机 | 第 2 轮(380 万行执行后,事务回滚) | 步骤 1(45 秒预检,零执行成本) |
| 孤儿记录问题发现时机 | 第 8 轮(尝试添加外键约束时) | 步骤 1(预检报告中同步发现) |
| 全量回滚次数 | 1 次(380 万行,约 8 分钟执行归零) | 0 次 |
| 生产数据库 QPS 波动 | 峰值 −35%(全量 INSERT 锁竞争) | 最大 −5%(分批执行) |
| 人类介入次数 | 多次(每次发现新问题后临时干预) | 2 次(初始 Plan 审批 + 动态修正批准) |
| 人类介入总时间 | 约 40 分钟(诊断 + 决策) | 约 2.5 分钟(Plan 审查 + 修正确认) |
| 总执行时间 | 约 3.5 小时(含回滚和重试) | 约 1 小时 |
| 数据完整性 | 97%(54,600 行未处理,外键未添加) | 100%(按约定规则处理全部行) |
| 任务 满足 | 否 | 是 |
监督杠杆率:策略 B 以 2.5 分钟的人类审查时间,替代了策略 A 中约 40 分钟的临时干预(且策略 A 仍以失败告终)。Plan 审查阶段的监督杠杆率约为 16:1——单位人类注意力成本在 Plan 层的产出,远高于在执行层的临时补救。
动态修正的轨迹分析
本案例中的动态修正属于 局部更新(§9.3):步骤 1 的 fallback 设计使问题在被发现的第一时刻就以低成本进入修正流程,而非等到执行失败后被动响应。
关键设计决策的对比:
| 设计决策 | 策略 A | 策略 B |
|---|---|---|
| 数据质量预检 | 无(假设数据格式均匀有效) | 步骤 1 显式预检,附触发条件 |
| 异常处理路径 | 无预设(发现后临时决策) | fallback 预定义处理规则,触发后补充 |
| 批次边界设计 | 无(全量单次执行) | 100K 行/批,每批独立验证可回滚 |
| 目标 定义 | 隐式(“完成迁移”) | 显式(行数匹配 + 约束创建成功) |
| 人类介入时机 | 被动(执行失败后) | 主动(Plan 审批 + 修正批准) |
步骤 1 的 fallback 设计体现了 §9.1 中”好的 Plan”的核心要求:不只描述”做什么”,也描述”遇到什么情况时做什么”。正是这个设计选择,将策略 A 的”第 2 轮全量回滚”转变为策略 B 的”步骤 1 预检后有序停止”——同样发现了问题,代价相差一到两个数量级。
本案例的核心工程结论:Plan 的价值不只是”减少回溯”,而是 将问题的发现时机系统性地前移——从执行层前移到规划层,从昂贵的事后修复前移到低成本的预检阶段。fallback 和 abort_conditions 的设计质量,决定了这种前移能走多远——设计精确的 Plan 能在步骤 1 的 45 秒内捕获策略 A 耗费 8 分钟才发现的问题,并以 30 秒的人类审批完成策略 A 40 分钟临时干预都未能解决的方向校正。