Agent 持久化执行
一句话:Agent 跑到第 18 步,进程挂了。这个专题讲怎么让它从第 18 步继续,而不是从头再来。
先约定几个词,本专题全程使用:
| 词 | 意思 |
|---|---|
| 持久化执行 | durable execution。让一段长时间运行的代码 在进程崩溃、机器重启、版本发布之后仍能接着跑完。这个概念在分布式系统领域已经有二十年历史,Agent 只是把它变成了日常问题 |
| 检查点(checkpoint) | 把执行到某一步的状态存到进程外的存储里,崩溃后据此恢复 |
| 幂等 | 同一个操作执行一次和执行多次,结果一样。这是整个专题里唯一没有任何框架能替你做的事 |
| 幂等键 | 一个确定性的字符串(比如 任务ID:步骤号),随请求一起发给下游服务,让它据此去重 |
| 副作用 | 代码对外部世界造成的、无法靠重跑抵消的改变:发出去的邮件、创建的工单、扣掉的钱 |
| 重放(replay) | 恢复时把代码从第一行重新跑一遍,已记录过的外部操作不真执行、直接返回历史返回值 |
| 确定性 | 同样的输入必然走出同样的执行路径。重放式方案要求代码满足这一条,所以随机数、时间戳、模型调用都不能直接写在里面 |
一、这是 Agent 从 demo 到生产的分水岭
Demo 里的 Agent 跑 5 秒,挂了就重跑,没人在意。
生产上的 Agent 不一样:
- 一个 Deep Research 任务跑 20 分钟、调 60 次模型、花掉几美元
- 一个客服工单处理流程要等用户回复,可能挂起三天
- 一个数据迁移 Agent 要跑 8 小时,中途 K8s 滚动更新把 Pod 干掉了
这三种情况下,"从头重跑"都不是一个可接受的答案 —— 不只是浪费钱,更要命的是副作用会重复:已经发出去的邮件会再发一遍,已经创建的工单会再建一个。
这个问题有一个成熟的名字:持久化执行(durable execution)。它在分布式系统领域已经有二十年历史,但 Agent 把它变成了一个几乎每个团队都会撞上的日常问题。
二、四条技术路线
四条路线的差异不在"用哪个产品",而在四个机制维度:状态存成什么形式、存在谁的存储里、崩溃后谁来重新拉起、以及对你的代码有没有确定性约束。
← 接入成本低、能力受限 能力强、心智负担重 →
读这张图有三个要点:
第一行的"存成什么"决定了后面一切。 LangGraph 存的是状态快照(恢复时把值灌回去),另外三家存的都是发生过什么(恢复时把代码重跑一遍,已完成的操作直接返回记录值)。
第四行是 LangGraph 唯一的硬缺口。 它的检查点安静地躺在数据库里,除非有人拿着 thread_id 再调一次,任务就永远停在那儿。另外三家都有服务端或运行时负责发现并拉起。
第五行是最容易被宣传掩盖的代价。 DBOS 主打"只要一个 Postgres",但它和 Temporal 一样是重放式的,确定性约束一条不少。降低的是运维成本,不是认知成本 —— 只有 LangGraph 因为不重放代码,才真正没有这个负担。
四条路线不是互斥的。 常见的生产组合是:LangGraph 管 Agent 图内部的状态,外面套一层 Temporal 管整个业务流程的长事务。
三、五篇正文
| # | 标题 | 回答的问题 | 主要拆解对象 |
|---|---|---|---|
| 01 | 为什么需要 | 从头重跑到底错在哪? | 从一个 30 步任务讲起,不需要前置知识 |
| 02 | LangGraph Checkpointer | 框架自带的方案能做到什么程度? | libs/checkpoint/ + checkpoint-conformance/ |
| 03 | Temporal 与确定性重放 | 为什么它要求你的代码"不许用随机数"? | Event History 重放机制与确定性约束 |
| 04 | DBOS 与 Restate | 不想跑集群,还有别的选择吗? | DBOS 的三阶段恢复 + Restate 的定位 |
| 05 | —— | 我该选哪条路? | 全专题结论 |
四、拆解对象
| 项目 | ★ | 协议 | 语言 | 为什么选它 |
|---|---|---|---|---|
langchain-ai/langgraph | 40,005 | MIT | Python | Agent 场景装机量最大,checkpointer 是一等公民 |
temporalio/temporal | 22,394 | MIT | Go | 持久化执行的工业标准,Uber 出身 |
restatedev/restate | 4,308 | — | Rust | 新一代,单二进制部署 |
dbos-inc/dbos-transact-py | 1,532 | MIT | Python | 路线最激进:直接把 Postgres 当状态机 |
resonatehq/resonate | 655 | Apache-2.0 | Rust | 最轻量,作为对照组 |
五、与其他专题的关系
- Agent Infra 板块总览:这一层在整个知识库里的位置。
- Agent 网关 · 路由与容错:网关的重试解决的是一次请求的失败,本专题解决的是一个长任务的失败 —— 两者尺度完全不同,01 篇会讲清边界。
- Agent 可观测性:持久化执行产生的重放会让 trace 变得诡异(同一步出现两次),05 篇会说怎么处理。
- mini-ray 项目沉淀:自己实现任务调度与状态管理时踩过的坑。