Agent 跑了半个小时,突然失败了。你不知道它在哪一步出了问题,不知道它之前做了什么,只能从头重跑一遍。
这不是偶发的倒霉,而是设计上的缺陷。Agent 没有留下任何可追溯的记录,出了问题就只剩一个黑盒。对短任务来说,这可能只是浪费几分钟;对长任务、并行任务、带外部副作用的任务来说,这会直接影响稳定性、成本和信任感。
所以,真正可用的 Agent 系统,不应该只关心最后输出了什么,还要关心执行过程中发生了什么。每一次关键判断、每一次工具调用、每一次失败重试,都应该留下可以回看的痕迹。
很多 Agent 的执行状态只存在于运行时的内存里。只要进程一结束,这些状态就消失了。
这会带来三个问题:
┌────────────────────────────────────────────┐
│ 问题一:无法恢复 │
│ 中途失败只能从头重跑,之前的工作全部作废 │
├────────────────────────────────────────────┤
│ 问题二:无法排查 │
│ 出错了不知道哪一步出的问题,只有最终结果 │
├────────────────────────────────────────────┤
│ 问题三:无法积累 │
│ 每次执行的经验无处沉淀,下次还是重头开始 │
└────────────────────────────────────────────┘
内存状态适合支撑当前这一次运行,但不适合承担长期责任。它可以告诉 Agent 现在走到哪一步,却很难在进程退出之后证明自己之前做过什么、为什么这么做、结果是否可靠。
解决这三个问题的方式是同一个:把执行过程中的关键事件持久化存储,而不是只依赖内存。
事件持久化的意思是:Agent 每执行一个有意义的操作,都把这件事记录下来,写到外部存储里。
记录的内容不需要很复杂,基本结构包括:做了什么、什么时候做的、输入是什么、输出是什么、是否成功。如果这一步失败了,还要记录失败原因、重试次数和下一步处理方式。
┌──────────────────────────────────────────────┐
│ 一条事件记录 │
│ │
│ 时间戳:2026-05-07 14:32:01 │
│ 事件类型:工具调用 │
│ 工具名称:search_logs │
│ 输入参数:{ "keyword": "timeout", ... } │
│ 输出结果:{ "count": 12, "files": [...] } │
│ 执行状态:成功 │
└──────────────────────────────────────────────┘
这条记录写进文件或数据库之后,就和进程的生死无关了。Agent 崩溃了、超时了、被手动停掉了,记录依然在。后续排查问题时,工程师不需要猜测当时发生了什么,只要沿着事件链往前追,就能看到任务是怎样一步步走到当前结果的。
更重要的是,事件记录不只是日志。日志偏向给人看,事件记录还要给系统继续使用。它应该能被查询、被聚合、被重放,必要时还能成为恢复任务、生成报告、沉淀经验的输入。
有了持久化的事件记录,Agent 才具备断点续跑的能力。
下次启动时,Agent 先读取上次的执行记录,找到最后一条成功的事件,从那里继续往下跑,而不是从头开始。已经完成的步骤不重复执行,节省时间,也避免重复操作带来的副作用。
┌─────────────────────────────────────────┐
│ 正常执行流程 │
│ │
│ 步骤 1 ──► 步骤 2 ──► 步骤 3(失败) │
└─────────────────────────────────────────┘
↓ 重启后
┌─────────────────────────────────────────┐
│ 断点续跑流程 │
│ │
│ 读取记录 ──► 步骤 1(跳过) │
│ ──► 步骤 2(跳过) │
│ ──► 步骤 3(从这里继续) │
└─────────────────────────────────────────┘
这对长任务尤其重要。一个跑了两个小时的 Agent,不应该因为最后五分钟的网络抖动就全盘作废。
不过,断点续跑不是简单地把失败步骤重新执行一遍。它还有一个前提:事件记录必须能说明哪些步骤已经产生了外部副作用。比如已经写过文件、发过请求、创建过资源,就不能假装这一步没有发生。否则重跑可能带来重复提交、重复扣费、重复创建数据等问题。
所以,事件持久化最好和幂等设计放在一起考虑。能重复执行的步骤,可以直接从事件记录恢复;不能重复执行的步骤,要记录外部资源标识、执行结果和补偿方式。这样恢复任务时,Agent 才知道自己应该继续、跳过、确认,还是回滚。
事件记录的另一个价值是可观测性。
在多 Agent 并行的场景里,主控 Agent 需要知道每个子 Agent 的执行状态。如果子 Agent 只在最后返回一个结果,主控就是盲调度,不知道谁跑完了、谁卡住了、谁出错了。
有了持久化的事件记录,主控随时可以查询每个子 Agent 的进度,而不需要等所有人都结束才能汇总。某个子 Agent 卡住了,可以提前介入;某个子 Agent 已经跑完,可以提前拿到结果往下推进。
┌───────────────────────────────────────────┐
│ 主控 Agent 查询子 Agent 状态 │
│ │
│ 子 Agent A:已完成(步骤 1/1) │
│ 子 Agent B:执行中(步骤 2/4) │
│ 子 Agent C:失败(步骤 3,超时) │
└───────────────────────────────────────────┘
这种实时的可见性,是单纯依赖内存状态做不到的。
在工程上,可观测性至少要回答三个问题:当前任务跑到哪里了,最近一次失败发生在哪里,下一步计划做什么。只要这三个问题能被稳定回答,Agent 就不再是一个只能等结果的黑盒,而是一个可以被调度、诊断、干预的工作流。
说到这里,细心的读者可能已经发现,事件持久化和前面几篇讲的内容是相互咬合的。
上一篇讲记忆分层,提到梦境整合会在会话结束后回顾历史、提炼经验写入长期记忆。那么,梦境整合回顾的是什么?正是这些事件记录。
没有持久化的事件记录,梦境整合就失去了原材料,只能依赖模糊的会话印象,提炼出来的经验质量大打折扣。
┌───────────────────────────────────────────────┐
│ 事件记录(原材料) │
│ 完整记录了每一步做了什么、结果如何 │
└──────────────────┬────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ 梦境整合(提炼) │
│ 从事件记录中识别规律、错误模式、高效路径 │
└──────────────────┬────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ 长期记忆(沉淀) │
│ 精炼后的经验,供下次会话直接使用 │
└───────────────────────────────────────────────┘
事件持久化、梦境整合、长期记忆,三者串在一起,才构成一个完整的经验积累闭环。
这里的关键不是把所有过程都塞进长期记忆,而是先把过程完整保留下来,再从里面筛选真正有复用价值的经验。事件记录负责保真,梦境整合负责提炼,长期记忆负责复用。三者分工清楚,系统才不会把临时噪音误当成长期经验。
事件记录不是越详细越好。记录太细,存储压力大,查找也慢;记录太粗,关键信息丢失,分析价值有限。
一般来说,值得记录的事件包括:工具调用、决策节点、错误和异常、任务的开始和结束、对外部资源产生影响的操作。这些事件共同决定了任务能否恢复、问题能否追踪、经验能否提炼。
不需要记录的包括:Agent 内部的每一步推理过程、临时的中间变量、大量重复的低价值操作。尤其是内部推理过程,本身不适合作为长期存储对象,也不一定能提升恢复和排查效率。
判断标准只有一个:如果这条记录丢了,你能不能还原出发生了什么。能还原,就不需要记;还原不了,就要记。
还可以再加一个工程判断:如果这条记录会影响恢复、审计、计费、安全、协作或经验复用,就应该记录;如果它只是在运行时临时帮助模型组织上下文,就没有必要长期保存。
事件持久化解决的是 Agent 的失忆问题。它让 Agent 的执行过程变得可追溯、可恢复、可观测,也为后续的经验积累提供了原材料。
这个系列到这里就完整了。从 Generator + Critic 到 Rubric 驱动,从记忆分层到并行编排,再到事件持久化,五篇文章覆盖了本地 Agent 落地的五个核心设计问题。它们不是孤立的技巧,而是一套相互支撑的架构思路。
如果把 Agent 当成一次性脚本,执行完就结束,事件持久化可能显得有点重。但只要你希望 Agent 能承担长任务、多人协作、并行调度和持续改进,它就不是锦上添花,而是基础设施。