Hu Wei | 2026-04 | https://arxiv.org/abs/2604.11378 Category: agent | Tags: framework, scheduling, dag, position-paper, agent-runtime Read: 2026-04-18
将 LLM agent 的执行系统统一为一个 scheduler 模型 $\mathcal{E}=(\mathcal{S},\mathcal{U},\mathcal{P},\mathcal{O},\Delta)$,用 ready-set 基数 $|\mathcal{U}|$ 把 Agent Loop 和 graph-based executor 放到同一条连续谱上,并据此提出一个牺牲表达力换可控性的静态 DAG 执行框架 Structured Graph Harness (SGH)。
Motivation:主流 LLM agent 采用 Agent Loop——单个 LLM 不断读取增长中的 context window 决定下一步。作者指出这个范式有三个结构性缺陷:(1) 步骤依赖是隐式的、不可验证的;(2) 失败恢复没有边界语义,LLM 可以无限 replan;(3) 执行计划可被 LLM 静默重写,事后无法构造忠实的 audit trail。作者在 70 个开源 agent 项目中观察到 60% 都是 Agent Loop 变体,问题不是个例。
Method:作者把所有 agent 执行系统形式化为 $(\mathcal{S},\mathcal{U},\mathcal{P},\mathcal{O},\Delta)$ 五元组,关键观察是:Agent Loop 是 $|\mathcal{U}|\le1$ 的 single-ready-unit scheduler,$\mathcal{P}$ 是 LLM 推理这个 "不可检查的非确定策略";而 graph executor 则可以达到 $|\mathcal{U}|\ge 1$。基于这个视角,作者提出 SGH——把控制流从 context 里 "拉" 到一个显式静态 DAG 里,并做三个设计承诺:(1) plan 在单个 version 内不可变;(2) planning / execution / recovery 三层严格分离;(3) recovery 遵守三级严格升级协议 local_retry → local_patch → request_replan,跳级禁止。同时形式化了节点状态机(10 个状态,证明了有界终止和 conditional soundness),以及 all_of / any_of join 语义(显式排除 first_of 竞争性并行)。
Results:这是一篇 position paper + design proposal,没有实现也没有实验数据。主要 "结果" 是:(1) 一个可比较 Agent Loop / LangGraph / Airflow / TDP 等 70 个系统的统一框架;(2) 四条设计原则和明确的牺牲/收益表;(3) 状态机的 termination 和 soundness 证明;(4) 一个七组对照的实验 protocol (G0–G6),把总增益分解为 $G_{\text{plan}}, G_{\text{scaffold}}, G_{\text{graph}}, G_{\text{patch}}, G_{\text{replan}}$ 五个可归因分量。
first_of 竞争性并行、递归子图展开、parent-chain rollback、动态拓扑修改——这些能力每一个都对应 violate 某条设计原则,不是疏忽。2025-2026 年 agent 领域正在经历从 "Agent Loop 野蛮生长" 到 "Graph orchestration 沉淀" 的拐点:LangGraph / AutoGen / CrewAI / AFlow / TDP / DynTaskMAS 都在往 graph 结构靠,但各家都只解决局部问题(LangGraph 要灵活,TDP 要 context 隔离,DynTaskMAS 要并行)。此时缺一个 能把这些系统放在同一尺度上比较的理论框架——这就是本文的时机位。它不是一个新系统,而是一个 命名和坐标系,相当于把 "为什么 Agent Loop 不够用" 从工程直觉升格为 $|\mathcal{U}|\le1$ 的形式化命题。
作者实质上在做一个 "为什么不可 X" 的穷举:
first_of 竞争性并行? 两个原因:(a) loser cancellation 需要 compensation protocol 回滚副作用,引入新失败模式;(b) commit-point 歧义——A 先成功但 B 可能质量更高,语义不明确。这些约束最终 "挤" 出了 SGH 的设计空间:静态 DAG + all_of/any_of + 三级 recovery + plan versioning。每个排除都映射到某条原则,不是任意选择。
可行性矩阵(简化版,基于论文 Table 6/7):
| Approach | Multi-ready | Deterministic $\mathcal{P}$ | Bounded recovery | Immutable plan | LLM-aware |
|---|---|---|---|---|---|
| Agent Loop | ✗ | ✗ | ✗ | ✗ | ✗ (隐式) |
| Plan-and-Act | ✗ | ✗ | ✗ | 部分 | 部分 |
| TDP | ✗ | ✗ | ✗ | mutable | 部分 |
| LangGraph | ✓ | semi | ✗ | mutable | 部分 |
| Airflow/Luigi/Prefect | ✓ | ✓ | ✓ | ✓ | ✗ |
| SGH | ✓ | ✓ | ✓ | ✓ | ✓ |
SGH 是唯一同时满足五列的位置。
"Agent Loop 不是一种特别的架构,它就是 $|\mathcal{U}|=1$ 的一种 scheduler"——这个 reframing 是全文的 aha moment。一旦换上 scheduler 视角,经典 DAG scheduling 半个世纪的积累(list scheduling、Kahn 拓扑、HEFT、critical path、2-1/m 近似比)立刻可以被复用到 agent 执行上。类比:相当于有人指出 "你们讨论的并不是'agent怎么思考',而是'下一个该执行哪个单元'——这本质是一个 OS scheduler 问题,而你们把它交给了一个 opaque 的 LLM。"
全文最硬核的一块不是 DAG 本身(这是 1960 年代的东西),而是 "在非确定 LLM 节点 + contract 验证不可靠"这两个约束下,如何仍然证明 bounded termination 和 conditional soundness。Theorem 6.2 的证明思路是:每个节点有 $\tau_v$ 超时 + $b_v$ 重试预算 + terminal state 绝对不可逆,把无限循环的可能性结构化地关进了 $\sum_v \tau_v\cdot(b_v+1) + \sum T_{\text{human}}$ 这个上界。Theorem 6.3 的 validation gap $\Pr\ge \prod p_v$ 则诚实地把 "contract 验证错误" 这个通常被业界忽略的失败模式显式写进了正确性 bound 里。这个 "bounded termination 可证 + validation gap 公开" 的组合,是把 SGH 和那些只在 README 写 "we handle retries" 的 graph 框架区分开的核心壁垒。
all_of / any_of 足以覆盖工程任务。作者在 §9.9 自己承认 report 节点的 all_of 过度序列化;实际上 LLM agent 面对的很多场景天然是 streaming / incremental 的,DAG 粒度无法轻易表达。SGH 强制绑定了以下前提:
run_shell 可以 read-only 也可以 rm -rf)。如果任务是长期 open-ended(比如 autonomous research),上面任何一条都不成立,SGH 不适用。
一个任务在 SGH 下的完整生命周期:
any_of 必须有 $\ge 2$ 候选)、contract well-formedness、side-effect consistency。pending → ready → running。running → executed,否则 running → failed_retryable 或 failed。recovery_state[v];pristine 时只允许 attempt_retry,retried 后才能 attempt_patch,patched 后才能 request_replan——跳级在 API 边界被直接拒绝。这篇是 2026-04 的 position paper,暂无下游采用记录。它的潜在影响路径有两条:(1) 作为学术语言被后续 graph agent 论文引用,把 "scheduler continuum" 变成标准坐标;(2) 作为工程参考,被 Claude Code / Codex / Devin 这些需要可审计性的 coding agent 借鉴 "plan versioning + three-level recovery"。值得关注的是作者自己指出的 companion paper(Evolutionary Graph Architecture),如果出来会是真正的实验验证。

