很多团队以为给长任务加一个超时阈值,就算完成了 SLA 设计。但真正进入生产后,你会发现问题远不止“多久结束”这么简单。任务可能先排队、再调用多个工具、再等待审批或外部回调,中途还会遇到限流、重试和人工接管。只要调度器不知道这条任务距离承诺时限还有多少缓冲,也不知道哪些等待应该计入 SLA、哪些等待可以暂停计时,系统就会在最忙的时候同时拖慢短任务、压垮长任务,并把违约风险推到最后一刻才暴露。
Azure Durable Functions、OpenAI Agents SDK 和 Temporal for AI 的材料都在强调同一件事:长任务不是单次请求,它需要可恢复的运行状态、可唤醒的等待点和可观察的执行边界。映射到 TaskPilots,这意味着 SLA 不能只写在工单或看板里,而要写进运行时合同里:什么时候开始计时、每一步能花多久、等待外部事件时如何扣减预算、何时必须升级人工。只有这样,独立运行的 Agent 才能在跨天、多步骤和高价值副作用场景里真正守住时限。
为什么这个问题重要
SLA 不是一个超时值,而是一份交付承诺
对长任务来说,SLA 既约束最终完成时间,也约束过程中的资源分配方式。一个两小时内必须完成的审批链,和一个二十四小时内完成即可的数据整理任务,不应该进入同样的排队策略,更不应该共享同样的重试节奏。前者需要更高优先级、更紧的步骤预算和更早的人工介入阈值;后者则更适合在低谷时段运行,避免挤占关键链路。
- 如果不区分 SLA 等级,短时高优任务会被长时低优任务堵住。
- 如果不记录剩余时间预算,恢复后的任务会继续按原节奏运行,最后在接近截止时集体超时。
- 如果不定义等待是否计时,团队会在复盘时发现“系统没坏”,但承诺已经失守。
如果不处理会怎样
最常见的后果不是系统立刻崩溃,而是 SLA 违约被慢慢“隐藏”起来。任务表面上仍在运行,日志里也能看到重试和回调,但运营团队不知道它还剩多少可用预算,调度器也不知道是否该抢占资源。等到客户催单、审批过期或窗口关闭时,团队才发现问题并不是某一次失败,而是整条链路从一开始就没有按时限去调度。
继续沿用这种做法,通常会出现三类连锁问题:第一,排队时间无法控,真正消耗预算的是等待,不是执行;第二,恢复逻辑与时限逻辑分离,任务恢复了却已经没有业务价值;第三,人工接管总在最后一分钟发生,导致运营负担和升级成本同时上升。
适用场景
谁最需要这套方法
这套方法最适合已经拥有多步骤工作流、需要等待外部事件、且结果有明确时效要求的团队。尤其适合那些“任务能跑很久,但不能随便晚到”的场景,因为这里真正困难的不是执行本身,而是如何在等待、恢复和资源竞争中仍然守住承诺。
- 跨部门审批、退款审核、合规核验等存在明确处理时限的运营链路。
- 依赖第三方回调、Webhook、人工确认或批处理窗口的异步工作流。
- 会写入 CRM、工单、订单或通知系统,且重复执行代价较高的任务。
- 同一平台上同时跑着高优先级实时任务和低优先级长任务的多租户环境。
什么时候先不要这么做
如果当前任务几乎都是几秒内完成的一次性调用,没有外部等待,也没有明确对外承诺时限,那么先把复杂的 SLA 调度引入运行时,收益可能不高。另一类不适用边界,是离线批处理且允许全量顺延的任务,例如夜间报表汇总、探索性数据清洗等。这类任务更适合先做基础重试和容量治理,而不是马上实现细粒度的预算拆分与人工升级链路。
推荐系统结构
把总时限拆成排队预算、执行预算和等待预算
更稳的做法,是把一条长任务的 SLA 明确拆成几个可执行的时间合同,而不是只保留一个最终截止时间。调度器需要知道任务何时进入系统、允许排队多久、每个关键步骤最多占用多久,以及外部等待是否暂停计时。这样一来,系统恢复、唤醒和抢占时都能基于同一套预算做决定。
- 为每条任务记录总截止时间 `dueAt`,而不是只记录创建时间。
- 为关键步骤设单独预算,例如模型推理、工具调用、人工审批等待和最终回写。
- 显式标记等待状态是“计时等待”还是“暂停计时等待”,避免不同团队各自理解。
- 每次恢复时重新计算剩余预算和风险等级,而不是沿用首次启动时的默认优先级。
把预算映射到 TaskPilots 的运行状态与升级规则
映射到 TaskPilots,可以把每一次长任务运行都视为一个带时限的状态机:运行记录里不仅要保存当前步骤,还要保存剩余 SLA、下一次唤醒时间、当前等待原因、可接受的重试次数和升级阈值。调度器据此决定哪条任务先运行、哪条任务先唤醒、哪条任务必须提前交给人工。这样做的关键价值,不是“看起来更复杂”,而是让 Agent 的每次等待和每次恢复都与业务承诺保持一致。
比较稳的控制面通常至少包含四类信号:任务优先级、剩余缓冲时间、失败类型和人工接管条件。比如某条任务距离截止只剩十五分钟,同时还依赖不稳定的外部服务,那么系统不应继续做宽松重试,而应直接切换到补偿或人工升级路径。SLA 调度真正要解决的,就是把这些判断从事故后的人工经验,前置成运行中的系统规则。
风险与失效点
最常见的四种失控方式
第一种失控,是把 SLA 简化成单个全局超时,结果所有任务在到期前都被同样对待,调度器无法提前识别风险。第二种,是只按 FIFO 排队,不看剩余时间预算,导致低优先级长任务长期占满资源。第三种,是等待外部事件时不保留状态,只能靠轮询或重跑来“碰碰运气”。第四种,则是人工接管阈值定义太晚,系统明明早已知道赶不上,却仍然把任务拖到违约之后再报警。
- 没有区分计时等待和暂停等待,SLA 统计会长期失真。
- 恢复后优先级不重新计算,任务会在最需要资源时继续排在队尾。
- 只监控平均耗时,不监控尾部延迟,真正会违约的任务被整体数据掩盖。
哪些地方必须保留人工兜底
凡是涉及客户承诺变更、外部窗口重约、资金与权益处理、规则例外批准或高影响补偿的节点,都应保留人工决定权。因为当系统判断“继续自动执行已不划算”时,下一步往往不是单纯失败,而是需要业务团队重新取舍:延长时限、换执行方案、拆分任务范围,或者直接通知相关方。没有这层人工兜底,SLA 调度就容易沦为机械地追时,而不是面向结果地守约。
验证指标
上线前怎么验证
上线前不要只测功能走不走得通,而要专门验证“调度是否真的按 SLA 行动”。建议至少做三类演练:一类是高低优先级混跑,检查关键任务能否被及时抢占调度;一类是外部回调延迟或工具限流,检查系统是否会及时调整剩余预算和升级阈值;一类是跨天恢复,检查任务被唤醒后是否仍按原承诺时限继续推进。
- 注入排队拥塞,观察高优任务的实际等待时间是否仍在预算内。
- 注入工具服务抖动,验证任务不会在无意义重试中耗尽全部时限。
- 模拟人工审批超时,确认系统能在违约前触发升级,而不是违约后才补告警。
上线后怎么持续判断
生产环境里,至少要持续追踪五类指标:按 SLA 分类的准时完成率、任务排队时长分位数、等待态唤醒延迟、升级前置率和人工接管成本。第一类看最终结果,第二和第三类看调度是否拖慢任务,第四类看系统是否能在违约前主动介入,第五类则帮助团队判断当前自动化是否真的值得继续扩大。
除此之外,最好再补两项结构化指标:步骤预算超支率,以及恢复后剩余缓冲时间分布。如果一条任务经常在恢复后只剩极少时间,却仍被系统当作普通任务排队,那就说明 SLA 逻辑还没有真正进入调度层。
下一步 / FAQ
下一步建议
最实际的起步方式,是先挑一条已经有明确时限、又经常跨步骤等待的任务链路,把它拆成三份预算:排队预算、执行预算和等待预算。接着再补两条规则:还剩多少缓冲时必须升级人工,哪些等待可以暂停计时。只要这一条链路先跑通,团队就能很快看见调度行为、恢复机制和业务承诺开始对齐,后续再把这套模型扩展到更多任务类型会容易得多。
FAQ
等待客户或第三方回调时,SLA 要继续计时吗? 不能靠口头约定,必须在运行时状态里显式定义。对外承诺是“自然时间”还是“工作时间”,等待是否暂停,都要前置写清。
是不是一定要做抢占式调度? 不一定,但只要同一系统里同时存在不同等级的时限任务,就至少需要优先级和剩余预算感知,而不能完全依赖 FIFO。
已经有重试和告警,还需要单独做 SLA 调度吗? 仍然需要。重试解决的是局部失败,SLA 调度解决的是整条链路如何在有限时间里完成或及时升级。
人工升级阈值怎么定? 一般不要等到只剩最后几分钟。更稳的做法,是按历史处理时长和缓冲比例预留固定窗口,让人工接手时还有真正可操作的空间。