算法可视化与交互学习平台

Planning & Execution:从下一步行动到完整任务Planning Agent: Decompose, Execute and Replan

No.17 用 state → action → observation 解决局部的‘下一步做什么’,No.18 把同一控制能力提升为完整任务闭环:先把模糊请求写成带验收证据的 Goal Contract,再拆成具有稳定 Step ID、输入输出契约和依赖关系的 DAG,经 Plan Validation 后调度串行与并行步骤,持续记录状态、预算和取消传播;遇到结构性失败时保留有效产物、替换失败子图并重新验收。核心浏览器实验在同一复杂任务、同一失败注入和同一预算下真实比较 ReAct only、Plan → Execute 与 Plan → Execute → Replan,并从 execution trace 计算七项指标。

RAG & AgentsAdvancedFree
1

No.17 决定下一步,No.18 对整个任务负责

No.17 的 ReAct 循环每次只回答一个局部问题:在当前 state 和 Observation 下,下一步应该调用哪个工具。复杂任务却还有另一组无法靠单步贪心自然解决的问题:哪些结果必须先拿到、哪些步骤可以同时进行、什么时候算真正完成、失败后哪些产物仍然有效,以及剩余预算是否足够继续。

No.18 的对象不是更长的聊天记录,而是一份可执行、可验证、可修改的任务计划。Planner 把 Goal 变成 DAG;Executor 只运行 ready steps;Runtime 维护状态、预算、取消和证据;Replanner 只在当前计划结构已不再可行时替换未完成子图。

层级核心问题可见产物
No.17 · local control下一步 Action 是什么?Action、Observation、局部 state transition
No.18 · global completion怎样以可验收方式完成整个任务?Goal Contract、Plan DAG、Execution Ledger、Plan Diff、Acceptance Report
2

Goal 不是一句愿望:目标、交付物、验收、约束和边界必须同时出现

一个可执行 Goal Contract 同时包含 objective、deliverables、acceptance criteria、constraints、budget 与 out-of-scope。只有 能把‘看起来完成’变成可验证完成。

Objective:任务要改变什么状态
Objective
Deliverables:必须交付的可观察产物
Deliverables
Acceptance Criteria:可机器或人工核验的完成条件
Acceptance criteria
Constraints:技术、权限、顺序和质量约束
Constraints
Budget:时间、token、费用和工具调用上限
Budget
Out of scope:明确不解决的内容
Out of scope

Acceptance Criterion 先声明证据要求

Goal Contract 只定义需要哪类 evidence 以及怎样判定通过;此时 Plan 尚未生成,不应提前引用任何 Step ID。随后由 Plan.acceptance_coverage 把 AC 映射到具体 step、output 与 predicate。

Goal.AC2.evidence_required.type = automated_test Goal.AC2.predicate = csv_special_characters == passed Plan.acceptance_coverage.AC2 = S7.test_report + predicate

约束参与规划,而不是写在备注里

如果用户要求不进入多 Agent,那么任何 delegation step 都应在 Plan Validation 阶段被拒绝,而不是执行后再解释。

scope_guard(plan) = all(step.capability not in X)
3
Goal contract lab

实验一:把模糊请求改写成 Executor 能验收的 Goal Contract

从熟悉的“待办清单导出 CSV”开始:用六个问题补全 Goal,运行普通列表、空列表与特殊字符验收样例,再展开查看完整 goal-contract.yaml。Goal 先声明 evidence requirement,Plan 才负责把 AC 映射到具体 step.output。

1 · 用户的原始请求

“给待办清单加一个导出功能,保持现有页面风格。”

“导出什么、什么格式、空列表怎么办、怎样证明原功能没坏”都没有答案,因此 Executor 现在还不能安全开始改代码。

2 · 先改写成一句可验收目标

让用户把当前筛选后的待办任务下载为 CSV;正常列表、空列表和特殊字符都能正确处理,并且现有功能与构建保持通过。

用户结果得到可重新解析的 CSV
质量底线4 条 AC 全部有真实证据
明确不做导入、云端与权限系统
3 · 用六个问题补全 Goal Contract
Objective · 目标

用户最终能够做什么?

从当前待办清单下载一个 CSV 文件。

为什么要写:描述任务完成后发生的状态变化,而不是先规定按钮写在哪个组件里。

goal-contract.yaml → objective
4 · 用具体输入运行验收条件
AC1 · Given / When / Then

