#AI#AI Agent#DevOps

多 Agent DAG 调度恢复:依赖就绪、事件重放与安全重规划

DAG 画出来不等于可恢复。本文把依赖满足、节点尝试、产物提交和图版本拆开,用事件重放与派生就绪集防止重启后漏跑、早跑或重复释放下游。

本文要点

  • 主题聚焦:AI、AI Agent、DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年3月17日·更新于 2026年7月20日

研究、编码和审阅可以并行,但发布必须等待所有硬前置成功;这类任务自然形成 DAG。生产问题通常不在拓扑排序,而在调度器崩溃的瞬间:父节点结果已经提交,child_ready 事件尚未发出;事件重复投递两次;失败重试与人工跳过同时释放后继;模型又提出一份修改后的图。若“就绪”只是内存队列里的消息,重启后必然出现漏跑或早跑。

Agent 委派协议 规定单次父子交接的输入输出,Agent 运行时状态机 规定一个 run 的合法状态。本篇只解决跨节点依赖如何由持久事实派生,以及图变更后怎样恢复,不重写角色提示或通用检查点。

DAG.v1 把定义与执行分开

不可变 DagRevision 保存 dagId、revision、节点定义摘要、边、边类型、输入映射、策略版本和创建原因。执行态另存 NodeExecution,键为 runId + dagRevision + nodeId,包含 stateVersion、observedCancelGeneration、当前 attempt、已提交产物摘要和终态原因。硬边可声明 ALL_SUCCESS、ALL_TERMINAL、ANY_SUCCESS 或带条件的 PREDICATE,不能只用一个含糊的 dependsOn。

每组依赖在同一 canonical snapshot 下求 TRUE/FALSE/UNKNOWN:ALL_SUCCESS 仅在全部父节点成功且所需 artifact 齐全时为真,出现终态非成功即为假;ALL_TERMINAL 只要求全部终态,仅被输入映射引用的成功结果需要 artifact;ANY_SUCCESS 在任一成功产物出现时为真,全部终态仍无成功才为假;PREDICATE 按固定策略版本求值,输入未决时保持未知。节点只有在自身为 PENDING、所有组为真且观察到当前 cancel generation 时才 ready;任一组为假则按策略进入 SKIPPED/FAILED,不能永久等待。

输入映射引用 producerNode/resultSchemaVersion/artifactDigest,不能读取“某 Agent 最新输出”。节点契约升级时,新 worker 必须明确兼容的 schema 范围;未知版本进入 MIGRATION_REQUIRED。这与 Agent 改 API 的契约兼容门 一样,需要消费者证据,而不是相信自然语言大致相似。

就绪集是投影,不是事实源

每次节点 canonical commit 与一条 NodeTerminal.v1 outbox 事件在同一事务落库。调度器可以消费事件增量更新 ready queue,但数据库里的图版本、节点终态和产物才是事实源。重启时从持久 watermark 重放事件,并周期性扫描“终态父节点已满足、子节点仍 PENDING 且未入队”的差集。重复 ready 事件通过 run/revision/node 唯一键折叠。

不要把全图扫描放在每次事件上。可维护每个 dependency group 的三值投影;每次边状态变化带唯一 satisfaction ID,恢复时从 canonical parent states 重算。Temporal 的 Event History 展示从历史恢复执行的思想,Argo DAG 的 depends 语义提醒我们,失败、跳过和成功不能压成一个布尔完成。

worker 领取 ready 节点时仍需 多 Agent 任务 Claim 的 generation。队列重复只会多产生一次被拒绝的 claim,而不会多提交一份结果。节点 commit 后才允许满足边;result_staged、流式部分输出或模型自报 done 都不能释放后继。

动态重规划不能原地改图

模型提出的 patch 必须携带 baseRevision + expectedActiveGeneration。验证无环、边端、规模、能力和预算后,一个事务锁定 run 与受影响 claim,重查 active tuple,提高待删除节点的 scheduler/cancel generation,写不可变 revision+1、逐节点 reuse record、取消 outbox,并 CAS 切换 active pointer/generation。事务提交即 fencing 旧 attempt;未知在途效果进入对账。竞争失败者基于新 revision 重算;只有输入、实现和策略摘要相同的完成节点可复用。

图迁移期间固定一个 active revision。旧 revision 的迟到终态只写旧历史,不能满足新边。若父节点结果需要人工选择,边状态保持 UNRESOLVED,交给 多 Agent 结果合并的血缘与冲突仲裁,不能让到达顺序代替决策。

故障矩阵与完成证明

测试在结果/outbox 事务前后、ready 投影更新一半、领取前和 revision 切换时杀进程。重复乱序投递终态,让两个调度器同时释放后继,并覆盖 ANY_SUCCESS 早成功、ALL_TERMINAL 含失败、条件未知、循环 patch、两个 replanner 竞争、父取消与成功竞争。断言相同历史得到相同 ready set,每节点一个 canonical 终态,未满足组的启动数为零。

指标包括 orphan-ready 差集、重复 ready 折叠率、依赖满足到领取延迟、历史重放耗时、投影校验漂移、每 revision 复用率、无输入启动拒绝数和 DAG 卡住时长。按失败类别统计终态,避免把策略拒绝伪装成 worker 故障。AI Agent 可观测性 的 trace 应携带 run、revision、node 和 attempt,但不记录完整提示词。

发布时先 shadow 重算 ready set,与旧调度器逐节点对比;再让新调度器只消费新建 run,旧 run 继续旧引擎。回滚先冻结 revision 晋级和新节点领取,保存 watermark,取消新引擎未提交 attempt,再由旧引擎从 canonical 状态重建队列。不能把临时 ready queue 倒回数据库当成事实。恢复后运行全量差集校验,确认无早跑、无漏跑、无跨 revision 提交,再解除冻结。

Related

相关推荐