让每个 harness 持久运行

让每个 harness 持久运行

💡 原文英文,约1900词,阅读约需7分钟。
📝

内容提要

Vercel 推出开源工具 durable-harness,使 Pi、OpenCode、Codex、Claude Code 等编码代理框架能在云端持久运行。该工具基于 Workflow SDK 的 World 接口,将每轮对话的模型调用与工具调用写入持久日志;函数崩溃或超时后,由队列转交新函数并从日志恢复未完成的工作,避免重复计费与进度丢失。工具可标记为安全重放或绝不重放,文件可存于日志、内存或独立沙箱,并支持 Vercel、Postgres 及本地部署。

🔎

延伸解读

持久化机制如何避免重复计费

durable-harness 在每次模型调用或工具调用前记录意图,完成后记录结果。函数崩溃后,新函数从日志读取已完成调用的结果,不会重新执行,因此不会为已完成的模型调用重复支付 token 费用。对于被中断的工具,标记为 replay: 'safe' 的会自动重跑,其他工具则告知模型可能已执行,由模型决定是否检查。这解决了云端代理因超时或网络错误导致进度丢失和重复计费的问题。

工具重放策略:安全与绝不重放

文章通过退款示例说明工具需声明重放策略:查询类工具标记为 'safe',崩溃后可自动重跑;退款类工具标记为 'never',绝不运行两次,模型会被告知调用可能已发生,从而先检查再决定。这种设计让开发者根据工具副作用选择行为,避免重复执行有副作用的操作,同时保证只读操作能快速恢复。

文件系统选项与沙箱选择

durable-harness 提供三种文件处理方式:virtual() 将文件保存在会话日志中,适合短任务和小工作区;virtual({ durable: false }) 将文件放在内存中,每轮结束清除,适合临时草稿;sandbox() 为会话提供独立的 Vercel Sandbox,/workspace 持久化,适合真实项目和长时间运行。Claude Code 和 Codex 因需要真实 shell 和文件系统,始终运行在 Vercel Sandbox 中。

World 接口带来的可移植性

durable-harness 基于 Workflow SDK 的 World 接口,该接口统一了日志、队列和流。开发者可以在 Vercel、本地文件、Postgres、MongoDB、Redis 或 Turso 之间切换,而无需修改代理代码。例如设置两个环境变量即可将代理迁移到 Postgres。这种设计让同一代理能在不同部署环境间迁移,降低了自托管和本地开发的切换成本。

❓

Q&A

durable-harness 是什么?它主要解决什么问题?

durable-harness 是 Vercel 推出的开源工具,让 Pi、OpenCode、Codex、Claude Code 等编码代理框架能在云端持久运行。它解决的是云端 harness 在函数崩溃或超时后丢失进度、重复计费的问题,通过持久日志和队列恢复未完成的工作。

durable-harness 是如何在崩溃后恢复会话的?

它基于 Workflow SDK 的 World 接口,将每轮对话的模型调用与工具调用写入持久日志:调用前记录意图,完成后记录结果。每轮还通过队列消息兜底,函数崩溃后队列将任务转交新函数,新函数读取日志继续未完成的工作,已完成的调用不会重复执行。

工具在崩溃后重放时,如何避免重复执行有副作用的操作?

每个工具可标记重放策略:'safe' 表示可安全重放(如查询),崩溃后会再次运行;'never' 表示绝不重放(如退款),模型会被告知该调用可能已执行,由模型决定是否先检查再重试。

durable-harness 支持哪些部署环境?

支持在 Vercel 上运行(使用 Vercel World),本地开发时使用文件系统,自托管时可用 Postgres、MongoDB、Redis 或 Turso。通过设置 WORKFLOW_TARGET_WORLD 和 WORKFLOW_POSTGRES_URL 等环境变量即可切换。

durable-harness 对文件存储提供了哪些选项?

提供三种选项:virtual() 将文件保存在会话日志中,带 bash 兼容 shell 但无法访问函数文件或网络,适合短任务;virtual({ durable: false }) 将文件保存在内存中,每轮结束清除;sandbox() 为会话提供独立的 Vercel Sandbox,/workspace 持久化,适合真实项目和长任务。

如何在 Vercel 上查看 durable-harness 会话的执行轨迹?

通过 Vercel 的 Agent Runs 功能,可以查看每个会话的完整轨迹,包括每次模型调用和工具调用。崩溃后恢复的轮次会出现在同一轨迹中,能清楚看到中断和恢复的位置。

🏷️

标签

➡️

继续阅读