普通列表

尚未运行
Given · 输入3 条可见任务,顺序为:写周报 → 修复测试 → 发布版本
Then · 期望下载 todo-list.csv;表头正确;数据行数为 3;顺序与页面一致。
点击运行后才产生 Observation;未运行不能预填为成功。
Goal 层只定义“需要什么证据”。它写 typepredicate,但此时还没有 S1、S2 等步骤,所以不应提前引用 step.output
Plan 层随后补覆盖映射:
acceptance_coverage:
  AC1: S7.test_report → csv_normal_export == passed
  AC2: S7.test_report → csv_special_characters == passed
  AC3: S7.test_report → csv_empty_list == passed
  AC4: S7.test_report → regression_tests && build == passed
4

Task decomposition 的最小单位不是动词,而是可验收的状态变化

“研究一下”“处理代码”“看看是否正常”看似是步骤,实际没有清晰的输入边界和结束条件。一个可调度步骤至少要回答四件事:消费什么、产生什么、由什么证据证明成功、失败会影响哪些后继。下面继续使用 G-TODO-CSV,不再切换任务。

模糊分解可执行分解为什么更好
理解需求不再新建 Step;已完成的 goal_contract 作为 initial_artifactPlan 消费 Goal,而不是在 S1 里重新解释或改写 Goal
检查项目S1“检查项目结构与待办数据”:输入 goal_contract + existing_project,输出 project_map + todo_data_contract把现有项目和待办数据边界变成可消费事实
查规则、看风格S2 输出 csv_rules;S3 输出 style_contract二者只依赖 S1,可以并行并在 S4 汇合
设计并修改多个文件S4 输出 csv_export_contract + change_design;S5 输出 csv_exporter;S6 输出 export_uiS5/S6 可并行,也能在契约漂移后单独修复
跑一下测试S7 输出 test_report;S8 消费它并输出 acceptance_report测试证据与最终验收分开,失败时能取消失效的 S8

分解粒度也不能无限变小。把每一行代码拆成 step 会让规划、状态更新和验证开销超过执行收益。经验规则是:当产物能被独立验证、依赖、重试、取消或并行时,才值得成为单独步骤。

5
Plan schema walkthrough

Plan Schema 把任务叙述变成 Runtime 可以拒绝、调度和追踪的数据

继续使用实验一的“待办清单导出 CSV”:阅读与后续 Runtime 共用的完整 P1 / S1–S8 plan.json,按七个语义组逐行理解计划身份、预算、Step ID、依赖与输入、输出契约、失败策略和 AC1–AC4 验收覆盖;同时解释 P / v / G / S / AC / ID / DAG 以及 JSON 符号。

沿用实验一的同一个例子
Goal · G-TODO-CSVPlan · P1 · v1Runtime 先验证,再调度

左侧是可以保存为 plan.json 的完整文件。选择右侧七个语义组,文件中的对应行会同步高亮;先理解“这一组行回答什么问题”,再看字段名。

plan.json
完整 Plan definition · 点击带颜色的代码行也可切换解释
8 steps · 4 AC
01{
16 "steps": [
17 {
37 },
38 {
58 },
59 {
79 },
80 {
104 },
105 {
126 },
127 {
148 },
149 {
171 },
172 {
192 }
193 ],
216}
01 · Plan identity

Runtime 正在执行哪份计划?它服务于哪个 Goal?

人话schema_version 说明文件格式;P1 是第 1 份 Plan;version: 1 表示当前为 v1;goal_ref 把这份计划绑定到上一张卡的 G-TODO-CSV。Replan 会产生 v2,但不应偷偷改掉 Goal。
Runtime 检查
  • plan_id 必须唯一且非空
  • version 必须为正整数,并在 Replan 时递增
  • goal_ref 必须能解析到真实存在的 Goal Contract
缺少后的后果Runtime 无法区分旧计划与新计划,也无法判断执行证据究竟在证明哪个 Goal。
最容易混淆的两个字段
depends_on: ["S5", "S6"]检查步骤状态S5、S6 是否都已经成功?它决定 S7 在 DAG 上能否进入 ready。
consumes: ["csv_exporter", "export_ui"]检查产物是否存在两个可用 artifact 是否真的已登记?它决定 S7 拿到的数据是否完整。