What it shows: 一个 Python bug fix 任务被分解为 10 个节点的 DAG:search_auth / search_utils 并行(蓝色 wave 1),各自触发 read_auth / read_utils 并行(绿色),汇合到 analyze,再扇出到 fix_A / fix_B / update_docs 三路并行,fix_A / fix_B 用 any_of join 接到 run_tests,最后 run_tests 和 update_docs 用 all_of 接到 report。
Why it matters: 这是全文唯一的 "soul diagram"。它同时展示了三个 SGH 核心能力——structural parallelism(搜/读两波并行,$|\mathcal{U}|=2$ / $3$)、alternative paths(any_of 让 fix_A/fix_B 任一成功即可,不用无脑重试)、explicit all_of dependency(analyze 必须等两个 read 都完成)。作者把同一任务在 Agent Loop 下跑成 11 轮串行,在 SGH 下跑成 6 个 scheduling round,直接把 "graph gain" 可视化出来。
Detailed description: 两个入口节点 search_auth / search_utils 无 predecessor。它们分别连接到 read_auth / read_utils,形成两条独立链。两条链在 analyze 用 all_of 合流。analyze 扇出到 fix_A / fix_B(都标 any_of——论文意思是它们是 run_tests 的 any_of candidates,不是 analyze 的子节点语义),同时扇出到 update_docs。fix_A / fix_B 的 any_of 边汇合到 run_tests,run_tests 和 update_docs 的 all_of 汇合到 report。论文标注了两次 $|\mathcal{U}|$ 扩张:第一波 searches 并行 ($|\mathcal{U}|=2$),第二波 fix+docs 并行 ($|\mathcal{U}|=3$)。
side_effect_level 和 waiting_human 状态。高副作用节点可要求人工审批,超时 $T_{\text{human}}$ 自动 cancel。
What it shows: 从左到右排列 5 种 agent 执行范式——Naive Loop → Parallel Loop → Planner Loop → Structured Loop → Graph Harness。每种标注 $|\mathcal{U}|$ 和 policy 类型。
Why it matters: 这张图是 "scheduler continuum" 理论的视觉载体,也是作者最想传播的概念图。它把 Agent Loop(1-ready,non-det)、parallel tool calls($\ge 1$-ready 但 non-det)、加 planner / scaffold 的系统(仍然 1-ready)、和真正的 SGH($\ge 1$-ready + det)放在同一条轴上,让读者一眼看出:加 planner、加 scaffold 只在 policy 轴上前进,只有真正的 graph 才能跨进多 ready 单元的象限。这直接支撑了 §3.4 的核心论点。
Detailed description: 图中 5 个方块横向排列,下方标注 "Policy explicitness and determinism" 方向。左起:Naive Loop($|\mathcal{U}|=1$, Non-det, Sequential)、Parallel Loop($|\mathcal{U}|\ge 1$, Non-det, Parallel calls)、Planner Loop($|\mathcal{U}|=1$, Non-det, Planner)、Structured Loop($|\mathcal{U}|=1$, Semi-det, Scaffold)、Graph Harness($|\mathcal{U}|\ge 1$, Det, Graph)。注意 Parallel Loop(OpenAI tool_calls)被单列出来,强调它虽然并行但策略仍不显式。
N/A — SGH 是 single-agent runtime 架构,只是把 planner / executor / recovery 三个 role 分层而已。论文 §2.3 讨论过 AutoGen / CrewAI 的 multi-agent,但作者归类它们为 $|\mathcal{U}|=1$ 或 semi,并认为 multi-agent 本质上仍可以被 scheduler 框架描述——"agent count" 不是 SGH 关心的轴。
| Layer | 影响 |
|---|---|
| Algorithm | 不直接涉及训练。间接:plan-version trace 可作为高质量 agent SFT/RL 数据格式。 |
| Kernel | 不涉及。多 ready 并发对 serving 侧意味着要吃 prefix cache(节点间共享 system prompt)、continuous batching。 |
| Framework | 核心影响层。serving 需要把每个 node 看成独立 request,且支持 plan-level 共享 prefix;agent framework 需要提供 DAG validator、state machine 实现、recovery 升级状态机、append-only WAL、token-bucket rate limiter。 |
| LLM | 对 function calling / JSON mode / structured output 的稳定性要求高,因为 contract validation 直接决定 retry 行为。模型规模上 planner ≫ executor 是自然的分层。 |
| Cost | 相比 Agent Loop:token 消耗因 context 隔离而降低(参照 TDP 82% 削减),但节点数多 + 并发 LLM 调用 → peak QPS 更高、总 tokens 不一定少。对 task-level 成本的影响是任务依赖的。 |
waiting_human 状态做审批。
What it shows: planner / runtime / recovery 三层的接口关系:planner 产出 $\Pi$ 给 runtime,runtime 执行不改 $\Pi$,failure 往上报到 recovery,recovery 决定 recovery action 或 request_replan 回到 planner。
Why it matters: 这张图把 Principle 2(stable commitment)变成一张架构图。读者能立刻看出:runtime 不接触 plan 结构,只消费;recovery 不接触 runtime 内部,只看 failure report 和 diagnostic context;planner 不接触 runtime 实时状态。这是 SGH 相对 LangGraph(runtime 可改图)、TDP(planner 可动态加 task)的本质区别。
Detailed description: 三个矩形垂直排列——顶部 Planner Layer(generates $\Pi$)、中部 Runtime Layer(executes $\Pi$ without modification)、底部 Recovery Layer(diagnoses failures, selects recovery action)。三条有向边:Planner → Runtime 传 $\Pi$;Runtime → Recovery 传 failure report;Recovery → Planner 传 "request replan" 请求(仅在 Level 3 时触发)。关键是 Runtime → Planner 没有直接边——runtime 不能把中间结果 push 回 planner 做动态 replan。

