第5章:Durable Execution —— 让 Agent 在崩溃中存活
Checkpoint / Replay / Resume 的原理,LangGraph 内置 checkpointer 详解,Temporal × Agent 的工业级范式,Restate / Cloudflare Agents 等替代方案
5 行 demo 的 agent,跑到第 8 步进程被 kill,所有状态归零;生产 agent 跑到第 8 步进程被 kill,重启后从第 9 步继续,用户毫无感知。这中间的差距叫 Durable Execution(持久化执行)——一套来自分布式系统的成熟技术,2024-2025 年大规模搬到 LLM agent 领域。本章讲透 checkpoint / replay / resume 的原理,带你看 LangGraph 内置 checkpointer 怎么用、Temporal 为什么是工业级首选、Restate / Cloudflare Agents 等新选手的定位。读完你能给任何 agent 加上”杀不死”的能力。
📑 目录
- 1. 为什么 Agent 需要 Durability
- 2. 核心原理:Checkpoint + Replay
- 3. LangGraph 内置 checkpointer
- 4. Time Travel:回到任意时刻分叉
- 5. Human-in-the-loop:暂停-恢复
- 6. Temporal × Agent:工业级范式
- 7. Restate / Cloudflare Agents
- 8. Workflow vs Agent 的边界
- 自我检验清单
- 参考资料
1. 为什么 Agent 需要 Durability
1.1 5 类必须 durable 的场景
| 场景 | 没有 durability 的后果 |
|---|---|
| 长任务(分钟-小时-天) | 中途任何崩溃都从头来,几个小时白跑 |
| 多步操作中途失败 | 状态不一致,重跑会重复扣库存/重复发邮件 |
| 等待人工审批 | 等审批时进程不能挂起,占资源 |
| 等待外部 API 异步回调 | 同上 |
| 部署滚动升级 | 老进程被替换时正在跑的 agent 全部丢失 |
1.2 Agent vs 传统 Web 请求的差异
传统 Web 请求:几百毫秒完成,失败重试一下用户不会发现。 Agent 任务:可能跑几分钟到几天,每一步都涉及 LLM 调用 + tool 调用,每一步都可能失败。
如果没有 durability,Agent 可靠性 = ∏(每步成功率) ^ 步数——单步 99% 成功率,10 步整体只有 90%。
🌟 Durable Execution 把”每步可能失败”变成”任何失败都能从断点续跑”,可用性从 90% 拉到 99.9%+。
2. 核心原理:Checkpoint + Replay
2.1 两种思路
| 思路 | 代表 | 工作方式 |
|---|---|---|
| State Checkpoint | LangGraph、Akka | 每一步把”状态快照”存到外部 |
| Event Sourcing(Replay) | Temporal、Cadence | 存”所有发生过的事件”,崩溃后重放重建状态 |
2.2 State Checkpoint 流程
Step 1 完成 → 存 state (id=t1, step=1, data={...}) → 继续
Step 2 完成 → 存 state (id=t1, step=2, data={...}) → 继续
Step 3 崩溃 → ❌
↓ 重启
读 state (thread_id=t1, latest=step 2)
继续从 step 3 跑
优点:实现简单,状态一目了然 缺点:state 大时存储/读取贵,frequent commit 影响性能
2.3 Event Sourcing 流程
WorkflowStarted(id=w1, input=...)
ActivityScheduled(name="check_inventory", input=...)
ActivityCompleted(result=...)
ActivityScheduled(name="charge_payment", input=...)
ActivityCompleted(result=...)
ActivityScheduled(name="ship", input=...)
[CRASH]
↓ 重启
重放上面 5 个 events,重建工作流到"已发起 ship"的状态
继续从 ship 等结果
优点:event log 即审计日志,完美可重现 缺点:重启时要重放(若 state 大可能慢);workflow 代码必须 deterministic
2.4 Determinism 是 Event Sourcing 的硬约束
Workflow 代码每次重放必须走完全相同的路径,否则重建的 state 会和原始不一致:
# ❌ 错:用了 datetime.now(),每次 replay 时间不同
def workflow():
if datetime.now().hour < 12:
return morning_logic()
else:
return afternoon_logic()
# ✅ 对:用 workflow.now() 这种 sandbox time
def workflow():
if workflow.now().hour < 12:
return morning_logic()
else:
return afternoon_logic()
Temporal、Cadence 都有这套 sandbox API。LangGraph 不强制 deterministic(走 state checkpoint 路线)。
3. LangGraph 内置 checkpointer
3.1 5 行加上 durability
from langgraph.graph import StateGraph
from langgraph.checkpoint.postgres import PostgresSaver
graph = StateGraph(...)
# ...add nodes and edges...
with PostgresSaver.from_conn_string("postgresql://...") as checkpointer:
app = graph.compile(checkpointer=checkpointer)
# 每个 thread_id 是独立的"会话",有自己的 checkpoint history
config = {"configurable": {"thread_id": "user_123_session_42"}}
# 启动:state 自动每步存
app.invoke({"messages": [...]}, config)
3.2 4 种内置 checkpointer
| checkpointer | 用途 | 适合 |
|---|---|---|
MemorySaver | 内存(进程重启就丢) | 本地调试 |
SqliteSaver | 单机文件 | 开发 / 小规模 |
PostgresSaver | Postgres | 生产首选 |
RedisSaver | Redis | 高吞吐 / 短期 state |
第三方还有 MongoDB、DynamoDB、Cosmos DB 实现。
3.3 自动恢复
# 进程崩了,新进程起来
config = {"configurable": {"thread_id": "user_123_session_42"}}
# 直接 invoke,LangGraph 检测到 thread 已有 checkpoint
# 从最近 checkpoint 继续
app.invoke({"messages": [new_user_msg]}, config)
LangGraph 把 thread 的 checkpoint history 暴露为可查询的对象——你可以列出所有 checkpoint、跳到任意一步、甚至从某一步分叉(time travel,下一节)。
3.4 性能与成本
- 每 node 执行后写一次 checkpoint(可选
interrupt_after/interrupt_before控制) - Postgres 写延迟 ~5-20ms,对 LLM 调用(几百 ms)是小头
- state 太大时(MB 级)要主动 prune:把不需要持久化的字段从 state 中剔除
4. Time Travel:回到任意时刻分叉
LangGraph 的 checkpoint history 可以回到过去任何一步,从那里分叉重跑:
# 列出 thread 的所有 checkpoint
checkpoints = list(app.get_state_history(config))
# 假设我想回到第 3 步重跑
target_checkpoint = checkpoints[3]
new_config = {**config, "configurable": {**config["configurable"], "checkpoint_id": target_checkpoint.config["configurable"]["checkpoint_id"]}}
# 从那一步分叉
app.invoke(None, new_config)
4.1 用途
| 用途 | 说明 |
|---|---|
| A/B 测试 prompt | 同一段历史,不同 prompt 跑出不同分叉,对比效果 |
| Bug 复现 | 用户报 bug 时,从他的 thread 任一步 replay |
| What-if 分析 | ”如果第 3 步选 A 不选 B,后面会怎样” |
| 训练数据生成 | 从同一起点采样多个 trajectory |
🌟 这是 LangGraph 区别于 Temporal 的杀手特性——Temporal 也能 replay 但不能”分叉到另一条路”。
5. Human-in-the-loop:暂停-恢复
5.1 场景
>=¥1000 的退款必须人工审批,Agent 在调 refund 前要暂停,等人批了再继续。
5.2 LangGraph interrupt
from langgraph.types import interrupt
def refund_node(state):
if state["amount"] >= 1000:
# 暂停,把当前提议返给前端
approval = interrupt({"action": "refund", "amount": state["amount"]})
# ↑ 进程在这里挂起,等下次 invoke 时 resume
if not approval["granted"]:
return {"status": "rejected"}
return execute_refund(state)
前端调:
# 第 1 次 invoke,跑到 interrupt 暂停
result = app.invoke({"messages": [user_msg]}, config)
# result 是 dict 里有 interrupt 标记,前端看到后让人审批
# 人工审批后,继续
from langgraph.types import Command
result = app.invoke(Command(resume={"granted": True}), config)
# 从 interrupt 那步继续跑
进程可以完全关掉,审批 3 天后用户来批准,新进程起来 invoke Command(resume=...) 照样能续上——因为 state 在 Postgres。
6. Temporal × Agent:工业级范式
6.1 为什么 Temporal 适合 Agent
Temporal 是分布式 workflow 引擎(Uber、Netflix、Coinbase 都在用),把”工作流即代码”做到极致:
| Temporal 特性 | 对 Agent 的意义 |
|---|---|
| Event Sourcing | 完整 audit trail |
| 自动重试 | LLM API 抖动自动恢复 |
| 长时间任务(无限期) | Agent 等几天审批 OK |
| Activity 隔离 | LLM 调用 / tool 调用作为 activity,独立超时和重试 |
| Workflow versioning | agent 升级时老 thread 仍能用老逻辑 |
| 多语言 | Python / TS / Go / Java / .NET |
6.2 Temporal × LangGraph 的两种集成
模式 A:Temporal 包 LangGraph
@workflow.defn
class AgentWorkflow:
@workflow.run
async def run(self, user_msg: str) -> str:
# 在 activity 里跑 LangGraph
result = await workflow.execute_activity(
run_langgraph_step,
args=[user_msg],
start_to_close_timeout=timedelta(minutes=5),
retry_policy=RetryPolicy(maximum_attempts=3),
)
return result
LangGraph 单步执行作为 Temporal activity,失败时 Temporal 自动重试。
模式 B:LangGraph 节点调 Temporal 子 workflow
def long_task_node(state):
# 把超长 / 跨服务的任务委托给 Temporal
handle = temporal_client.start_workflow(LongTaskWorkflow.run, args=[...])
return {"task_id": handle.id, "status": "running"}
LangGraph 自身不变,把超出”单进程能搞定”的任务外包给 Temporal。
🍎 Temporal 出了 AI Agent 专门的 Python SDK + 教程:temporal.io/blog/durable-execution-meets-ai
6.3 Temporal 的代价
- 学习曲线高:Workflow / Activity / Worker / Task Queue 概念多
- 部署复杂:需要 Temporal Server(Cassandra / Postgres + ES + Frontend)
- deterministic workflow 约束:写代码要规避 random / time 等
给 Agent 团队的建议:小规模用 LangGraph 内置 checkpointer 就够;到了”长任务 / 跨服务 / 强审计”的阶段再上 Temporal。
7. Restate / Cloudflare Agents
7.1 Restate
“轻量、cloud-native 的 durable execution。”
- 单二进制部署,比 Temporal 简单
- 提供 SDK(Java / TS / Python / Go / Rust)
- 也是 event sourcing 模型
- 适合”想要 Temporal 的能力但不想要 Temporal 的复杂度”
import { rs } from '@restatedev/restate-sdk';
const agentService = rs.service({
name: 'AgentService',
handlers: {
runAgent: async (ctx: rs.Context, input: string) => {
const plan = await ctx.run('plan', () => llm.plan(input));
for (const step of plan) {
await ctx.run(`step-${step.id}`, () => execute(step));
}
return 'done';
},
},
});
7.2 Cloudflare Agents
“边缘 / serverless 上的 durable agent。”
Cloudflare Workers + Durable Objects + Workflows,把 agent 跑在 edge:
- 全球低延迟
- 自动 scale
- 内置 KV / R2 / D1 持久化
- 适合 SaaS / 用户量大、地理分散的场景
劣势:LLM 调用还是要走外部(Cloudflare 自己有 Workers AI 但能力有限)。
7.3 Render / Modal / Vercel Functions
通用 serverless 平台都开始原生支持 durable execution——Render 出了 durable workflow,Modal 长任务支持,Vercel Functions 配 Cron 也能凑。
🌟 2026 趋势:durable execution 成为 serverless 平台的”标配能力”,像 HTTP 一样基础。
8. Workflow vs Agent 的边界
工业界经常有这个问题:Temporal 是 Workflow 引擎,LangGraph 是 Agent 框架,哪个该做哪个?
8.1 区别
| 维度 | Workflow(Temporal) | Agent(LangGraph) |
|---|---|---|
| 决策来源 | Code(deterministic) | LLM(non-deterministic) |
| 路径 | 提前定好 | 运行时由 LLM 决定 |
| 用例 | 订单流转、批处理、ETL | 对话、推理、自由探索 |
| Replay | 必须 deterministic | 不要求 |
| Steps 数 | 固定 / 少分支 | 可能 100 步循环 |
8.2 生产 Agent 是 Workflow 包 Agent
Outer:Workflow(Temporal,deterministic)
┌────────────────────────────────────┐
│ step 1: 验证 input │
│ step 2: 加载用户上下文 │
│ step 3: 跑 LangGraph agent loop ◄──┐
│ step 4: 持久化结果 │ agent 在这里
│ step 5: 通知用户 │ 自由发挥
└────────────────────────────────────┘
外层 Workflow 把”必须有的步骤”固化,内层 Agent 在某个节点自由决策。两者结合 = 既有可靠性又有灵活性。
✅ 自我检验清单
- 5 类必 durable 场景:能讲出 5 个具体业务,没有 durability 会怎样
- 可用性数学:能解释”99% × 99% × … = 90%“为什么 durability 是必需的
- State Checkpoint vs Event Sourcing:能对比两者的优劣
- Determinism 约束:能给一个反例代码,说明为什么 Event Sourcing 要禁随机/时间
- LangGraph checkpointer:能写一段最简代码加 PostgresSaver
- Time travel:能解释 LangGraph 的 time travel 三个用途
- Human-in-the-loop:能解释
interrupt()+Command(resume=...)流程 - Temporal 适用判断:能给出”什么时候该上 Temporal”的边界
- Workflow vs Agent:能解释”Workflow 包 Agent”的混合范式
- Restate / Cloudflare Agents:能说出各自定位
📚 参考资料
官方文档
- LangGraph Durable Execution:官方教程
- LangGraph Persistence:Persistence 文档
- Temporal × AI Agent:temporal.io/blog/durable-execution-meets-ai
- Temporal AI Agents Sample:github.com/temporalio/samples-python/tree/main/openai_agents
- Restate:restate.dev
- Cloudflare Agents:developers.cloudflare.com/agents/
工业博客
- The Agent Stack — Part 4: Runtimes, Workflows, and Durable Execution:Substack
- Of course you can build dynamic AI agents with Temporal:Temporal
- Build durable AI agents with Pydantic and Temporal:Temporal
- Durable Workflow Platforms for AI Agents and LLM Workloads:Render
- The Rise of the Durable Execution Engine (Temporal, Restate):Kai Waehner
- Durable Execution for AI Agents:inference.sh blog
学术与背景
- Sagas (Garcia-Molina & Salem, 1987) —— compensating actions 的经典论文(下章详引)
- Pat Helland — Life Beyond Distributed Transactions —— 分布式事务理论必读