两者不能互相替代:前置步骤可能显示 succeeded,却没有产出约定 artifact;也可能 artifact 来自初始输入,并不要求先执行某个步骤。

缩写与符号怎么读
P1Plan 1

第 1 份计划的 ID

v1Version 1

计划的第 1 个版本

GGoal

目标契约前缀

SStep

步骤 ID 前缀

ACAcceptance Criterion

验收条件前缀

IDIdentifier

稳定且唯一的标识符

DAGDirected Acyclic Graph

有向无环依赖图

{} = 一个带命名字段的对象
[] = 一个列表;空列表表示“没有”
: = 左边字段名对应右边的值
读完这张卡后再进入下一张:Plan definition 只说明“准备怎样完成”;真正执行时,Step 的 pending / running / succeeded / failed、实际成本与证据会写入独立的 Execution Ledger,不能回写覆盖这份计划文件。
6

Step ID 与输出契约是跨执行、重试和 Replan 的引用坐标

S7 不只是显示序号。完整引用坐标是 plan_id / version / step_id / attempt,例如 P1 / v1 / S2 / #1。Trace、日志、预算、依赖边、验收条件和取消事件都通过它指向同一次逻辑执行;Step ID 在一个 plan version 内必须唯一,并且一旦产生可消费输出就不能被静默复用。

情形正确处理禁止行为
S2 CSV 检索瞬时超时记录 S2#1 failed、S2#2 succeeded;逻辑 ID 仍映射 S2假装第一次调用没有发生
S7 暴露输入契约漂移保留 S1–S6 的历史与仍有效产物,新增 R1/R2/R3,并把 S8@v1 标记 cancelled直接覆盖 S7 的失败记录
成功产物仍有效以 immutable artifact reference 复用;R2 只添加增量 contract_fixReplan 时重跑所有已成功步骤
旧后继失效显式 cancelled / superseded,并传播到尚未分派的后代让旧步骤和新步骤同时提交结果

输出契约还应说明结构、版本、来源和完整性。例如 test_report@v2 不只是“测试通过”四个字,而是包含 suite、exit code、AC1–AC4 predicate 结果、artifact hash 与生成它的 plan version。

7
Executable plan validator

实验二:向 Plan 注入环、缺失依赖和断裂输出,观察 Validator 在执行前拒绝

先把 Validator 理解为“开工前检查图纸”:对照正确的 P1 / S1–S8 基线,再分别注入循环等待、不存在的 S99,以及 S7 输入与 AC4 证据断裂。每次都沿着“改了什么 → 为什么无法开始 → 错误码的白话含义 → 最小修复”追踪因果,并区分依赖步骤与输入产物。

当前验证对象G-TODO-CSVP1 · v1 · S1–S8
先理解:Validator 是开工前的图纸检查

它不会生成 CSV、修改文件或运行测试,只读取 Plan,判断“有没有可能按这张图开始并走到验收”。如果结果是 INVALID,Runtime 会在派发第一个 Step 之前拒绝计划,因此执行步数与执行预算消耗都为 0。

01 · 等待谁
depends_on

前置步骤必须真实存在并成功结束

02 · 拿到什么
consumes

所需 artifact 必须来自初始材料或祖先输出

03 · 如何验收
acceptance_coverage

每条 AC 必须能定位到真实证据

READY(step) = 所有 depends_on 已成功 + 每个 consumes 都已存在
正常基线 · 先看懂正确计划
S1 → [ S2 ∥ S3 ] → S4 → [ S5 ∥ S6 ] → S7 → S8

表示右侧必须等待左侧; 表示依赖满足后可以并行。artifact 是能被 Runtime 登记并交给下游读取的有名产物,例如 S7.test_report

相对有效 Plan,刚刚改了什么?
没有修改任何字段。这是其他三个故障都要对照的正确基线。
生活化理解:像一份材料齐全、工序没有互相等待的施工单:检查员允许把它交给施工队。
从改动到结果 · 一步一步追因果
  1. 1S1 可以直接使用 goal_contract 与 existing_project 开始工作。
  2. 2每个 depends_on 都指向真实步骤,而且依赖关系中没有环。
  3. 3每个 consumes 都能在初始材料或祖先步骤的 produces 中找到。
  4. 4AC1–AC4 都能追溯到 S7.test_report。
最小修复:无需修复。Validator 允许 Runtime 把计划交给 Executor;这只证明结构可执行,不保证运行时永不失败。
validation result
允许执行VALID
静态检查通过 60
60

