新しいハーネスパッケージの追加
このガイドでは、エージェントハーネスのための新しい @ai-sdk/harness-<name> パッケージを作成する方法を説明します。
ランタイムを評価する前に、ハーネス要件 を読んで、実現可能性の基準と文書化すべき機能ギャップを確認してください。要件に従いながらハーネスパッケージを実装します。
ハーネスは ホスト駆動型 と ブリッジバック型 の2種類があります。ホスト駆動型 では、ランタイムがホストプロセス内で実行され、サンドボックスをリモートで使用します。ブリッジバック型 では、ランタイムがサンドボックスのファイルシステムやプロセス環境にローカルアクセスする必要があるため、小さなブリッジがサンドボックス内で実行されます。ランタイムがサポートしている場合は、ホスト駆動型を優先してください。
ファーストパーティハーネスとサードパーティハーネス
- サードパーティパッケージ: どのランタイムでも外部ハーネスパッケージを公開できます。
- ファーストパーティ
@ai-sdk/harness-<name>パッケージ: 最初にIssueを作成して、ランタイムがこのリポジトリに含まれるべきかどうかを議論してください。
参考例
新しいハーネス追加の完全な例については、https://github.com/vercel/ai/pull/16255/changes を参照してください。
ハーネスアーキテクチャ
AI SDKは、アダプタパターンに従った階層型ハーネスアーキテクチャを使用しています。
- ハーネス仕様 (
@ai-sdk/harness):HarnessV1やHarnessV1Sessionなどのインターフェースを定義します。 - ユーティリティ (
@ai-sdk/harness/utils): ハーネス実装のための共有コードです。 - ハーネス実装 (
@ai-sdk/harness-<name>): ハーネス用の具体的なアダプタです。 - ハーネスエージェント (
@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の設定
既存のハーネスパッケージをスクリプト、エクスポート、リポジトリメタデータ、公開設定の信頼できる情報源として使用します。
必須のパッケージ基本情報:
"name": "@ai-sdk/harness-<name>""type": "module""version": "0.0.0"(新しいパッケージの開始点)"license": "Apache-2.0""sideEffects": false@ai-sdk/harnessへの依存 (workspace:*経由)- サンドボックス/認証/スキーマユーティリティを使用する場合、
@ai-sdk/provider-utilsへの依存 (workspace:*経由) - ハーネスに必要なランタイムSDK/CLI依存関係
- 既存のハーネスパッケージと一致する開発依存関係
"engines": { "node": ">=22" }
ブリッジパッケージの場合、src/bridge/ 下のファイルに必要なブリッジアセットコピーステップを追加します。
ブリッジ依存関係のルール (ブリッジバック型ハーネス):
- ブリッジのランタイム依存関係は、
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 はメインパッケージで宣言された依存関係、ピア依存関係、オプションの依存関係を自動的に外部化します。そこで宣言されていないブリッジ専用の依存関係は、tsdown.config.tsのdeps.neverBundleに追加します。依存関係や必要な除外が欠けていると、サンドボックス実行時にモジュール解決エラーとして現れることがあります。- ランタイムが 遅延インポート するパッケージ (例: モデルIDから実行時に解決されるプロバイダSDK (
@anthropic-ai/sdk、openai)) は、何も直接インポートしていなくてもsrc/bridge/package.jsonに含めます。ブリッジソースがそれらをインポートしない限り、neverBundleエントリは必要ありません。これらは、そのプロバイダのモデルが実際に使用された場合にのみ失敗します。 - 共有依存関係のバージョン (トランスポート、スキーマ、ツール、ランタイムSDK) を、他のハーネスパッケージが現在使用しているものに合わせます — 独自のピンを選択するのではなく、兄弟パッケージからコピーします。古いピンはセキュリティパッチから逸脱し、共有ブリッジランタイムとの非同期を引き起こす可能性があります。作成時に現在のバージョンを確認してください。
3. TypeScript、ビルド、テスト設定の作成
最も近い既存のハーネスパッケージの設定ファイルをコピーし、パス/パッケージ名を調整します。
tsconfig.jsontsconfig.build.jsontsdown.config.tsturbo.jsonvitest.node.config.js
ハーネスパッケージは、実装に別のランタイムを追加する特定の理由がない限り、現在Nodeテストのみを使用します。
4. ハーネスアダプタの実装
<name>-harness.ts からファクトリをエクスポートし、src/index.ts から再エクスポートします。
契約の詳細についてはアーキテクチャドキュメントを参照してください。実装時には、以下を確認します。
specificationVersion: 'harness-v1'を持つHarnessV1を返す。- 安定したケバブケースの
harnessIdを使用する。 builtinToolsを通じてアダプタネイティブの組み込みツールを公開する。- コンストラクションを同期的かつ副作用なしに保つ。
startOpts.sandboxSessionとstartOpts.sessionWorkDirを使用する。別のサンドボックスを作成しない。- サポートされていないランタイム機能を必要とするメソッドから
HarnessCapabilityUnsupportedErrorをスローする。 - ランタイムが技術的にデフォルトモデルを必要とする場合を除き、デフォルトモデルをハードコードしない。基盤となるSDKによっては独自のデフォルトがないものもある。それ以外の場合は、コンシューマーが設定した場合にのみモデルを渡し、元のSDKのデフォルトはそのままにしておく。セッションの
modelIdを実際に送信されるものと一致させる (ブリッジが静かに上書きしたモデルを報告しない)。 doPromptTurn/doContinueTurnが受け取る可能性のあるtoolsとinstructionsを処理する。ランタイムがカスタムtoolsを受け入れられない場合はHarnessCapabilityUnsupportedErrorをスローして、静かに無視されるのではなく明示的にする。ネイティブのinstructions入力がない場合は、最初のユーザーメッセージの前にそれらを追加する (Codex/Claude Codeの回避策)。sandbox.run/sandbox.spawnのシェルコマンドを構築する際に、補間されたパス (workDir、ブリッジ状態ディレクトリなど) を引用符で囲む。スペースを含む可能性があるため。
ランタイムがサンドボックス内でのセットアップを必要とする場合は、getBootstrap() を公開します。
5. ランタイム固有の懸念事項の実装
ランタイムが必要とする懸念事項のみを追加します。
- 認証解決 — AI Gatewayサポートのために、環境変数を直接読み取るのではなく、中央の
getAiGatewayAuthFromEnv()ヘルパーを使用します。これにより、VERCEL_OIDC_TOKENとAI_GATEWAY_API_KEYの両方がGateway資格情報として受け入れられることが保証されます。ランタイムがプロバイダをモデルごとに解決する場合、モデルIDからプロバイダを解決し、そのプロバイダの環境変数を設定します。ゲートウェイを経由してルーティングする場合、ベースURLの規則はプロバイダごとに異なることに注意してください (例: Anthropicクライアントはルートベースに/v1/messagesを追加し、OpenAIクライアントは/v1ベースに追加します)。 - AI Gatewayクライアント属性 — 既存のハーネスパッケージの規則に従います。
ai-sdk/harness-<name>/${VERSION}のようなバージョン管理されたクライアントアプリ値を定義し、Gatewayリクエストに使用します。基盤となるランタイム/SDKが両方をサポートしている場合は、User-Agentとx-client-appの両方のヘッダーを設定します。これらのヘッダーのうち少なくとも1つは必須です。ランタイムが任意のヘッダーを直接設定できない場合は、これらのヘッダーのいずれかを生成するランタイムがサポートする同等の方法 (例: SDKのクライアントアプリ環境変数) を使用します。 - カスタムツールスキーマ変換 — ホストツールのJSON Schemaをランタイムのツール形式に変換する場合は、再帰的に 変換します (ネストされたオブジェクト、配列
items、列挙型、説明)。フラットなトップレベルのみの変換では、モデルの構造化されたガイダンスが静かに失われます。ランタイムがそれを受け入れる場合は、JSON Schemaを直接渡すことで問題を回避できます。 - スキルまたはディスカバリーファイルの具体化。
- ネイティブプロトコルからハーネスストリーム/制御への変換。
- ライフサイクル状態スキーマ。
- ブリッジプロトコルと診断。
ハーネスアダプタに関する特定の構造上の規則は、konsistent CLI によって適用されています。
完了したら pnpm konsistent を実行して、それらを確認します。先に進む前に、フラグが立てられた違反を修正してください。
6. テストの作成
以下のためのフォーカスされたNodeテストを追加します。
- ファクトリメタデータと設定。
- 認証解決。
- サンドボックスの使用法とパス配置。
- ホスト駆動型のリモート操作またはブリッジプロトコルの動作。
- プロンプト/制御イベント変換。
- セッション再開とターン継続の動作。
- サポートされていない機能のエラー。
- サポートされている場合のスキル具体化。
可能な場合は、モックされたサンドボックスセッションとブリッジ/ランタイム境界を使用します。単体テストでライブプロバイダ資格情報を必要としないでください。
getBootstrap() は コンパイル済み ブリッジアセット (例: dist/bridge/index.mjs) を読み取ります。これは、src に対してテストが実行された時点では存在しないため、これを呼び出すテストは ENOENT にヒットします。ブリッジアセットパスに対して node:fs/promises の readFile をモックします (パターンについてはCodex/OpenCodeハーネステストを参照)。
7. READMEの追加
READMEは短くします。
- パッケージの目的。
- セットアップコマンド。
- 最小限の
HarnessAgentの使用法。 - 必要なサンドボックス機能 (ブリッジバック型ランタイムのポートなど)。
- 注目すべき認証設定。
より広い概念については、メインのハーネスドキュメントへのリンクを貼ります。
8. サンプルの追加
新しいハーネスのための関連サンプルを追加します。
- 必要なAPI/関数サンプルを
examples/ai-functions/src/harness-agentに、インタラクティブサンプルをexamples/harness-e2e-nextに追加します。
9. ドキュメントの追加
content/providers/02-ai-sdk-harnesses/<次の番号>-<name>.mdx にドキュメントを作成します。
以下を含めます。
- セットアップ手順
- 必要なサンドボックス機能
- 認証設定
- ハーネス固有のオプション
- 使用例
- 既知の制限事項
新しいハーネスを公開できる状態になったら、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 でチェンジセットを追加します。真新しいハーネスパッケージの最初のリリースには、major (通常の patch ではなく) を使用して、他のハーネスパッケージと一致させます。
関連するハーネスサンプルをライブサンドボックスに対して 早期に 実行します — 単体テストと type-check だけに依存しないでください。ランタイムAPIの制約 (予期しない設定オプションの拒否、ランタイムが発行する正確なストリーミングイベント名、ゲートウェイベースURL形式など) は、ブリッジが実際にランタイムを駆動した場合にのみ明らかになり、ドキュメント/サンプルがその上に構築される前に発見する方がはるかにコストが低くなります。
チェックリスト
-
packages/harness-<name>にパッケージ構造が作成されている -
package.jsonが正しい依存関係で設定されている - TypeScript設定 (
tsconfig.json、tsconfig.build.json) がセットアップされている - ビルド設定 (
tsdown.config.ts) - テスト設定 (
vitest.node.config.js) - ハーネスアダプタの実装が完了している
- ランタイムの配置が隠しサンドボックスを作成せずに処理されている
- ブリッジバック型の場合、ブリッジアセットがビルド中にコピーされる
- 認証解決が実装されている (必要な場合)
- AI Gatewayリクエストに
User-Agentおよび/またはx-client-appクライアント属性が含まれている - ハーネス基盤、スキル、ブリッジコード、およびシークレットが
sessionWorkDirの外に保持されている - セッション再開とターン継続がテストされている
- 単体テストが作成され、合格している
- README.md が作成されている
-
CHANGELOG.mdが追加されている (パッケージヘッダー、konsistentで必須) - チェンジセットが追加されている (最初のリリースは
major) - サンプルが追加されている
-
content/providers/02-ai-sdk-harnesses/にドキュメントが追加されている - 公開されている場合は、ハーネスアダプタリストが更新されている
- ライブサンドボックスに対して検証されている (単体テスト / type-check だけでなく)
-
pnpm update-referencesが実行されている - パッケージビルドが合格している
- パッケージテストが合格している
- 型チェックが合格している (ルートから
pnpm type-check:full) - 関連サンプルが正常に実行されている
関連ドキュメント
- ハーネス抽象化アーキテクチャ
@ai-sdk/harnessREADME- 同様のランタイム配置を持つ既存のハーネスパッケージ