Skip to main content
ストーリーボードは、エージェントが conformant として公開されるかを決めるバージョン管理されたバイヤーシミュレーションスイートです。バイヤーエージェントはそのステータスでフィルターします — 過剰主張やストーリーボード失敗は、CI 警告ではなく公開で永続的なシグナルです。このページは「エージェントを構築した」と「npx @adcp/sdk@latest storyboard run を実行できる」の間のチェックリストです。

ランナーが必要とする 3 つのサーフェス

ランナーは、バイヤーが呼ぶのと同じ公開ツール、加えてフィクスチャセットアップ用の 1 つのサンドボックス専用ツールを通じてエージェントを駆動します。3 つのサーフェスが整っていなければなりません: あなたはこれら 3 つのサーフェスを出荷します。ランナーはストーリーボード選択、フィクスチャ順序、レスポンス比較を所有します。

Step 1 — ケイパビリティを正直に宣言

get_adcp_capabilities は、ランナーがどのストーリーボードがあなたに適用されるかを選ぶ方法です。それは 適合性 コントラクトでもあります: あなたは宣言したものに一致するすべてのストーリーボードを通過することを約束しています。 下の例はフルサービスの保証セラー(プロポーザルライフサイクル有効)用です。直接購入の保証セラーは media_buy.supports_proposals: false を設定(または省略)します。放送 TV セラーは sales-broadcast-tv を主張します。クリエイティブのみのエージェントは creative-ad-server または creative-generative 専門分野で creative プロトコルを主張します。シグナルプロバイダーは signals を主張します。パターンは同じ: 実際に実装するもののみを宣言。
  • supported_protocols/compliance/{version}/protocols/ から一致するプロトコルストーリーボードを引き込む。
  • specialisms — オプトイン専門分野ストーリーボードを引き込む(完全な列挙については Compliance Catalog を参照)。
  • account.sandbox: true — サンドボックスセマンティクス(実際の支出なし、本番副作用なし)を尊重することをシグナル。
  • account.require_operator_auth — サンドボックスブートストラップパス(ステップ 2)を決定。
RTB のみを実行するのに sales-guaranteed を主張すると、記録に残るかたちで失敗するストーリーボードに送り込まれます。適合性ステータスは、バイヤーエージェントがセラーをフィルターするのに使う Verified バッジの一部です — 一度過剰主張すると、どこでも包含を失います。

Step 2 — サンドボックスブートストラップパスを選ぶ

ランナーは何かをする前にサンドボックスアカウントを取得しなければなりません。require_operator_auth フラグがパスを選びます: バイヤー宣言アカウント(require_operator_auth: false)。 エージェントは任意の認証されたバイヤーからの sync_accounts を受け入れます。ランナーは sandbox: truesync_accounts を呼びオンデマンドでテストアカウントを鋳造します。ほとんどの新しいセールスエージェントはここから始めます。 アカウント ID 名前空間(require_operator_auth: true)。 アカウントはあなた側の人間または上流プラットフォームによって事前プロビジョニングされなければなりません。ランナーはサンドボックスフィルターで list_accounts を呼び既存のテストアカウントを発見します。認証情報が正確に 1 つのサンドボックスアカウントにバインドされている場合、そのシングルトンを返します。オペレーターに 1 つを要求する方法を伝える短いノートを公開します — 連絡先、期待されるターンアラウンド、受け取る認証情報を含めます。 完全な詳細と例: サンドボックスモード

Step 3 — コンプライアンステストコントローラーを実装

コンプライアンステストコントローラーなしでは、ランナーはバイヤー開始のフロー(観察モード)のみをテストします — スキーマ適合性、auth 拒否、ハッピーパスバイヤー呼び出し。それは初期統合作業と本番パスのサンドボックススモークテストに十分ですが、コントローラーシードまたはコントローラー強制のシナリオがスコープ内のときはいつでも 部分カバレッジ を生成します。適合性 は、コントローラーによって可能になる完全なライフサイクルウォークである 決定的モード を、完全な専門分野カバレッジのラインとして扱います。 実際には、セラーは通常両方を実行します: 最初の実行は「本番バイヤー可視パスはサンドボックストラフィックを許容するか?」に答えます。2 番目は「ランナーは宣言された専門分野のすべてのライフサイクルパスを証明できるか?」に答えます。それらを 1 つのシグナルに折り畳まないでください。ゼロ失敗の部分実行は有用ですが、バイヤーはどのライフサイクルアサーションがグレードされなかったかを正確に知るためスキップリストが必要です。 comply_test_controller は、3 つのファミリーをカバーする scenario パラメーターを持つ単一のサンドボックス専用ツールです: シナリオごとのパラメーターとレスポンス形状については コンプライアンステストコントローラーリファレンス を、各専門分野がどのシナリオを要求するかについては Compliance Catalog を参照。

SDK スキャフォールドの配線