结构检查通过,可以派发 Step;运行时仍可能遇到 timeout 或测试失败。

一种合法先后清单 · Topological order

它证明依赖可以排开,不代表所有步骤必须串行;S2/S3 与 S5/S6 的并行排程会在下一实验展开。

受影响步骤的 contract
切换故障会自动定位到关键步骤,也可以手动查看其他 Step
depends_on
要等待哪些步骤成功
consumes
开始时必须拿到哪些产物
{
  "id": "S1",
  "depends_on": [],
  "consumes": [
    "goal_contract",
    "existing_project"
  ],
  "produces": [
    "project_map",
    "todo_data_contract"
  ],
  "estimate": {
    "duration_ticks": 2,
    "cost_units": 3
  },
  "policy": {
    "cancellable": false,
    "on_failure": "stop"
  }
}
依赖存在、无环、每个 input 都能在祖先 output 中找到,并且验收证据可达。计划可以交给 Executor。
8

Plan Validity 是多项硬约束的合取,不是 Planner 的自评分

只有所有硬约束同时成立,Plan 才能进入执行。估算接近上限可以是 warning;超过扣除 Replan reserve 后的可执行预算,以及环、缺失依赖、输入输出断裂或不可达验收证据,必须是 error。

Step ID 在版本内唯一且格式稳定
Unique stable step identifiers
每条 depends_on 都指向存在且非自身的步骤
Dependencies exist and are not self references
依赖图可拓扑排序
The graph is acyclic
每个输入都能由 initial_artifacts 或祖先输出提供
Inputs are supplied by initial artifacts or ancestor outputs
每条验收条件都有可达证据
Acceptance evidence is reachable
估算不违反时间、成本、权限与 scope
The plan is feasible under constraints

Dependency Satisfaction 在运行时再次检查

静态 Validity 只证明计划结构可能执行;真正分派某步前仍要确认所有依赖已 succeeded 且所需 artifact 可读。

ready(s)=∀d∈deps(s): status(d)=succeeded ∧ ∀x∈inputs(s): artifact_store.has(x)

Validator 必须独立于 Planner

让产生 Plan 的同一自由文本输出自行宣布 valid,会把遗漏的依赖误当成不存在的约束。Runtime 应依据 schema 与独立 oracle contract 检查。

9

DAG 只表达先后必要性:没有依赖边,不等于一定要并行

在有向无环图中,边 S2 → S4 表示 S4 必须等待 S2 的 csv_rules;它不表示二者属于不同 Agent,也不表示 Runtime 一定拥有足够资源。并行首先由依赖允许,然后还要通过资源锁、预算预留、并发上限和副作用冲突检查。

S1 检查项目结构与待办数据
├─ S2 检索 CSV 规则 ─────┐
└─ S3 检查交互与页面风格 ─┴→ S4 设计 CSV 导出契约
                               ├─ S5 实现 CSV 逻辑 ─┐
                               └─ S6 接入导出按钮 ──┴→ S7 测试 → S8 验收
概念Runtime 判断本实验例子
Ready Set依赖成功、输入齐备、预算已预留S1 完成后 S2 与 S3 同时 ready
Serial barrier必须汇合多个分支S4 等待 S2 + S3;S7 等待 S5 + S6
Resource conflict即使无依赖也不能安全并发S5/S6 若同时修改同一组件,需要文件锁或重新分解
Cancellation propagation失败依赖让后继 blocked;结构替换让旧后继 cancelledS7 failed 后 S8@v1 不可继续
10
DAG scheduler & critical path

实验三:在同一 DAG 上切换全串行与依赖并行,并高亮 Critical Path

在同一个 Todo CSV P1 上点击任意节点检查 consumes / produces,切换调度模式观察 makespan 从 26 降到 18 ticks;紫色节点构成决定最短完工时间的 Critical Path。

同一计划继续P1 · G-TODO-CSVS1–S8 · 串行工作量 26 ticks
工作量 26 ticksCritical Path 18可节省 8
↓ dependencies satisfied
↓ dependencies satisfied
↓ dependencies satisfied
↓ dependencies satisfied
↓ dependencies satisfied
Earliest-start schedulemakespan = 18
S1
S2
S3
S4
S5
S6
S7
S8
Selected stepS5 · 实现 CSV 生成逻辑
Inputscsv_export_contract + change_design
Outputscsv_exporter
11

