Skip to content

三条能终止的护栏:长任务不再被轮次墙卡死 ​

一句话结论:一个 30 分钟长任务,曾经被轮次墙、token 预算、上下文闸、各种超时共 30 多处「终止点」同时盯着,任何一个都可能提前掐死它。我们把这些全收掉,只留下三条硬终止:用户取消、授权预算耗尽、不可恢复错误。护栏的职责从「判决」变成「降级 + 续接」。

一个长任务会被多少东西掐死 ​

做一次全量排查,数出 37 个能让任务结束的位置:7 个合法,30 个要改。它们分好几类:

类别例子
轮次上限默认 12 轮硬上限
token 预算累计 204800 撞线
上下文闸把「累计消耗」误当成「当前上下文占窗口比」
时间墙worker 会话 300s、节点 1800s、整链 30min、拆解 30s、评审 15s
审批超时用户没表态被当"拒绝",节点 FAILED
异常路径panic recover、调度器静默跳过

问题不在数量,在于每道闸都是"判死":到了就写终态,任务直接结束。结果是长任务跑到第 12 轮被"轮次墙"腰斩,模型明明还在干活。

核心转变:护栏只保留三条硬终止 ​

最终拍板的口径:

  1. 用户取消——必须有用户动作或明确表态。
  2. 授权预算耗尽——开始前就告知且可见的 token / 时长 / 算力点。
  3. 不可恢复错误——重试换档换模型后仍失败,且与任务无关(401、模型不存在、license、内容安全、panic、余额)。

除此之外的"墙",一律不判死。

三级护栏:从判决到降级 ​

把原来的判决点改成三级:

级触发行为
L1 提醒上下文 60%、重复 1 次注入提示,继续跑
L2 降级上下文 85%压缩 → 换模型 → 缩范围 → 换工具 → 打回 → 重切
L3 交卷 + 自动续接预算到顶收工,缺的自动追加续接轮补做,不终止

关键是 L3:预算到顶不再写 failed,而是交卷 + 续接。正常任务能撞到的闸,就是画错的闸——这条判断线直接把绝大多数"墙"判成了设计错误。

为什么「预算耗尽」对个人版不成立 ​

一个细节值得记:企业版有"授权额度"概念(多租户要控成本),但个人版没有。用户只会说"最多花多少钱",不会说"多少 token",系统无法量化。所以个人版的终止条件最终只定两条:用户取消、不可恢复错误。预算类卡点全部拆除,只保留"无进展 360s"作为唯一技术性判死,且必须先穷尽降级。

踩过的坑 ​

  • 上下文闸量错对象:传的是"本次循环累计消耗",语义却是"当前上下文占窗口比",累计 188k / 窗口 131072 = 143%,直接判满;单轮真实只占 8%~17%。
  • A3 预算砍半回归:把预算从 204800 改成窗口×0.8=104857,等于砍半,比的是累计消耗——老错误回归。
  • worker MaxTurns 显式传 12,绕过了"0=不限"的开关,导致开关从未生效于 worker。

结论 ​

长任务的难点,不是"能不能跑久",是"该停的时候才停、不该停的时候别停"。把 30 多道判决收成三条硬终止 + 三级降级续接,任务第一次能跑满 30 分钟而不被自己画错的闸掐死。


相关阅读:异步双工 · 验收契约 · 长任务交卷