[控场AI]
· 7 分钟阅读· 3,970 字

让每个编码代理框架都具备持久性

让每个编码代理框架都具备持久性

durable-harness 为任意编码代理框架注入崩溃恢复能力,实现云端持久运行。

编码代理框架正从本地迁移至云端,但云端虚拟机不会自动记录已完成的模型与工具调用,崩溃即意味着工作丢失。Vercel 推出的 durable-harness 复用 Workflow SDK 的持久化机制,通过“日志与队列”让 Pi、OpenCode、Codex、Claude Code 等任意框架具备崩溃恢复能力:调用前记录意图、完成后记录结果,轮次由队列兜底交给新函数从断点继续,已完成的模型调用不会重复计费。工具通过 replay 策略声明中断行为,文件系统提供 virtual 与 sandbox 多种选项。World 接口统一日志、队列和流,支持 Vercel、本地文件、Postgres 等多种后端,代码无需更改即可迁移。文档机制则让待办列表等非对话状态同样持久。

从本地到云端:编码代理框架的持久性挑战

开发者早已习惯通过 Pi、Claude Code 等编码代理框架(harness)在本地运行编码代理。这些工具在日常代码生成中表现可靠,但若要实现全天候运行,就必须让电脑保持开机和唤醒状态——由此催生了“笔记本合盖”的梗和 Mac mini 的需求激增。

如今,编码代理框架正迁移至云端,合上盖子不再是问题。然而,云端运行引入了新的复杂性:本地框架对工作区和会话历史有直接、持续的磁盘访问权限,中断后只需一个简单提示即可恢复;而在云端的虚拟机上,系统不会自动记录哪些模型和工具调用已完成,崩溃后也无法恢复被中断的轮次,一次失败的调用或网络错误就意味着工作丢失。此外,并非所有代理任务都需要沙箱——数据库查询和 API 调用可以安全地在函数中运行,这也意味着所需凭证无需进入沙箱。

durable-harness:为任意框架注入持久性

Vercel 此前构建了 eve 和 fx,使其在云端天生具备持久性。现在推出的 durable-harness 将这种持久性扩展到了任意框架,包括 Pi、OpenCode、Codex 和 Claude Code。它利用驱动 Workflow SDK 的同一套机制来抵御崩溃和函数超时。

借助 durable-harness,开发者可以:

  • 在 Vercel 上持久运行上述任意框架
  • 使用自己的 Postgres 实例自托管框架
  • 使本地框架工作流具备持久性
  • 构建自己的持久化框架

其核心设计围绕“日志与队列”展开。durable-harness 是一组适配器和工具集,让现有框架将会话保存在 World(Workflow SDK 的持久化后端)中。它在模型调用或工具调用运行前记录意图,调用完成后记录结果。轮次本身由队列消息兜底:如果函数死亡,队列会将轮次交给新函数,新函数读取日志并从断点继续。

Workflow SDK 是 Vercel 推出的用于构建持久化、可恢复工作流的开发工具包。它把长时间运行的任务拆分为可重放的步骤(step),每一步的输入输出都被记录到持久化存储中。当函数因超时或崩溃中断时,SDK 能从最后完成的步骤继续执行,而无需从头开始。Workflow SDK 的核心抽象是 World,它封装了日志、队列和流三种能力,使工作流引擎与具体存储后端解耦。durable-harness 正是复用这套底层机制,将持久性从原生支持的工作流扩展到第三方编码代理框架。

崩溃恢复的机制细节

以编码代理为现有应用添加定价页面为例:代理读取现有页面、写入新页面、发起拉取请求,并等待 CI 完成后报告。如果 CI 仍在运行时函数超时,会发生什么?

没有持久性时,代理会停止工作直到手动重启,已完成的工作被不必要地重复。而有了 durable-harness,新函数会从日志中读取已完成的结果并恢复轮次。如果浏览器断开连接,代理继续运行,重新连接时从日志追赶进度。

崩溃后,日志会明确记录:哪些调用已完成、哪些正在运行、哪些从未开始。已完成的调用永远不会再次运行,因为其结果从日志读取——这意味着你不会为已完成的模型调用的 token 付费两次。模型会记住之前的调用而不是重复它们。被中断的工具若标记为 replay: 'safe' 则会重新运行;其他工具会以“可能已运行”的状态返回给模型,由模型决定是否检查。

对于保留自身会话文件的框架(如 Claude Code 的 transcript、Codex 的 rollout、OpenCode 的事件存储),每条记录都会镜像到日志中,新函数或 Sandbox 可从中重建它们。