Critical Path 给出无限资源下的时间下界,优化非关键步骤不一定更快

拓扑顺序中逐步计算 earliest start 与 earliest finish,最终最大值就是关键路径长度。串行总工作量是 ,当前 DAG 的

步骤 s 的最早开始时间
Earliest start
步骤 s 的最早结束时间
Earliest finish
步骤持续时间估算
Step duration
依赖约束下的理论最短 makespan
Critical-path duration

本实验的关键路径

S2 比 S3 慢 1 tick,S5 与 S6 等长,因此有两条同长关键分支。界面选择其中一条作为可解释的 backpointer path。

S1(2) → S2(4) → S4(3) → S5(5) → S7(3) → S8(1) = 18

Critical Path 会随 Replan 改变

插入 R1/R2/R3 后必须重算,而不能沿用 Plan v1 的时间下界;否则 Parallel Efficiency 会被错误夸大。

12

Plan-and-Execute 不是生成列表后照单全做,而是一个持续验证的调度循环

  1. Plan:从 Goal Contract 生成 versioned DAG 与每步输出契约。
  2. Validate:检查 ID、依赖、环、契约、验收覆盖和预算可行性;INVALID 时禁止执行。
  3. Schedule:从 Ready Set 中选择不冲突的步骤,先预留预算,再并行 dispatch。
  4. Observe:只接受真实工具或代码运行产生的 output artifact;写入 append-only Ledger。
  5. Update:把 succeeded / failed / cancelled 传播到后继,重新计算 ready、blocked 和剩余预算。
  6. Accept:没有 ready steps 不等于成功;还必须逐条验证 Goal Acceptance。

No.17 的行动循环可以嵌入第 3–4 步,用于完成某个复杂 step;No.18 的 Scheduler 不替代工具选择,而是为每次局部行动提供全局依赖、预算和完成语境。

13

Execution Ledger 让每一步从 pending 到终态都可追踪,blocked 只是依赖派生状态

pending → ready → running → succeeded
                         ├→ failed
                         └→ cancelled

blocked = pending AND any(dependency ∈ {failed, cancelled})

blocked 不应覆盖成一个不可逆的主状态:Replan 可能替换失败依赖,使原本 blocked 的目标重新可达。真正的 Ledger 需要记录事件序列,而不是只保存每步最后一个字符串。

事件字段用途不能省略的原因
plan_version + step_id + attempt唯一定位一次执行区分 S2#1 超时与 S2#2 成功
started_at / ended_at / lane计算 makespan 与并行效率只看顺序号无法证明并发
input_refs / output_refs验证 Dependency Satisfaction不能依赖 Planner 自报
reserved_cost / actual_cost预算 guard 与退款取消步骤可能释放未消费预算
reason / error_class选择 retry、replan 或 stop所有失败都重试会形成循环

对有副作用的步骤还需要幂等键、提交边界和补偿策略。取消一个“尚未分派”的步骤很安全;取消一个已经写入外部系统的步骤,可能只能停止后续工作并执行补偿,而不能假装它从未发生。

14

失败后先分类:Retry 修复一次执行,Replan 修复任务结构

失败类型Plan 仍可行?首选动作Todo CSV 例子
瞬时工具失败在 retry policy 内重试同一逻辑步骤S2 检索 CSV 规则 timeout,输入和输出契约未变
参数或格式错误通常是修复参数后重试;保留错误 ObservationCSV 检查器收到错误的 delimiter 参数类型
结构性契约漂移Replan 未完成子图S6 的 export_ui 传 filtered_tasks,而 S5 的 csv_exporter 仍读取 all_tasks
目标或约束改变生成新 Goal/Plan version 并重新验收用户把“浏览器本地导出”改成“云端定时导出”
不可恢复或预算不足取消后继并受控停止剩余预算不足以重新测试并生成 acceptance_report

Replan 不是“再想一次”的同义词。如果新计划没有可见 diff,没有说明哪些成功产物被保留、哪些旧后继被淘汰、预算怎样重新分配,那么它只是一次不可审计的重试。

15

Replanning 的输入必须包含失败证据、不可变成功产物和剩余预算

Replanner 依据同一个 Goal、当前 Plan、Execution Ledger、失败 Observation、仍有效的成功 artifacts 与剩余预算,生成只替换未完成子图的新版本。

