Vercel 推出 durable-harness 讓所有 harness 可持久化
Making every harness durable
durable-harness 讓任何 harness(如 Pi、OpenCode、Codex、Claude Code)都能在雲端或自建環境下持久化執行,避免因函式失敗或網路錯誤造成工作遺失。
提供了在雲端持久化執行 coding harness 的方法,讓開發者能輕鬆構建長期執行的 agent 工作流程。
開發者熟悉透過 Pi、Claude Code 等工具在本地執行編碼代理。它們是生成程式碼的可靠日常工具,但要讓代理全天候執行,必須保持電腦開機且不睡眠,這也促成了筆記本蓋子 meme 與 Mac mini 需求激增。
在雲端執行工具
工具工作負載正遷移至雲端。個別開發者正在部署持續運作的編碼代理工作流程,像 OpenWork 與 HanaAgent 等專案利用開源工具作為應用程式背後的引擎,工程師亦在打造自己的工具產品。
這些工具設計為長時間執行的流程,保持會話在記憶體中,代理任務通常會執行數分鐘或數小時。在本地,工具可直接、持續存取同一磁碟上的工作區與會話歷史,因此恢復中斷工作僅需簡單提示。
在雲端,你可以使用虛擬機器與持久儲存來複製此設定,但虛擬機器並不會自動記錄已完成的模型與工具呼叫,亦無法在崩潰後恢復中斷的回合。失敗的回合或網路錯誤將導致工作遺失。
此外,並非所有透過工具執行的代理任務都需要沙盒。資料庫查詢與 API 呼叫可在函式中安全執行,亦表示所需憑證永遠不必進入沙盒。
打造每個工具的耐久性
我們建置了eve和fx,讓它們能在雲端即插即用並持續執行,今天我們推出durable-harness,將這種耐久性延伸到任何執行環境,包括Pi、OpenCode、Codex與Claude Code。它使用與Workflow SDK相同的機制來抵禦崩潰與函式逾時。
使用 durable-harness,你可以:
在 Vercel 上持久執行任何這些工具
以自己的 Postgres 例項自行託管工具
使你的本地工具工作流程具備耐久性
打造您自己的耐久 harness
在回合中途崩潰仍能存活的 Session
以一個編碼代理為例,為現有應用程式新增一個價格頁面。代理閱讀現有頁面,撰寫新頁面,開啟 Pull Request,並在 CI 完成前等待再回報。
如果其函式在 CI 仍在執行時超時,會發生什麼?
在以下示範中終止函式或斷開連線,以比較兩個代理如何恢復以及哪些工作會被重複。
若缺乏耐久性,代理會停止工作直到手動重啟,且已完成的工作會被不必要地重複。
使用 durable-harness,新函式會從日誌讀取已完成的結果並繼續進行回合。若瀏覽器斷線,代理仍會繼續執行,重新連線時會從日誌追蹤進度。
日誌與佇列
durable-harness 是我們開源產品組閤中最新的套件。它是一組介面卡與工具,能讓您已經使用的 harness 在 World(Workflow SDK 的耐久後端)中保持其會話。
它會將回合的每一步寫入耐久日誌。在模型呼叫或工具呼叫執行前,它會記錄一個意圖;呼叫結束時,則記錄結果。整個回合以佇列訊息作為後備支援,因此若函式失敗,佇列會將回合交給新函式,該函式會讀取日誌並從中斷處繼續。
在崩潰之後,日誌會說明哪些已完成、哪些正在執行,以及哪些從未開始:
已完成的呼叫不會再次執行,因為其結果已從日誌讀取,您不會因已完成的模型呼叫的 tokens 被重複計費。
模型會記住之前的呼叫,而非重複執行。
被標記為
replay: 'safe'的中斷工具會再次執行。其他任何工具則會回傳給模型,模型決定是否檢查。
保持自身會話檔案的 harness,例如 Claude Code 的 transcript、Codex 的 rollout,以及 OpenCode 的 event store,會把每筆記錄映象到日誌中,這樣新的函式或 Sandbox 就能從中重建。
選擇你的 harness
fx 和 eve 本身即具備耐久性。其餘的,durable-harness 會從外部提供耐久性,且不改變 harness。
欲瞭解每個 harness 的完整設定指南,請參閱 docs。
適用於各處
耐久代理需要每一步的日誌、在其程序終止時恢復回合的方法,以及供觀察者使用的串流。
Workflow SDK 將這三項功能封裝於一個介面:World。
durable-harness 將資料寫入該介面,讓你可以在不改變程式碼的情況下,將同一個代理從一個 World 移動到另一個 World:
在 Vercel 上,它使用 Vercel World。
開發時,它使用 files on your machine。
在你自己的伺服器上,它使用 Postgres、MongoDB、Redis 或 Turso。
兩個變數將每個代理移動至 durable-harness 的 Postgres。
若想更細緻控制,例如設定名稱空間或在伺服器啟動時恢復會話,請在程式碼中建立 World,並將其傳遞給代理:
更多細節請參閱 self-hosting docs。
在 Agent Runs 中檢視每個會話
Agent Runs 在 Vercel 上顯示每個會話的追蹤,包括每個模型呼叫與工具呼叫。經過崩潰後恢復的回合會出現在同一追蹤中,讓你能準確看到回合停止與重新開始的位置。
工具
代理僅擁有你給予的工具,並在你的函式中執行。每個工具都會說明若發生崩潰應如何處理。'safe' 工具,例如查詢,能再次執行。'never' 工具,例如退款,永遠不會執行兩次:模型會被告知該呼叫可能已發生,於是它會在再次嘗試前先檢查。
以下示範了上述示範中程式編寫代理可能如何定義其工具:
讀取檔案或檢查 CI 狀態的工具被標記為
'safe',以便能自動再次執行。釋出 PR 評論的工具被標記為
'never',以避免評論被重複釋出。
以下範例使用處理退款的代理為例,為每項政策定義一個工具:
關於每個 harness 的內建工具,例如其 shell 與檔案編輯,請繼續閱讀。
檔案
當 harness 需要 shell 與檔案時,直接在共享的無伺服器函式主機上執行並不安全。許多會話可能共用同一個函式,且其檔案系統無法保證在多次呼叫間持續存在。
為瞭解決此問題,durable-harness 為你提供幾個選項:
virtual()將檔案儲存在會話日誌中,並提供一個無法存取你函式檔案或網路的 bash 相容 shell。它適用於短暫任務與小型工作區,無需啟動完整 sandbox。virtual({ durable: false })將檔案儲存在記憶體中作為草稿工作,並在每回合結束時清除。sandbox()為會話提供自己的 Vercel Sandbox,並在一個持續存在於每個 sandbox 與每個函式之外的 Drive 上使用/workspace。它適用於實際專案與長時間運作。
請在 docs 中並排比較三種方案。
每個 harness 的內建工具都在你選擇的工作區執行。使用 Pi 時,CodingTools 安裝 Pi 自己的 read、write、edit 與 bash,且 virtualEnv() 或 sandboxEnv() 為它們提供工作區:
對於 OpenCode,將工作空間傳遞為 workspace;對於 fx,傳遞到 fxTools()。Claude Code 和 Codex 永遠在 Vercel Sandbox 中執行,因為它們需要真正的 shell 和檔案系統,且不適合多租戶使用。啟用它們的內建工具後,工具會在會話的 Drive 上運作,啟用方式為 builtins: true。每個 harness guide 都列出了其內建工具。
檔案
有些狀態屬於會話,但不是對話的一部分,例如待辦清單、計畫或代理人填寫的表單。檔案是一種 typed JSON,存在於會話的日誌中,因此在崩潰時仍能保留,並隨會話遷移。
工具可以透過 io.docs 編輯檔案,每一次編輯都會與工具結果一起提交到日誌,確保檔案的持久狀態與工具呼叫保持一致:
您的應用程式可以在沒有自有資料庫的情況下讀取並編輯同一份檔案,聊天路徑甚至可以將每一次變更即時串流到您的 UI:
事實上,之前的 virtual() 工作空間就是建立在檔案之上:其檔案樹是會話日誌中的一份檔案,每一次工具呼叫的變更都與其結果一起提交。
瞭解更多關於 工具、檔案與檔案 以及如何 保護您的代理人安全。
總結
開發者選擇 harness 的原因在於它對提示、工具與上下文的選擇。它如何在崩潰後存活不應成為選擇之一。使用 durable-harness 時,若某一輪在執行過程中失去功能,系統會從日誌繼續到新的輪次,無需手動重試,也不會重複已完成的部分。自託管與可攜性可即時使用,因為它建立在 Workflow SDK 的 World 介面之上。
durable-harness 是 在 GitHub 上開源。