跳到主要内容

学习型系统的任意时间点恢复:那个没人做的备份

· 阅读需 12 分钟
Tian Pan
Software Engineer

询问任何基础设施团队,要求将生产数据库恢复到昨天下午 3 点的状态,他们会向你提供一份操作手册 (Runbook)、一个 RPO 以及一份预估时间。但如果询问同一个团队,要求将 Agent 恢复到昨天下午 3 点的状态——在它吸收一批中毒的记忆之前,在有人发布错误的提示词版本之前,或者在那个悄无声息地破坏了检索的重新索引之前——你得到的将是沉默。这并不是因为各个组件缺乏备份,而是因为没有人能说出“下午 3 点的 Agent”究竟意味着什么。

这是每个运行学习型 Agent 的团队都会面临的尴尬发现:你的数据库有快照,你的代码有 git,而你的 Agent——那个用户真正与之交互的东西——两者都没有。它的运行状态散落在向量索引、一堆记忆文件、提示词注册表和一套工具配置中,这些组件要么各自拥有独立的版本,要么根本没有版本。仅恢复其中任何一个都无法找回昨天的 Agent。你得到的只是一个逻辑破碎的大脑。

你的 Agent 状态散落在五个系统中

想想在任何给定的日子里,究竟是什么构成了生产环境中 Agent 的行为:

  • 长期记忆:用户偏好、学习到的事实和片段摘要,通常存在于文档存储或专门的记忆服务中,并持续追加。
  • 向量索引:文档、历史对话和检索知识的嵌入(Embeddings),存在于具有自身快照语义的向量数据库中。
  • 提示词和指令版本:系统提示词、技能文件和 CLAUDE.md 风格的上下文,理想情况下在 git 中,但通常在某人手动编辑的仪表板中。
  • 工具配置:存在哪些工具、它们的 Schema、它们的权限——通常分布在代码、环境配置和 MCP 服务器注册表中。
  • 模型本身:模型版本及任何微调(Fine-tune),由供应商或机器学习平台以完全不同的发布节奏控制。

每一层通常都有 某种 持久化方案。向量数据库将快照备份到对象存储。记忆服务有夜间转储。提示词在 git 中。从个体来看,一切都“已备份”。

问题在于,Agent 的行为是这五层 共同作用 的函数,而没有任何共享记录说明它们在特定时间点是如何关联的。恢复方案供应商开始直接指明这一点:智能体(Agentic AI)系统由不同的层组成,没有共同的历史记录,因此在发生故障后,恢复的任何切片都无法确认它们是否属于同一整体,或反映了相同的运行状态。恢复很容易。一致性地恢复则尚未定义。

不连贯的恢复是什么样的

假设一个 Agent 在周二遭到了记忆投毒(Memory-poisoned)——这类攻击已不再是假设。针对记忆注入的研究表明,攻击者可以通过普通的仅查询交互来破坏 Agent 的长期记忆,在理想设置下注入成功率超过 95%。最近的安全性文献将“遗忘与回滚”视为记忆防御的一等公民,正是因为对每一条条目进行人工审计是无法扩展的。

于是你在周四发现了投毒,并做了显而易见的事:从周一的备份中恢复记忆存储。现在你拥有的是:

  • 记忆中引用了在周三被重命名的工具。Agent 回忆起“对于发票问题使用 billing_lookup 工具”,但该工具现在叫 invoice_search 且具有不同的 Schema。每次检索该记忆都会产生一次失败的工具调用。
  • 向量索引仍然包含中毒对话的嵌入,因为索引和记忆存储是按不同计划进行快照的。中毒内容已从记忆中消失,但在相似性搜索中仍然胜出。
  • 系统提示词在周三进行了更新,以 补偿 中毒记忆导致的行为。现在的补偿机制正与恢复后的状态发生冲突,产生了一种从未有人观察过的新行为。

更糟糕的是,假设你还在同一窗口期内回滚了嵌入模型的升级。即使是相同的文本,来自模型 v1 和模型 v2 的向量也是不可比的——维度相同,语义空间迥异——因此任何混合了不同时期的索引都会返回信誓旦旦的错误邻居,而不是报错。没有任何东西崩溃。检索只是悄无声息地降级,而这是检测成本最高的一类故障。

在存储层面,这些组件都没有“损坏”。每一次恢复都成功了。但组装起来的系统就像一个大脑,其各个部分记得的是不同的星期——而且与崩溃的数据库不同,它不会拒绝启动。它启动正常,但表现出微妙且持续的错误。

存储工程早已解决了这个问题——我们只是忘了借鉴

这种完全相同的故障形态——应用程序状态分布在必须共同捕获的卷(Volumes)上——在存储工程中是一个已解决的问题,其解决方案有一个名字:一致性组 (Consistency group)

当一个数据库跨越多个磁盘时,你不会独立地对磁盘拍摄快照。因为一个镜像可能代表 10:00:01,另一个代表 10:00:04,卷 A 上的预写日志(Write-ahead log)会描述卷 B 上的数据文件从未见过的事务。相反,存储系统将这些卷视为一个单一单元:所有成员的 I/O 会被瞬间隔离(Fenced),快照在同一瞬间拍摄,其结果被保证为 作为一个集合 具有崩溃一致性。AWS 增加多卷崩溃一致性快照正是出于这个原因;NetApp 的 ONTAP 将一致性组正式定义为一个具有共享保护策略的管理对象。规则很简单:必须一起恢复的状态,必须一起拍摄快照——否则就干脆不拍。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates