#大模型#AI Agent#DevOps

长任务 Agent 的持久化工作流:断点续跑、超时和幂等边界

研究、采购、批量数据处理等 Agent 任务常跨越数分钟甚至数天。本文讲解如何持久化任务快照、恢复检查点、处理超时和避免重启后重复执行外部副作用。

本文要点

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

“长任务”不只是把 HTTP 超时调大。一个需要等待用户上传文件、轮询第三方审批、处理数千条数据或分阶段产出报告的 Agent,必然会遇到进程重启、消息重复、依赖服务抖动和租户配额变化。若运行状态只在内存里,任何一次发布都会让任务从头开始,或者更糟糕地从中间重复写入。

可靠的设计从持久化边界开始:把每个能够安全停下来的位置定义为检查点。检查点不是“模型已经想到了什么”的全文转储,而是恢复下一步所需的最小事实,例如已处理分页游标、当前计划版本、已成功工具调用的幂等键、等待事件的关联 ID 和最后一次可验证输出。

把任务拆成可重放的步骤

一个批量导入 Agent 可以分为准备、分片、执行、汇总和交付五步。每一步结束后写入不可变事件或版本化快照,并在下一步开始时从存储中读取,而不是依赖当前 worker 的内存。对模型推理结果,持久化结构化决策和输入哈希即可;对外部写操作,持久化请求摘要、幂等键和下游返回的资源 ID。

示意数据模型可以是:

ts
type RunCheckpoint = {
  runId: string;
  step: "PREPARE" | "SHARD" | "EXECUTE" | "SUMMARIZE" | "DELIVER";
  version: number;
  cursor?: string;
  planHash: string;
  completedToolKeys: string[];
  waitForEvent?: string;
  updatedAt: string;
};

恢复时先验证 planHash 和任务版本是否兼容,再读取未完成步骤。代码升级导致步骤语义改变时,不能假装旧快照仍然安全;应提供迁移函数或让任务进入人工复核。把 schema 版本作为检查点字段,能避免“新 worker 用新假设解释旧状态”的隐性错误。

幂等键比重试次数更重要

重试不是问题,重复副作用才是问题。对创建工单、扣费、发送通知、写入文件等行为,调用前生成稳定的幂等键,例如由 runId + step + resourceId + inputHash 构成。服务恢复后,如果同一个键已经有结果,就直接复用而不是再次调用下游。

不要用随机 UUID 作为每次重试的幂等键,那会让下游无法识别重复。也不要只靠“先查后写”,因为两个 worker 可能同时通过查询。应由下游 API、唯一约束或事务性 outbox 提供最终去重边界。对于没有幂等能力的旧系统,至少把调用请求和结果纳入受控队列,并把人工补偿写入流程。

超时要区分三种语义

任务总时限、单步时限和外部调用时限不应混在一个数字里。外部调用 30 秒超时可能允许重试;等待用户三天超时可能改为取消;整个任务超过预算则应停止继续推理并输出当前进度。每个超时都要落为事件,带上触发条件和下一状态,方便运营人员判断是依赖慢、用户未响应还是设计错误。

对于排队系统,还要设置租户级并发和速率上限。一个长任务恢复后不能立即抢占所有 worker,尤其是模型调用和数据库扫描会放大峰值。恢复策略应先检查配额、限流和取消标记,再领取下一段工作。

用故障演练验证断点是否真实

最有效的测试不是等生产宕机。准备一个十步的测试任务,在第 3、6、9 步后主动终止 worker;重复投递同一消息;让一个外部调用先返回超时再返回成功。验证点包括:已完成的副作用没有重复、游标没有倒退、任务状态没有跳过审批、最终汇总能解释每次恢复原因。

可以在预发布环境记录一个恢复指标:从 worker 重启到任务继续领取的时间,以及因幂等命中而避免的外部调用次数。它们能把“支持恢复”的口号变成可观测能力。

清理策略决定恢复数据能保存多久

持久化不等于无限保留。检查点、工具摘要和中间产物需要按任务类型设置保留期:用户可下载的交付物可能保留数天,审计记录按合规要求更久,原始提示词和临时文件则应更短并采用最小权限访问。清理任务也必须理解运行状态,不能在一个等待审批的任务恢复前删掉它唯一的上下文。

建议在任务进入终态后先写出最终摘要和关联资源,再异步清理可再生的中间数据;删除前记录清理版本和原因。测试恢复机制时同样要测试清理边界:已经完成的任务不应因为清理重跑,未完成的任务也不能因为过度清理失去唯一检查点。这样长期运行的 Agent 才不会把可靠性问题转化为存储和隐私问题。

延伸阅读

Related

相关推荐