幂等性(idempotency) 是理解崩溃恢复的关键概念。一个操作如果执行多次与执行一次的效果相同,就称为幂等。在代理运行中,模型调用通常不是幂等的——重复调用会消耗额外 token 并可能产生不同结果;而查询类工具(如读取文件、搜索)往往是幂等的。durable-harness 的 replay: 'safe' 标记本质上是在声明该工具具备幂等性,可以安全重跑;'never' 则标记非幂等操作(如退款),必须避免重复执行。日志记录“意图”与“结果”的模式,正是实现恰好一次(exactly-once)语义的常见手段:先写意图再执行,完成后写结果,恢复时依据日志判断哪些步骤已完成。

工具与文件系统的安全策略

每个工具都需要声明崩溃中断时的行为。'safe' 工具(如查找)可以再次运行;'never' 工具(如退款)永不运行两次——模型会被告知调用可能已发生,以便在重试前进行检查。

文件系统方面,durable-harness 提供了三种选项:

  • virtual():文件保存在会话日志中,附带兼容 bash 的 shell,无法访问函数文件或网络,适合短任务和小工作区
  • virtual({ durable: false }):文件保存在内存中用于草稿工作,每轮结束时清除
  • sandbox():为会话提供独立的 Vercel Sandbox,/workspace 位于比沙箱和函数更持久的 Drive 上,适合真实项目和长时间运行的工作

Claude Code 和 Codex 始终运行在 Vercel Sandbox 中,因为它们需要真实的 shell 和文件系统,不适合多租户使用。

Vercel Sandbox 是一种隔离的临时计算环境,为每次会话提供独立的文件系统和 shell,与宿主函数及其他租户相互隔离。它适合运行需要真实文件系统、任意命令执行或网络访问的代理任务,但启动有一定延迟,且默认生命周期有限。durable-harness 将 /workspace 放在比沙箱本身更持久的 Drive 存储上,意味着沙箱实例被回收或重建后,工作区文件仍然保留,新沙箱可以挂载同一 Drive 继续工作。这种“计算 ephemeral、存储持久”的分离,是云端代理实现长时间运行和崩溃恢复的基础设施前提。

World 接口:一次编写,随处运行

持久化代理需要每一步的日志、进程死亡后恢复轮次的方式,以及供观察者使用的流。Workflow SDK 将这三者封装在一个接口 World 之后。durable-harness 写入该接口,因此同一代理可以从一个 World 迁移到另一个而无需更改代码:在 Vercel 上使用 Vercel World,开发时使用本地文件,自托管时使用 Postgres、MongoDB、Redis 或 Turso。

两个环境变量即可将所有使用 durable-harness 的代理迁移到 Postgres:

WORKFLOW_TARGET_WORLD="@workflow/world-postgres"
WORKFLOW_POSTGRES_URL="postgres://user:password@host:5432/database"

在 Vercel 的 Agent Runs 标签页中,每个会话的追踪记录都会展示,包括每次模型调用和工具调用。崩溃后恢复的轮次会出现在同一追踪中,清晰显示轮次在哪里停止、从哪里继续。

Postgres、MongoDB、Redis 和 Turso 在这里都是作为 World 接口的存储实现。Postgres 和 MongoDB 是通用数据库,提供事务与持久化保证,适合生产自托管;Redis 是内存键值存储,读写极快但持久性取决于配置,适合对延迟敏感的场景;Turso 是基于 SQLite 的边缘数据库,轻量且支持嵌入式部署。由于 durable-harness 只依赖 World 抽象,切换后端只需更改 WORKFLOW_TARGET_WORLD 环境变量和对应连接串,代理代码无需改动。这种可移植性避免了供应商锁定,也让本地开发(文件后端)与云端生产(Postgres 等)可以使用同一套代码路径。

文档:会话状态的新载体

有些状态属于会话但不属于对话,例如待办列表、计划或代理填写的表单。文档(document)是存在于会话日志中的类型化 JSON,因此它能抵御崩溃并随会话移动。工具可以通过 io.docs 编辑文档,每次编辑与工具结果一起提交到日志,确保文档的持久状态与工具调用本身保持一致。

应用可以读取和编辑同一文档而无需自己的数据库,聊天路由甚至可以将每次变更流式传输到 UI。事实上,前面提到的 virtual() 工作区正是基于文档构建的:其文件树是会话日志中的一个文档,每次工具调用的变更随结果一起提交。

结语

开发者选择某个框架,是基于它在提示、工具和上下文方面做出的选择。框架如何抵御崩溃不应成为选择之一。借助 durable-harness,中途失去函数的轮次会从日志在新函数上继续,无需手动重试,也不会重复已完成的工作。通过构建在 Workflow SDK 的 World 接口之上,自托管和可移植性开箱即用。durable-harness 已在 GitHub 上开源。

对于使用编码代理的团队而言,这意味着可以真正将代理视为可靠的基础设施组件——即使底层函数崩溃,会话也能无缝恢复,已完成的计算不会被重复计费。

#durable-harness#编码代理框架#Vercel#Workflow SDK#崩溃恢复#Claude Code#持久化代理
分享:

相关推荐