@adcp/sdk(6.x が AdCP 3.0 の本番 GA)は createComplyController を出荷し、ツール登録、パラメーター検証、エラーエンベロープ、再シード冪等性を再実装せずにデータ層をコントローラーに配線できます。
スキャフォールドは TypeScript/JavaScript です。Python、Go、Java のセラーは スキーマ に対して直接ツールを実装します — 下のコントラクト(アダプター、エラーコード、冪等性セマンティクス)は同じように適用されます。他言語の SDK は Choose your SDK で追跡されます。
スキャフォールドがあなたのために扱うもの:
  • ツール登録とスキーマ。 controller.toolDefinition が公開された仕様バージョンと同期のまま。
  • ディスパッチと UNKNOWN_SCENARIO 登録しないシナリオは自動的に UNKNOWN_SCENARIO を返す — スキーマエラーは決してない。
  • パラメーター検証。 無効なパラメーターは、アダプターに到達せずに読める error_detail を伴う INVALID_PARAMS を生成。
  • シード冪等性。 同じ product_id と等価な fixtureseed_product を 2 回呼ぶと previous_state: "existing" を返す。分岐した fixtureINVALID_PARAMS を返す。アダプターは最初のシードでのみ呼ばれる。
  • 型付きエラーエンベロープ。 コントローラーエラーコード表の codeTestControllerError(code, message, currentState?) を throw。一般的なアダプターコードは 'INVALID_TRANSITION' | 'NOT_FOUND' | 'FORBIDDEN' | 'INVALID_PARAMS'。ダイジェストモードの query_upstream_traffic 実装は、RFC 8785/JCS 正準化が非有限数値に遭遇したとき JCS_NON_FINITE_NUMBER も返しうる。
スキャフォールドはステートマシンを 所有しません。遷移ルールはあなたのアダプターに存在するため、コンプライアンステストと本番が 1 つの真実の源泉を共有します — teach-to-test 回避セクション が依存するメカニクス。

サンドボックスゲーティングの 2 層

スキャフォールドは 2 つのゲートをサポートします。同じプロセスからサンドボックスと本番の両トラフィックを提供する任意のデプロイで両方を出荷してください:
  1. 登録ゲート(主要)。 controller.register(server) を環境チェックでラップ。これが comply_test_controller を本番 tools/list から完全に外すものです。それなしでは、本番エンドポイントの漏洩したサンドボックス認証情報がセラー側の状態強制を露出します。
  2. リクエストごとのゲート(多層防御)。 createComplyControllersandboxGate: (input) => boolean を渡す。スキャフォールドはすべてのリクエストでそれを呼び、false を返すとき FORBIDDEN を返す。ツールが登録されているが一部のリクエストが依然本番アカウントを参照しうる共有プロセスデプロイでこれを使う。
sandboxGate は生のツール入力(Record<string, unknown>)を受け取ります。SDK は auth コンテキストをそれに配管しません — あなたが何を検査するかを決めます。典型的なパターンは、参照されたエンティティ ID を params から引き出し、それが自身のデータ層でサンドボックスアカウントに属することを検証することです:
カスタム MCP ラッパー — リクエストごとの auth の AsyncLocalStorage、トランスポートレベルのサンドボックスゲーティング、セッション裏付けストア — については、@adcp/sdk/server から低レベルの handleTestControllerRequesttoMcpResponseTOOL_INPUT_SHAPE を直接合成してください。

Step 4 — ストーリーボードランナーを実行

3 つのサーフェスが整ったら、ランナーが引き継ぎます:
ランナーはケイパビリティを発見し、サンドボックスアカウントを取得し、コントローラー経由でフィクスチャをシードし、各一致するストーリーボードを歩きます。完全な CLI、デバッグフラグ、Addie ワークフローについては エージェントを検証する を参照。

Avoiding the teach-to-test trap

ストーリーボードはフィクスチャ ID をハードコードします — "test-product""campaign_hero_video""acmeoutdoor.example"。それらの文字列を特別扱いするコントローラーは、すべての実際のバイヤーで黙って失敗しながらスイートを通過します。それはまさに適合性が防ごうとしている業界コストです: すべての適合性後の統合失敗がセラーの評判を焼き、バイヤーエージェントの懐疑を膨らませ、プロトコル採用を遅らせます。 SDK スキャフォールドは既に正しい方向を指しています: アダプターは product_idcreative_id などを条件ではなく値として受け取ります。アダプターに product_id === "test-product" のスイッチが含まれていたら、後退しています。 2 つの経験則:
  1. シードシナリオを汎用に実装。 seed_product は任意の product_id を受け入れ、その ID でプロダクトをサンドボックスデータ層に永続化する。アダプターはサンドボックスストアに対する実際の upsert の薄いラッパー。
  2. fixture オブジェクトがコントラクトで、ID はそうでない。 ストーリーボード作者は fixture をテストが必要とする最小の形状に設定する。それを超えたすべて — ディスカバリー、フィルタリング、認可 — は、本番データで実行するのと同じ方法でフィクスチャシードされたデータで実行される、あなたの通常のコードパス。
確認するには: ストーリーボードのフィクスチャ ID をランダム UUID にスワップし再実行します。実行がまだ通過すれば、コントローラーは正しいです。壊れれば、修正するハードコードされた動作があります。

準備チェックリスト

最初の完全なストーリーボードスイープの前に:
  • get_adcp_capabilities が実際に実装するプロトコルと専門分野のみを返す
  • account.sandbox: true が宣言され尊重される — サンドボックスリクエストが実際の支出、本番プラットフォーム呼び出し、永続化された本番状態を生成しない
  • sync_accounts(暗黙)または list_accounts(明示)がステップ 2 に従いサンドボックスリクエストを扱う
  • comply_test_controller が任意の本番エンドポイントの tools/list から欠如している
  • 非サンドボックスアカウントを参照するリクエストが FORBIDDEN で拒否される
  • 主張するストーリーボードが依存するすべてのシードシナリオが、ID 特別扱いなしにフィクスチャを汎用に永続化する
  • すべての force シナリオが本番と同じ状態遷移ルールを使い、無効な遷移で型付きエラーを返す
  • フィクスチャ ID がランダム UUID にスワップされても完全なストーリーボードスイープが通過する

次は