当前计划版本及其 DAG
Current plan version
截至失败时的 append-only Execution Ledger
Execution ledger
结构化失败 Observation 与错误分类
Failure observation
仍满足契约的不可变成功产物
Still-valid successful artifacts
扣除已花费和已预留资源后的剩余预算
Remaining budget

最小改图原则

先求失败节点的受影响后继闭包,只替换其中尚未成功且输出已失效的部分。

replace_set = descendants(failed_step) ∩ not_succeeded preserve_set = succeeded ∩ contract_still_valid

新版本仍必须验证

Replanner 不是 Validator 的例外。Plan v2 仍要通过无环、输入输出、验收覆盖和预算检查后才能继续。

16

正确 Replan 的第一步常常是取消旧后继,而不是立刻增加新步骤

默认契约漂移场景中,S7 发现 export_ui 与 csv_exporter 的输入契约不一致,因而没有产生可信 test_report;S8@v1 已经失去可用输入。Runtime 先把它标记为 cancelled,随后 Plan v2 插入 R1 定位边界、R2 生成增量 contract_fix、R3 只重跑受影响测试,最后创建 S8@v2。

Plan v1: S5 csv_exporter + S6 export_ui → S7 failed → S8 blocked
                                               │
                                               └─ cancel S8@v1

Plan v2: preserve S1…S6 → R1 diagnose → R2 repair → R3 test → S8@v2
保留取消 / 替换为什么
G-TODO-CSV、S1 project_map + todo_data_contract、S2 csv_rules、S3 style_contract不重跑失败没有使这些输入和知识失效
S5 csv_exporter 与 S6 export_ui保留原 artifact,R2 生成增量 contract_fix便于审计接口 diff,避免覆盖历史
S7 failed event不删除,R3 生成新 test_reportRecovery 指标需要失败证据
旧 S8cancelled,不能复活同一 attempt它引用的是缺失的 test_report
17

预算要在分派前预留,并为诊断与 Replan 留出恢复空间

预算不仅覆盖成功路径。Runtime 在步骤开始前预留 estimate;若剩余预算不足,就取消尚未分派的步骤并返回 budget_exceeded,而不是先超支再统计。

生成与验证 Plan 的成本
Planning cost
每个步骤的预留与实际成本
Per-step budget
失败诊断、改图与再次验证的成本
Replanning budget
不可预见恢复与最终验收保留量
Contingency reserve
扣除已用与正在预留后的可用预算
Available unreserved budget

为什么默认预算是 40

Plan v1 的正常成功路径成本为 31。契约漂移时,S1–S7 的已用成本为 30;R1/R2/R3 与 S8@v2 再用 9,总计 39,仍有 1 unit 余量。ReAct only 因提前接入按钮和重复检查需要 41,恰好在最终验收前被 guard 停止。

Plan→Execute→Replan = 30 + 2 + 3 + 3 + 1 = 39 ReAct only = 41 > 40

Budget Exceeded Rate 的含义

硬 guard 不允许真实花费超过上限;指标统计的是因预算不足而终止的 trials / 总 trials,而不是超限了多少资源。

18

核心实验先冻结公平性:三种策略只能改变控制方式,不能改变任务真值

三种策略继续共享实验一的同一个 G-TODO-CSV:检查项目与待办数据,并行获得 CSV 规则和页面风格,设计导出契约,并行实现 csv_exporter 与 export_ui,运行测试,最后按 AC1–AC4 验收。从 Goal 到核心实验始终只有这一项任务。

固定项三种策略完全相同
Goal 与验收同一个 G-TODO-CSV、AC1–AC4 与独立 oracle
步骤真值同一 S1–S8 拓扑、artifact contract、耗时和成本;不让某策略得到更便宜的工具
Failure injection无故障、S2 一次 CSV 规则检索 timeout、或 S7 发现 export_ui / csv_exporter contract drift
预算30 / 40 / 48 units,分派前使用同一 guard
指标全部从同一 PlanningEvent trace 计算;N/A 不冒充 0

唯一自变量是控制策略:ReAct only 逐步选择局部动作且没有显式全局 Plan;Plan → Execute 先生成并验证固定 DAG;Plan → Execute → Replan 允许在结构性失败后取消旧分支并提交有效 Plan v2。

19
Core experiment · same task, three strategies

