设想 AI 智能体跑到第九十九步时断了电,重启后是重头再来还是接着走,取决于长任务的状态保存做没做到位。把「随时可续」变成默认能力,靠的是检查点机制,这篇拆解它的存法与恢复细节。
长任务为什么要留底
跑几十分钟甚至几小时的任务,中断几乎必然发生:网络抖动、服务重启、上游限流,都算日常。不留底的任务一断就清零,重跑既费时又可能重复产生副作用——发过的通知再发一遍,写过一半的文件写两份。留底的目的有两个:续跑省时,重跑不重复。两个目的缺一不可,只顾省时不防重复,反而会添乱。
状态存成什么样才好恢复
检查点通常存三类信息:做到哪一步了,这是进度指针;每一步的关键产物,这是续跑的原料;外部副作用清单,比如已发送的请求凭据,这是防止重复动作的凭据。三者齐备,恢复程序才知道从哪继续、拿什么继续、哪些动作绝不能再做一遍。凭据思想与幂等是靠什么实现的同源,只是用在了存档侧,两边配合才严密。
三类信息各管一段,缺一类恢复就卡壳:
| 存什么 | 具体内容 | 缺了会怎样 |
|---|---|---|
| 进度指针 | 做到哪一步了 | 恢复程序不知道从哪继续 |
| 关键产物 | 每一步的关键产物,续跑的原料 | 不知道拿什么继续 |
| 外部副作用清单 | 已发送的请求凭据等 | 不知道哪些动作绝不能再做一遍 |
每完成一步就落一次盘
存档节奏是个平衡题:每步都存,开销大但损失小;隔十步存一次,省了开销却可能退回很远。常规做法是按里程碑存档——关键步骤、外部调用前后、耗时长的环节之后必存。存档本身还要做坏档保护:先写临时文件再原子替换,避免存到一半断电,把唯一的好存档也毁了。ModelScope 上的长训练任务靠检查点续跑,纳米AI的多步任务也有类似的进度存档,都是这个套路。
中断后从断点继续的细节
恢复并非简单跳回最后一步:先校验存档完整性,再核对环境是否还成立——页面可能改版了、数据可能过期了,变了就局部重取,页面变化的应对见网页改版了 Agent 怎么办。续跑前还会对齐外部状态,把「我做过什么」与「世界实际发生了什么」对上,确认无重复后才继续。整个过程写进执行日志的结构长什么样所讲的档案里,恢复的每一步都可追溯。
状态保存自查清单:进度指针是否精确到步骤;关键产物是否随存档落盘;外部副作用是否有凭据清单;存档写入是否做了坏档保护。四项都有,断了也不慌。
说到底,状态保存改变的是任务的失败成本:从「全部重来」降到「补一段路」。跑得久的智能体,拼的并非一口气跑多远,而是摔倒后爬起来的位置离终点有多近。
多任务并存时的存档管理
多个长任务并行跑时,存档管理比单任务复杂:谁的检查点、存到哪、占多少空间,都要有台账。基本规矩是按任务标识分目录,存档带上时间戳与版本号,恢复时只认最新有效版本。空间要设上限——单任务存档超限就先压缩产物,再不够就提高存档间隔,而不是任其涨满磁盘拖垮所有任务。清理也要讲次序:先清已完成任务的存档,再清过期任务的,正在跑的任务的存档最后动。台账每月对一次账,孤儿存档——任务早没了、存档还躺着的那种——及时回收,别让它们悄悄吃掉存储。还有一点容易被忽略:存档也要做访问控制,谁有权读取哪个任务的检查点,要与权限体系挂钩,防止横向越权翻看别的任务的产物。跨机器迁移任务时,存档格式保持向后兼容,老版本恢复程序读得懂新存档,升级才敢放开了做。
关于状态保存,问得最多的三个
- 存档本身会占上下文吗?:不会,存档落在外部存储,对话里只留一句进度引用,需要时再取回。
- 多久存一次最合理?:按里程碑而不是固定步数,外部调用前后必存,纯内部计算可以放宽。
- 存档损坏了怎么办?:保留最近两到三份存档,坏一份就回退到上一份,损失可控。


