@ryancarson: https://x.com/ryancarson/status/2064751272834593135
摘要
利用 Devin AI 设置自动化代理驱动灾难恢复的详细指南,涵盖两种备份策略(PITR 和异地备份)、执行行动手册以及现场破坏性测试。
查看缓存全文
缓存时间: 2026/06/10 19:53
如何使用智能体实现灾难恢复自动化
作为早期采用者,你的智能体已经在100%地交付你的功能、修复和重构。拍拍自己的肩膀——该进阶到智能体驱动的自动化灾难恢复了。(作弊码:直接把这篇内容丢给你的智能体,然后说“实现这个”。)
数据库恢复是你整个技术栈中最吓人的按钮。它会造成破坏,很少用到,而当你真正需要它时,你会在凌晨2点惊慌失措,努力回忆哪个备份是好的。这正是那种应该写成智能体可执行的剧本的高风险、低频操作——关键在于,你必须在真正需要它之前,在真实条件下测试过它。
本文介绍我们是如何设置的:两种独立的备份策略(时间点恢复和异地转储)、智能体遵循的单一剧本、如何触发、如何验证,以及我们如何在不丢失数据的情况下,对生产环境进行真实的、具有破坏性的测试。
我们使用的智能体是 @DevinAI,具体机制是 Devin 剧本——一个可复用的程序,Devin 加载并执行。我们将具体说明如何创建该剧本、Devin 如何运行它,以及(因为总有人问)剧本与技能有何不同。这些概念适用于任何有能力的编码智能体,但下面的连线是我们实际运行的。
在整个过程中,有两个标准词汇值得牢记,因为经验丰富的运维人员正是这样思考的:
- RPO(恢复点目标): 可以承受的数据丢失量,以时间衡量。每日备份意味着RPO最多约24小时;持续PITR可缩短到秒级。
- RTO(恢复时间目标): 允许恢复操作花费的时间。
另一个参照点是经典的 3-2-1 规则:至少 3 份数据副本,存储在 2 种不同介质/系统上,其中 1 份在异地。以下所有内容实际上只是该规则的一个具体、由智能体实现的版本,并明确设定了 RPO/RTO 目标。
为什么需要两种备份,而不是一种?
备份的黄金法则:从未恢复过的备份,只是一个希望。 单一的备份策略是单点故障。我们使用两种,因为它们的失败方式不同,覆盖不同的灾难场景:
1. 时间点恢复 (PITR) —— 你的快速“撤销”
大多数现代托管 Postgres 提供商(我们使用 @neondatabase - 它与 @vercel 集成非常容易;Supabase、RDS、Cloud SQL 等都有等效功能)会保留持续变更历史,让你可以将数据库回滚到保留窗口内的任意时刻(我们的是7天)。
- 最佳场景: “我们刚刚在20分钟前运行了一个错误的迁移/错误的删除/有缺陷的部署。” 你将系统回滚到损坏发生前的那一刻。(极佳的RPO——秒级。)
- 粒度: 精确到秒。
- 速度 (RTO): 取决于提供商——不要假设“瞬间”。在 Neon 上,恢复是一个写时复制分支操作,几乎是即时的。在 RDS / Cloud SQL 上,PITR 从基础快照加上 WAL 回放配置一个全新实例,可能需要十几分钟到几小时,之后你再切换过来。了解你提供商的恢复机制,并在演练中计时,这样你的 RTO 是一个测量值,而不是猜测。
- 杀手锏: 它是可逆的。当你恢复时,提供商会将恢复前的状态保留为单独的分支/快照。如果你的恢复操作是个错误,你可以撤销这个撤销。
- 陷阱: 它位于与你生产数据库相同的提供商账户内。如果该账户被攻破、删除,或者提供商出现灾难性故障,你的 PITR 历史也会随之消失。
2. 异地转储 —— 你的“办公楼着火了”备份
这是一个写入不同供应商的对象存储(我们使用 AWS S3;GCS、Cloudflare R2、Backblaze B2 都可以)的备份。一个 cron 作业按计划运行(我们每天一次)。我们使用普通的 pg_dump,诚实地指出何时该工具是合适的选择:
- 逻辑转储(pg_dump)适合中小型数据库——比如几十GB。它们简单,跨 Postgres 版本可移植,并且易于检查。但它们扩展性不佳:随着数据库增长,转储和(单线程)恢复会变得极其缓慢,并且夜间转储给出的是粗糙的RPO(最多约24小时)。
- 对于更大或要求更高RPO的系统,升级到物理备份 + 持续的 WAL 归档到对象存储——工具如 pgBackRest、WAL-G 或 Barman。这些提供异地时间点恢复(不仅仅是夜间快照)、并行/更快的恢复,以及更好的RPO。如果你的数据库很大或者RPO目标很严格,把夜间 pg_dump 当作起点,并计划升级。
无论使用哪种机制:
- 最佳场景: 提供商账户本身丢失、损坏或被锁定。或者你需要早于PITR窗口的备份。或者合规性要求一个不可变、可导出的副本。
- 粒度 (RPO): 取决于你的节奏/归档(每日转储 = 潜在丢失最多约24小时;WAL归档 = 秒级)。
- 速度 (RTO): 比PITR慢——你需要下载并重放。对于逻辑转储,恢复时间随数据库大小增长。
- 杀手锏: 它是异地且不依赖特定供应商的。与主数据库完全独立的爆炸半径。
- 陷阱: 逻辑转储是粗粒度的,并且只和最近一次运行一样新鲜。
同时拥有二者的意义: PITR 是你日常的、细粒度的、快速撤销。异地转储是你最坏情况下的保险。在真实事件中,你通常会一起使用它们——这正是我们演练的场景(下面详述)。
第一步:设置两种备份
在写剧本之前,这些必须存在。智能体可以帮助你构建这一切。
时间点恢复:
- 确认你的提供商有PITR,并检查保留窗口(例如7天)。如果预算允许,延长它——窗口越长,你能恢复的灾难越多。
- 验证恢复操作保留了之前的状态(Neon通过自动分支实现)。可逆性保证了实时测试的安全性。
异地转储:
- 一个定时任务(GitHub Actions cron、Vercel cron、Lambda——任何合适的)运行 pg_dump,压缩并用 gzip 压缩,然后上传到不同供应商的存储桶。(扩展到生产规模时,将其替换为像 pgBackRest/WAL-G 这样写入同一存储桶的WAL归档工具。)
- 一个开启了版本控制且具有合理生命周期/保留策略的存储桶。如果需要防勒索软件、防篡改的副本,考虑对象锁定/不可变性。
- 一个只读、最小权限的凭据,仅作用于该备份存储桶,智能体可以使用它来列出和下载转储。不要将你的根密钥交给智能体。
- 额外功能:启用手动触发(例如 workflow_dispatch),这样你可以在几分钟内生成立即转储,而不是等待夜间运行。
💡 提示: 了解实际的转储时间,而不是 cron 表达式。我们的任务计划在03:00 UTC运行,但由于CI排队时间,实际约在04:30 UTC完成。当你在推断“我们会丢失多少数据”时,这个细节很重要。
第二步:编写剧本
在 Devin 中,剧本是一个一等公民的可复用程序,你编写一次,然后附加到任何会话中。你可以在 Devin Web 应用(设置 → 剧本)中创建,给它一个名称和一个触发宏(我们的是 !database_restore),并将主体写成一个通俗易懂、逐步的操作手册。之后,团队任何人都可以启动一个 Devin 会话,附加该剧本(或输入宏),Devin 加载这些指令并自己执行它们——调用数据库/提供商API、运行 psql、切换维护模式、并报告回来。你并不是在编写 Devin 调用的代码;你是在编写 Devin 遵循的检查清单。 (如果你使用的是另一个没有剧本概念的智能体,将相同的内容作为仓库中结构良好的 RESTORE.md 文件,并在提示中引用它,就能达到大部分效果。)
关键见解:剧本就是操作手册。 你正在编写一个细心的人会遵循的检查清单,精确到智能体可以在危险部分不即兴发挥就能执行的程度。
我们的剧本有两种模式:
- 验证模式(默认,非破坏性): 恢复到一次性分支,检查数据看起来正确,然后丢弃。这是你按计划运行以保持诚实的方式。它不触及任何真实数据。
- 灾难模式(破坏性,需要明确授权): 真实操作,针对生产数据库。
一个好的恢复剧本需要按顺序说明:
- 首先进行排查。 确认确实是数据问题,并确定精确的恢复时间戳(“恢复到09:15 UTC之前的状态”)。
- 在接触数据库之前,将应用置于维护模式,这样应用写入和cron作业会停止,你就不会在恢复过程中得到损坏的数据。(见步骤4——使其即时生效,并注意其实际限制:中间件阻止前端写入,并非阻止所有可能的写入者。)
- 选择路径: 损坏在PITR窗口内且提供商健康 → PITR。提供商账户被攻破,或者你需要更旧的/异地副本 → S3转储。
- 首先对当前状态进行快照,即使它已损坏——将其命名为类似 main-before-restore- 这样的明显名称。这是你的“撤销之撤销”安全网。
- 执行恢复(特定的提供商API调用或psql命令)。
- 验证(下方步骤5)——仍然在维护模式下进行。
- 只有验证通过后,才能解除维护模式。
- 报告:恢复了什么,恢复到什么时间,安全分支名称,总停机时间,以及前后行数。
要将以下内容融入剧本,这样智能体就不会搬起石头砸自己的脚:
- 硬性门控: “如果验证失败,保持维护模式开启并停止。不要在错误恢复上解除维护。”
- 无中断的预检: 在启用维护之前,检查凭据有效性以及转储是否可下载/有效。如果S3不可达,你会在关闭网站之前就知道。
- 永远不要在运行过程中删除安全分支。 清理是一个独立的、由人工批准的决策。
- 灾难模式需要明确授权。
剧本与技能——有什么区别?
经验法则:如果你希望智能体自行决定何时应用某些知识,那就做成技能。如果你希望人工有意识地拉动某个杠杆,那就做成剧本。
破坏性的数据库恢复正是剧本的教科书案例,而不是技能。你绝不希望智能体自动决定覆盖生产——这是一个由人工有意拉动、需要授权的杠杆,而这正是手动附加的剧本所提供的。(技能非常适合围绕它的非破坏性习惯——例如,一个仓库技能说明“如何将计划中的验证恢复运行到一次性分支中”。)
第三步:触发智能体
我们有两种触发方式,对应两种不同情况:
真实事件(你,手动): 打开一个 Devin 会话,附加剧本或输入宏 (!database_restore),告诉它发生了什么:“我们大约在09:15 UTC执行了一次错误删除,将生产恢复到09:10。” Devin 加载剧本并逐步执行,在剧本要求暂停的地方暂停。
监督式演练(Devin 生成子 Devin): 在我们的实时测试中,我们让一个主 Devin 会话生成一个单独的 Devin 子会话,专门用于运行剧本,并在实时中观察其工作。Devin 可以启动和监控子会话,这使得操作干净整洁:
- 子智能体在其自己的机器上从头到尾执行程序。
- 父智能体监控进度而不干扰,并向你传递里程碑(“维护模式开启”、“恢复完成”、“已验证”、“维护模式关闭”)。
- 你会得到一个干净、可审计的抄本,记录着确切执行了什么。
第四步:让维护模式即时生效
这是安全恢复背后默默无闻的英雄。你不可能在写入者还在操作数据库时进行干净的恢复。 你需要一个在几秒内就能:
- 将所有流量路由到维护页面,
- 停止应用驱动的写入,
- 并暂停cron/后台作业的开关。
要精确理解“维护模式”实际冻结了什么。 应用层中间件只会停止通过应用前端的写入。它不会自动停止:后台工作进程和队列消费者、命中其他入口点的入站Webhook、已经处于运行中的计划任务,或任何直接连接到数据库的内容。你的维护开关也必须对这些路径进行门控(我们冻结cron,并在API/服务端操作层拒绝写入),并且你应该接受在标志翻转的瞬间,仍有少量正在进行的写入可能落地。唯一真正的写入冻结是在数据库本身——例如,撤销写入权限、将数据库设为只读,或终止所有其他连接。对于短暂的恢复窗口,应用层门控加上暂停的cron通常足够;只是不要告诉自己这是一个硬性保证。
要避免的错误:将维护模式门控在需要重新部署才能修改的环境变量后面。在事件期间,等待3-5分钟来部署切换维护模式是极其痛苦的,并且会扩大你的数据丢失窗口。我们使用在每个请求的中间件中读取的低延迟边缘配置存储(我们使用Vercel Edge Config;Redis键或任何快速KV存储都可以)使其即时生效且无需重新部署:
- 一个 maintenanceMode 标志,中间件在每个请求上检查,将所有请求重定向到 /maintenance。
- 通过API调用,标志在约1–3秒内翻转——无需重新部署。
- 故障打开(刻意做出的可用性权衡): 如果配置读取出错,默认提供流量而不是显示维护页面,这样配置存储的短暂故障就不会黑掉你的整个网站。其代价是事件期间配置中断不会自动门控写入——如果你更倾向于保证门控,则改用故障关闭。有目的地选择失败模式。
- 额外功能:将维护页面的标题/消息/预计完成时间(ETA)存储在同一个配置中,这样你可以在不发布代码的情况下实时更新文案(“预计10:30 ET恢复”)。
我们给了智能体一个针对此功能的小型CLI(maintenance-mode on|off|status),因此剧本步骤只需一条命令。
第五步:验证它确实有效(但不影响生产)
将验证构建成一个你日常持续运行的例行程序,而不仅仅是在事件期间:
- 计划中的验证恢复。 让智能体按计划将最新的异地转储备份恢复到一次性分支,运行完整性检查,并进行报告。如果转储备份损坏或恢复机制出问题,你在周二的下午就能知道——而不是在火情期间。
- 有意义的完整性检查。 关键表(用户、你的核心领域表)的行数,确认所有模式都存在,并检查高写入表中最新的时间戳以确认新鲜度。
- 凭据检查。 确认智能体的备份凭据以预期的最小权限身份进行认证,并且可以列出/读取存储桶。(关于原因详情见下方。)
⚠️ 演练能发现的错误类型。 演练通常会暴露出在纸面上看起来没问题的问题:已过期或范围错误的凭据、失去存储桶读取权限的备份身份、已过期的密钥、悄悄漂移的IAM策略。在有人实际执行路径之前,这些问题都是不可见的——而且它们在全新的、冷启动的紧急会话中最容易造成严重破坏,因为该会话没有你笔记本电脑上的缓存状态。运行演练可以在零生产影响下清除这些问题,这样你就可以集中修复凭据/策略,并在问题真正发生前重新运行。
从未测试过的备份,往往会在关键时刻辜负你。
第六步:进行一次真实的、有破坏性的测试
首先,直言不讳地说明标准实践:测试恢复的正常安全方式是非破坏性的,恢复到单独的分支/克隆/预发布实例(步骤5)。你应该按计划这样做,对于大多数团队来说,这已经足够了——它证明了转储是好的,恢复机制有效,而从不冒生产环境的风险。如果你没有进行这一步……
相似文章
我刚刚为了可靠性重写了整个代理基础设施,有人也这样做吗?
作者描述了在遭遇级联故障后,使用DBOS持久化执行重写其AI代理基础设施以提高可靠性的经历,并向社区询问类似的经历、工具选择以及自建与购买决策。
@walden_yan: 如果你正在构建自己的云代理,比如Devin或Ramp Inspect,这里有关于设置虚拟机的许多精彩细节……
与Walden Yan (Cognition)和Cole Murray (OpenInspect)深入探讨构建云代理,涵盖虚拟机设置、计算机使用、内存以及异步代理在AI工程领域的兴起。
NirDiamant/agents-towards-production
一个全面的开源指南,包含将AI代理转化为生产就绪产品的教程,涵盖部署、记忆、安全等。
@avyvar: 我们让将智能体部署到生产环境变得极其简单,您的编码智能体可在 5 分钟内完成部署。获取生产级 API,支持…
本文介绍了一款新工具,旨在简化 AI 智能体在生产环境的部署,支持在 5 分钟内完成设置,并具备会话扩展、长时间暂停及崩溃恢复等功能。
你们是如何处理AI代理在生产中中途任务失败的?以及这种情况对你们来说有多频繁?
一个讨论提问,询问开发者如何处理AI代理在生产中中途崩溃的情况,探讨重启、持久化状态、使用检查点或手动检查等方法。