核心实验:同一复杂任务比较 ReAct only、Plan → Execute 与 Plan → Execute → Replan

在同一个 G-TODO-CSV / P1 / S1–S8 上选择失败注入与总预算,运行 deterministic Planning Runtime;对照总体状态、Plan 版本、成本、makespan、七项指标和逐事件 execution trace。

Failure injection

S7 发现 export_ui 与 csv_exporter 对筛选任务的输入契约不一致,需要替换失败子图。

Total budget
StrategyPlan ValidityDependency SatisfactionPlan CompletionReplan RecoveryRedundant StepsParallel EfficiencyBudget Exceeded Rate
ReAct only
Plan → Execute
Plan → Execute → Replan
Inspect execution trace
选择场景与预算后运行;未运行状态不预填成功结果。
Execution trace 尚未生成。点击“运行三种策略”后,事件、取消原因、Plan version 与预算结算会出现在这里。
读数原则:默认“契约漂移 + 40 units”故意让三种策略分叉:ReAct only 因提前接入按钮与重复检查在最终验收前耗尽预算;固定 Plan 能正确停在失败依赖上,却无法改图;Replan 取消 S8@v1、保留 S1–S6 的有效产物,只替换失败分支并完成 AC1–AC4。切换“工具超时”可看到 retry 足够时不应产生 Replan。
20

逐项读默认 trace:三个失败结果来自三种不同机制

1. ReAct only:能局部恢复,但全局冗余吞掉最终验收预算

A3 在 csv_rules 与 csv_export_contract 尚未齐备时提前接入按钮,形成一次 blocked 冗余步骤;S7 发现 export_ui / csv_exporter 契约漂移后,它又重新检查已经看过的项目与数据。它最终修复并重跑测试,却已经花完 40 units;分派需要 1 unit 的 S8 时触发预算 guard。失败原因不是模型完全不会修,而是没有全局依赖和恢复预算。

2. Plan → Execute:调度高效,但固定 DAG 不能消化结构性新事实

S2/S3 与 S5/S6 两组并行,使执行贴近 Critical Path;S7 failed 后 S8 因缺少 test_report 正确 blocked。它没有越权改图或伪造成功,因此 Plan Completion 为 75%。这是一种正确失败:系统知道 P1 v1 已经不够,却没有 Replanner 能力。

3. Plan → Execute → Replan:先取消旧下游,再最小替换失败子图

Runtime 保留 S1–S6,取消 S8@v1,插入 R1/R2/R3,并用 S8@v2 重新验收。总成本 39 小于预算 40;没有重新检索 CSV 规则或重复检查页面风格。Replan Recovery 为 100%,但只有在 contract drift 场景才有定义。

切换场景后应观察什么合理结果
S2 工具超时固定 Plan 内 retry 成功;Replanner 不产生 v2
无故障两种 Plan 策略结果相同;ReAct 仍因串行和提前尝试略慢
30 units不同策略在不同分派点触发取消;真实 cost 永不超过 30
48 units + contract driftReAct 可最终完成,但冗余和 makespan 仍高于最小 Replan
21

七项指标分别检查结构、执行、恢复、浪费、并行与预算,不能压成一个总分

Planning 质量必须从计划版本、真实执行 trace 与独立验收共同计算。ReAct 没有显式 Plan,因此 Plan Validity、Plan Completion 与 Replan Recovery 显示 N/A,而不是 0。

Plan Validity:通过完整 Validator 的 Plan versions / 提议版本
Plan validity
Dependency Satisfaction:分派时真实前置与输入均满足的步骤 / 已尝试步骤
Dependency satisfaction
Plan Completion:最终 active plan 必需步骤的成功比例
Plan completion
Replan Recovery:结构性可恢复失败后由有效新 Plan 完成验收的比例
Replanning recovery
Redundant Steps:不支持任何后继或验收的已执行步骤数,越低越好
Redundant steps
Parallel Efficiency:同一有效 trace 的 Critical Path 下界 / 实际 makespan
Parallel efficiency
Budget Exceeded Rate:被预算 guard 终止的 trials / 总 trials
Budget-exceeded termination rate

Plan Completion 不等于 Goal Acceptance

计划内步骤可能全部 succeeded,但验收证据仍不满足用户 Goal;二者必须分别计算,最终 completed 以 Acceptance 为准。

Redundant Steps 需要数据流判断

失败尝试不自动等于冗余;如果它提供了错误证据并支持正确恢复,就可能是必要诊断。真正冗余是输出未被后继或验收消费。

单次实验中的 Budget Exceeded Rate

每次选定场景相当于一个 trial,所以显示 0% 或 100%;批量 benchmark 时再对多个 trials 取均值。

22

浏览器实验的忠实缩略控制器:验证、调度、记录、取消、Replan 与验收

typescript
这段代码做什么

本卡展示核心实验同构的控制边界。上方四个实验直接运行项目内的 TypeScript Planning Runtime;这里不使用伪 Python 执行器,以免把静态示例误当成真实 DAG 结果。

按执行顺序理解与检查

Stage 1

Stage 2

Stage 3

Stage 4

Stage 5

完整可运行脚本
type Terminal = 'succeeded' | 'failed' | 'cancelled'

async function planAndExecute(goal: GoalContract, budget: Budget) {
  let plan = await planner.create(goal, budget)
  let validation = validatePlan(plan)
  if (!validation.valid) return stop('invalid_plan', validation.issues)

  const ledger = new ExecutionLedger(plan.version)
  const artifacts = new ArtifactStore()

  while (!goal.acceptance.every(ac => ac.verify(artifacts))) {
    const ready = readySteps(plan, ledger, artifacts)
      .filter(step => !resourceLocks.conflicts(step))

    if (ready.length === 0) {
      const failure = classifyBlockedPlan(plan, ledger, artifacts)
      if (!failure.recoverable) return stop(failure.code, ledger)

      const diff = await replanner.createDiff({
        goal,
        currentPlan: plan,
        ledger,
        failureObservation: failure.observation,
        immutableArtifacts: artifacts.stillValid(),
        remainingBudget: budget.remaining()
      })

      cancelSupersededDescendants(diff, ledger, budget)
      const candidate = applyPlanDiff(plan, diff)
      validation = validatePlan(candidate)
      if (!validation.valid) return stop('invalid_replan', validation.issues)
      plan = candidate
      continue
    }

    const batch = reserveWithinBudget(ready, budget)
    if (batch.length === 0) {
      cancelPending(plan, ledger, 'budget_guard')
      return stop('budget_exceeded', ledger)
    }

    const observations = await Promise.allSettled(
      batch.map(step => executor.run(step, artifacts))
    )

    for (const [index, observation] of observations.entries()) {
      const step = batch[index]
      ledger.append(toExecutionEvent(step, observation, plan.version))
      if (observation.status === 'fulfilled') {
        artifacts.commit(step.outputs, observation.value, plan.version)
        budget.settle(step.id, observation.value.actualCost)
      } else {
        budget.settleFailure(step.id, observation.reason.actualCost)
        if (isRetryable(observation.reason, step.policy)) {
          ledger.enqueueRetry(step.id, observation.reason)
        }
      }
    }
  }

  return complete({
    planVersion: plan.version,
    acceptanceReport: goal.acceptance.map(ac => ac.evidence(artifacts)),
    metrics: computePlanningMetrics(plan, ledger, budget)
  })
}
23

No.18 的完成标准:不是拥有 Plan,而是能用证据完成、失败、改图或取消

能力本模块已经闭环的判断
Goal模糊请求被改写为 deliverables、AC、constraints、budget 与 out-of-scope
Decomposition步骤以可验证输出为边界,粒度足以依赖、并行、重试和取消
PlanStep ID、input/output、DAG、估算、failure policy 与验收引用可解析
Validation执行前拒绝重复 ID、缺失依赖、环、断裂契约和不可达验收
Execution只分派 ready steps,记录 append-only Ledger,严格区分 succeeded / failed / cancelled
Replan以失败证据和剩余预算为输入,保留有效产物,最小替换未完成子图并再次验证
Evaluation三策略同任务同预算,从 trace 计算七项指标,N/A 与 0 保持不同语义

当前实现是一个确定性、单进程、单 Agent 的教学 Runtime。它没有持久化跨会话记忆,不会把工作委派给其他 Agent,也不模拟分布式队列、租约、跨机器补偿事务或生产级权限系统。这些都不是缺失的“隐藏功能”,而是明确的 scope boundary。

AI
问问 LLM:把 Goal、DAG、预算与 Replanning 解释成可执行判断

正在检查登录状态与模型配置…