新增 Harness 套件
本指南涵蓋為代理 harness 建立新的 @ai-sdk/harness-<name> 套件。
在評估執行時期之前,請先閱讀 Harness 需求 以了解可行性標準和需要記錄的能力缺口。在實作 harness 套件時,請遵循這些需求。
Harness 可以是 主機驅動 的,即執行時期在主機進程中運行,並遠端使用沙盒;或者是 橋接後端 的,即在沙盒內部運行一個小型橋接器,因為執行時期需要本機存取沙盒檔案系統或進程環境。 如果執行時期支援,則優先使用主機驅動。
第一方 vs 第三方 Harness
- 第三方套件:任何執行時期都可以發布外部 harness 套件。
- 第一方
@ai-sdk/harness-<name>套件:請先建立 issue 來討論該執行時期是否屬於此儲存庫。
參考範例
請參閱 https://github.com/vercel/ai/pull/16255/changes 以獲取新增 harness 的完整範例。
Harness 架構
AI SDK 使用遵循適配器模式的分層 harness 架構:
- Harness 規格(
@ai-sdk/harness):定義HarnessV1和HarnessV1Session等介面 - 工具(
@ai-sdk/harness/utils):用於實作 harness 的共享程式碼 - Harness 實作(
@ai-sdk/harness-<name>):針對 harness 的具體適配器 - Harness 代理(
@ai-sdk/harness/agent):高階、面向使用者的HarnessAgentAPI
逐步指南
1. 建立套件結構
使用以下基本結構建立 packages/harness-<name>:
packages/harness-<name>/
├── src/
│ ├── index.ts
│ ├── <name>-harness.ts
│ ├── <name>-harness.test.ts
│ └── <name>-auth.ts # 如果執行時期需要認證解析
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsdown.config.ts
├── turbo.json
├── vitest.node.config.js
└── README.md
如果執行時期必須在沙盒內部執行,則同時加入橋接檔案:
src/
├── <name>-bridge-protocol.ts
├── <name>-bridge-protocol.test.ts
└── bridge/
├── index.ts
├── package.json
└── pnpm-lock.yaml
加入僅包含套件標題(# @ai-sdk/harness-<name>)的 CHANGELOG.md。每個套件都必須有這個檔案。
2. 配置 package.json
以現有的 harness 套件作為 scripts、exports、repository 元資料和發布設定的權威來源。
必要的套件基本資訊:
"name": "@ai-sdk/harness-<name>""type": "module""version": "0.0.0"(新套件的起點)"license": "Apache-2.0""sideEffects": false- 透過
workspace:*依賴@ai-sdk/harness - 使用 sandbox/auth/schema 工具時,透過
workspace:*依賴@ai-sdk/provider-utils - harness 需要的執行時期 SDK/CLI 依賴
- 與現有 harness 套件相符的開發依賴
"engines": { "node": ">=22" }
對於橋接套件,請加入 src/bridge/ 下檔案所需的任何橋接資產複製步驟。
橋接依賴規則(橋接後端 harness):
- 橋接的執行時期依賴存在於
src/bridge/package.json中(在引導時安裝於沙盒內),而不是主 package.json。更改後,使用pnpm --dir packages/harness-<name>/src/bridge install --lockfile-only --ignore-workspace(可從儲存庫根目錄執行)重新產生src/bridge/pnpm-lock.yaml。 - 對於
src/bridge/中的每個第三方匯入,將該依賴加入src/bridge/package.json,以便在沙盒中安裝。tsdown 會自動外部化主套件宣告的依賴、peer 依賴和可選依賴;將未在其中宣告的橋接專用依賴加入tsdown.config.ts的deps.neverBundle中。缺少的依賴或必要的排除可能只會在沙盒執行時期顯示為模組解析錯誤。 - 包含執行時期惰性匯入的套件——例如在執行時期根據模型 ID 解析的提供者 SDK(
@anthropic-ai/sdk、openai)——也應加入src/bridge/package.json,即使沒有直接匯入它們。除非橋接原始碼匯入了它們,否則它們不需要neverBundle條目。只有當實際使用該提供者的模型時,這些才會失敗。 - 將共享依賴的版本(傳輸、schema、工具、執行時期 SDK)與其他 harness 套件當前使用的版本匹配——從兄弟套件複製,而不是自行選擇固定的版本。過時的固定版本會因安全性修補而漂移,並可能與共享的橋接執行時期不同步;請在建立時檢查當前版本。
3. 建立 TypeScript、建置和測試配置
複製最相似的現有 harness 套件配置檔案,並調整路徑/套件名稱:
tsconfig.jsontsconfig.build.jsontsdown.config.tsturbo.jsonvitest.node.config.js
Harness 套件目前僅使用 Node 測試,除非實作有特定理由加入另一個執行時期。
4. 實作 Harness 適配器
從 <name>-harness.ts 匯出一個工廠函式,並從 src/index.ts 重新匯出它。
使用架構文件了解合約細節。在實作時,請確認:
- 回傳一個
specificationVersion: 'harness-v1'的HarnessV1; - 使用穩定的 kebab-case
harnessId; - 透過
builtinTools公開適配器原生的內建工具; - 保持建構同步且無副作用;
- 使用
startOpts.sandboxSession和startOpts.sessionWorkDir;切勿建立單獨的沙盒; - 從需要不支援的執行時期能力的方法中擲出
HarnessCapabilityUnsupportedError; - 除非執行時期技術上需要,否則不要硬編碼預設模型——有些底層 SDK 沒有自己的預設值。否則,僅在使用者配置了模型時才傳遞模型,並保持原始 SDK 的預設值不變;保持 session 的
modelId與實際發送的內容一致(不要報告一個被橋接靜默覆寫的模型); - 處理
doPromptTurn/doContinueTurn可能接收到的tools和instructions:如果執行時期無法接受自訂tools,則擲出HarnessCapabilityUnsupportedError,以便明確知悉而不是靜默丟棄;如果沒有原生的instructions輸入,則將其附加到第一條使用者訊息之前(Codex/Claude Code 的變通方法); - 在為
sandbox.run/sandbox.spawn建構 shell 指令時,對插值路徑(workDir、橋接狀態目錄等)加上引號——它們可能包含空格。
如果執行時期需要在沙盒內設定,請公開 getBootstrap()。
5. 實作執行時期特定的關注點
僅加入執行時期需要的關注點:
- 認證解析——為了 AI Gateway 支援,請使用中央的
getAiGatewayAuthFromEnv()輔助函式,而不是直接讀取環境變數。這確保了VERCEL_OIDC_TOKEN和AI_GATEWAY_API_KEY都被接受為 Gateway 憑證。當執行時期按模型解析提供者時,從模型 ID 解析提供者並設定該提供者的環境變數;如果透過 Gateway 路由,請注意基本 URL 約定因提供者而異(例如,Anthropic 用戶端會將/v1/messages附加到根基礎 URL,而 OpenAI 用戶端會附加到/v1基礎 URL); - AI Gateway 用戶端歸屬——遵循現有 harness 套件中的約定:定義一個版本化的用戶端應用程式值,例如
ai-sdk/harness-<name>/${VERSION},並將其用於 Gateway 請求。當底層執行時期/SDK 同時支援時,配置User-Agent和x-client-app標頭;這兩個標頭中至少需要一個。如果執行時期無法直接設定任意標頭,請使用執行時期支援的等效方法來產生這些標頭之一(例如,SDK 用戶端應用程式環境變數); - 自訂工具 schema 轉換——如果您將主機工具的 JSON Schema 轉換為執行時期的工具格式,請遞迴轉換(巢狀物件、陣列
items、列舉、描述);僅扁平化頂層轉換會靜默丟棄模型的結構化指導。如果執行時期接受,直接傳遞 JSON Schema 可以避免此問題; - 技能或探索檔案具體化;
- 原生協定到 harness 串流/控制轉換;
- 生命週期狀態 schema;
- 橋接協定和診斷。
Harness 適配器的某些結構約定正在透過 konsistent CLI 強制執行。
完成後執行 pnpm konsistent 來檢查這些約定。在繼續之前修復任何標記的違規。
6. 撰寫測試
為以下內容加入聚焦的 Node 測試:
- 工廠元資料和設定;
- 認證解析;
- 沙盒使用和路徑放置;
- 主機驅動的遠端操作或橋接協定行為;
- 提示/控制事件轉換;
- 恢復 session 與繼續回合行為;
- 不支援的能力錯誤;
- 技能具體化(如果支援)。
盡可能使用模擬的沙盒 session 和橋接/執行時期邊界。單元測試中不需要即時提供者憑證。
getBootstrap() 讀取編譯後的橋接資產(例如 dist/bridge/index.mjs),這在針對 src 運行測試時不存在,因此呼叫它的測試會遇到 ENOENT。請模擬 node:fs/promises 的 readFile 用於橋接資產路徑(請參閱 Codex/OpenCode harness 測試以了解模式)。
7. 加入 README
保持 README 簡短:
- 套件用途;
- 設定指令;
- 最小化的
HarnessAgent用法; - 必要的沙盒能力,例如橋接後端執行時期所需的連接埠;
- 重要的認證配置。
連結到主要 harness 文件以了解更廣泛的概念。
8. 加入範例
為新的 harness 加入相關範例。
- 在
examples/ai-functions/src/harness-agent下加入必要的 API/函式範例,並在examples/harness-e2e-next下加入互動式範例。
9. 加入文件
在 content/providers/02-ai-sdk-harnesses/<next number>-<name>.mdx 中建立文件。
內容應包含:
- 設定說明
- 必要的沙盒能力
- 認證配置
- Harness 特定的選項
- 使用範例
- 已知限制
當新的 harness 準備好公開時,更新 content/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx 以列出它。
10. 更新參考並驗證
從工作區根目錄執行:
pnpm konsistent
pnpm update-references
pnpm --filter @ai-sdk/harness-<name> build
pnpm --filter @ai-sdk/harness-<name> test
pnpm type-check:full
使用 pnpm changeset 加入一個 changeset。對於全新 harness 套件的首次發布,請使用 major(而不是通常的 patch),與其他 harness 套件一致。
及早針對即時沙盒運行相關的 harness 範例——不要僅依賴單元測試和 type-check。執行時期 API 限制(例如,意外的配置選項拒絕、執行時期發出的確切串流事件名稱、Gateway 基礎 URL 格式)只有在橋接實際驅動執行時期時才會浮現,而且在文件/範例建立在之上之前發現它們的成本要低得多。
檢查清單
- 在
packages/harness-<name>中建立了套件結構 - 配置了
package.json,具有正確的依賴 - 設定了 TypeScript 配置(
tsconfig.json、tsconfig.build.json) - 建置配置(
tsdown.config.ts) - 測試配置(
vitest.node.config.js) - Harness 適配器實作完成
- 在不建立隱藏沙盒的情況下處理了執行時期放置
- 如果是橋接後端,在建置期間複製了橋接資產
- 如果需要,實作了認證解析
- AI Gateway 請求包含
User-Agent和/或x-client-app用戶端歸屬 - Harness 基礎架構、技能、橋接程式碼和秘密已排除在
sessionWorkDir之外 - 測試了 Session 恢復和回合繼續
- 撰寫了單元測試並通過
- 撰寫了 README.md
- 加入了
CHANGELOG.md(套件標題;konsistent需要) - 加入了 Changeset(首次發布為
major) - 加入了範例
- 在
content/providers/02-ai-sdk-harnesses/中加入了文件 - 如果公開,更新了 Harness 適配器列表
- 針對即時沙盒進行了驗證(不僅是單元測試 / type-check)
- 執行了
pnpm update-references - 套件建置通過
- 套件測試通過
- 類型檢查通過(從根目錄執行
pnpm type-check:full) - 相關範例成功運行
相關文件
- Harness 抽象架構
@ai-sdk/harnessREADME- 現有的具有類似執行時期放置的 harness 套件