跳转到主要内容

AI Agent 的预写日志:借鉴数据库恢复模式实现崩溃安全执行

阅读需 2 分钟Tian PanTian Pan

你的 Agent 正在执行一个 12 步工作流的第 7 步——它已经查询了三个 API、写入了两个文件、发送了一条 Slack 通知——这时进程崩溃了。接下来会发生什么?如果你的答案是"从第 1 步重新开始",那你将重新发送那条 Slack 消息、重新写入那些文件,并再次消耗你的 LLM token 预算。这正是数据库几十年前通过预写日志解决的问题。这个模式可以高度精确地映射到 Agent 架构中。

核心思路很简单:在 Agent 执行任何步骤之前,先记录它打算做什么。在继续下一步之前,记录发生了什么。这个仅追加的日志成为恢复的唯一真实来源——不是 Agent 的内存状态,不是世界的快照,而是一个可以确定性重放的意图和结果的顺序记录。

Agent 架构中的持久性缺口

大多数 Agent 框架将执行视为临时性的。一个函数运行、调用 LLM、调用一些工具、返回结果。如果执行过程中出现任何故障,框架会从头重试整个函数。这对于无状态的请求-响应模式来说完全没问题,但 Agent 并不是无状态的。

一个典型的生产级 Agent 工作流包含:

  • 多次相互依赖输出的 LLM 调用
  • 具有真实世界副作用的工具调用(发送邮件、创建数据库记录、调用外部 API)
  • 依赖中间结果的分支逻辑
  • 可能暂停数小时或数天的人工审批环节

复合可靠性问题是残酷的。如果 10 步工作流中每一步的可靠性为 99%,整体成功率将降至 90.4%。如果每步可靠性为 95%,整个工作流的成功率只有 59.9%。而且这还假设故障是干净的——实际上,部分故障更糟糕。它们会让系统处于不一致状态,其中一些副作用已经触发而另一些还没有。

从头重试不仅浪费 token。它还会产生重复的副作用。你的 Agent 发送了两次邮件、创建了重复记录、再次向客户收费。数据库领域在 1990 年代就解决了这个问题。是时候让 Agent 领域迎头赶上了。

预写日志的工作原理(以及为何能映射到 Agent)

在数据库中,WAL 遵循一个简单的规则:在修改磁盘上的任何数据页之前,先将预期的变更写入顺序日志。该日志是仅追加的、持久的、有序的。如果数据库在事务中途崩溃,恢复过程会向前读取日志,并根据日志内容完成或回滚每个事务。

映射到 Agent 执行是直接的:

  • 数据页 变为 Agent 状态(Agent 积累的上下文、中间结果和记忆)
  • 事务 变为 工作流步骤(每个工具调用、LLM 调用或决策点)
  • 日志 变为 执行日志,记录每个步骤的意图和结果

关键属性是相同的:日志在动作执行之前写入,结果在 Agent 进入下一步之前记录。这为你提供了从头重试无法实现的三种恢复能力。

第一,对已完成步骤的跳过重放。如果第 5 步的结果已经记录在日志中,你不需要重新执行它——你重放缓存的结果并从第 6 步继续。这就是 Temporal 的事件溯源模型的工作方式:它重放事件历史来重建应用状态,使用存储的返回值而不是重新执行活动。

第二,副作用的精确一次语义。因为日志记录了哪些工具调用已成功完成,恢复过程知道不需要重新执行它们。有副作用的工作——发送 Slack 消息、信用卡扣款——即使周围的工作流多次重启也只执行一次。

第三,非确定性操作的确定性恢复。LLM 调用本质上是非确定性的——相同的提示可能产生不同的输出。没有日志的话,重试工作流第二次可能会走完全不同的执行路径。有了日志,存储的 LLM 输出在恢复时被重放,保留了原始执行路径。

检查点粒度:工程权衡

并非所有检查点策略都是相同的。持久化状态的粒度决定了你的恢复精度、存储成本和写入开销。Agent 工作流有三个自然边界。

每次工具调用检查点 在每个工具调用后记录结果。这提供了最细粒度的恢复——你永远不会重新执行单个工具调用——但带来了最高的写入开销。对于每次工具调用都有显著副作用或高延迟(外部 API 调用、数据库写入)的工作流,这通常是正确的选择。

每个计划步骤检查点 在 Agent 计划的逻辑边界处记录状态。如果你的 Agent 将任务分解为"研究→草稿→审查→发布",你在每个阶段之间设置检查点。这减少了写入开销,但意味着在"草稿"阶段崩溃需要重新执行该阶段内的所有工具调用。当单个工具调用便宜且幂等,但整个工作流重启代价高昂时,这种方式效果很好。

每个决策点检查点 仅在 Agent 基于 LLM 输出做出分支决策时记录状态。这是最粗粒度的有用级别——它确保你不会重新执行决定执行路径的 LLM 调用,但接受在决策之间重新执行确定性工作。当大多数步骤快速且无副作用,而昂贵的 LLM 推理发生在关键节点时,这是合适的。

正确的选择取决于你的成本函数。如果重新执行一步的 API 费用为 0.50 美元,而检查点存储每次写入成本为 0.001 美元,那就检查点一切。如果你的步骤很便宜但数量成千上万,在逻辑边界处设置检查点以避免日志成为瓶颈。

持久化执行:WAL 原则作为运行时

会员专享

余下内容仅对会员开放。

会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。

  • 完整文章,包含未公开存档的部分
  • 可落地的工作框架,附带权衡与决策依据
  • 新文章抢先看,先于公开发布

随时取消 · 一次订阅,畅读全部

参考资料

保持联系,关注我获取更多内容

阅读需 10 分钟

智能体的死信:当没有智能体能完成任务时该怎么办

消息队列通过死信队列解决了消息卡顿的问题。智能体系统也面临同样的问题,但其失败模式更加丰富 —— 本文将介绍如何适配这一模式。

insider
ai-agents
阅读需 12 分钟

智能体集群并发:在没有死锁或惊群效应的情况下协调数十个智能体

LLM 智能体集群是一个小型分布式系统,而不是单个智能体的三十个副本。准入控制、AIMD 背压、熔断器和外部状态协调是防止并发集群自我崩溃的关键。

insider
ai-agents
阅读需 9 分钟

那个因等待另一个 Agent 而死锁的 Agent

两个能力出色的 Agent 可能会在你的账单飞涨时永远互相等待。为什么是协作——而非模型能力——导致了 Agent 群体的崩溃,以及分布式系统准则如何修复这一问题。

insider
ai-agents
阅读需 10 分钟

你的智能体需要的是监督者,而不是重试循环

当长时间运行的智能体失败时,重试循环回答了错误的问题。Erlang 的 OTP 监督树在三十年前就定义了真正的决策路径:是彻底重启、从检查点重启,还是升级给人工处理 —— 以及如何将这些策略映射到智能体流水线中。

insider
ai-agents
阅读需 10 分钟

那些被你的智能体“触发并遗忘”的异步工具调用

函数调用将同步和异步工具视为相同的形式。智能体触发了一个任务,收到了一个 ID,随后标记该步骤已完成 —— 而实际工作却从未落地。

insider
ai-agents