What it shows: 10 个状态的节点状态机,4 个 terminal 态 {executed, failed, cancelled, skipped} 用灰色标注;转移边标注 trigger 条件(deps met / dispatch / success / timeout / retry / exhausted / dep lost / sibling done / transient err / structural err)。
Why it matters: 这是 SGH termination 证明的基石。Theorem 6.2 的证明完全基于这张图的结构——terminal state 无出边(absorbing)+ 每个非 terminal 态必有一条通往 terminal 的路径 + $\tau_v$/$b_v$ 有限。如果这张图里任何一个 terminal 态加了出边,bounded termination 就破。论文把这张图当作 "formal object" 来证明,而不仅仅作图示。
Detailed description: 节点初始 pending → 条件 deps met → ready → 条件 dispatch(被 $\mathcal{P}$ 选中)→ running。running 有 4 条出边:success → executed(terminal,但被 contract validation 守护);transient err → failed_retryable(budget>0 可回到 pending 走新一轮,exhausted 则 → failed);structural err → failed(terminal);need human → waiting_human(resume → ready 或 timeout → cancelled)。ready 有 2 条额外出边:dep lost → blocked(→ pending 当 dep 恢复);sibling done(any_of join)→ skipped(terminal)。failed_retryable 也可因 any_of sibling 完成而 → skipped。
attempt_retry(v) / attempt_patch(v, cfg) / request_replan(reason) 三个入口。每个入口在 API 边界 check recovery_state[v]——跳级调用会被直接拒绝。作者对比 Rust 的 unsafe 块:只要实现尊重 API 边界,invariant 就不可能被违反。any_of join 的"loser skip"语义很微妙: 当某个候选成功后,剩余 pending / ready / running / failed_retryable 的 sibling 会被强制转 skipped;已经 terminal 的保留原状态。这避免了做真正的 mid-execution cancellation(会触发 compensation 问题),但代价是 loser 继续跑到自然结束。waiting_human) 设计成第一等公民,而不是边缘 feature。Scheduler 视角下,Agent Loop 和 LangGraph 只是 $|\mathcal{U}|$ 轴上的不同点;SGH 用"静态 DAG + 三级 recovery + plan versioning"把 agent 执行从一个 non-det, unbounded, unauditable 的 loop 改造成一个 det, bounded, auditable 的 scheduler,代价是放弃竞争性并行和动态拓扑。