必須構造
最終レスポンス(status: “completed”)
A2A 上の AdCP レスポンスは必ず以下を満たす必要があります:- タスクのペイロードを含む
DataPart(kind: ‘data’)を少なくとも 1 つ含める - 複数アーティファクトではなく、1 つのアーティファクトに複数パートを入れる
DataPartが複数ある場合は最後のものを正とする- AdCP ペイロードをフレームワーク固有オブジェクトでラップしない(
{ response: {...} }など禁止)
- TextPart (kind: ‘text’): 人間向けサマリー - 推奨(任意)
- DataPart (kind: ‘data’): 構造化された AdCP レスポンスペイロード - 必須
- FilePart (kind: ‘file’): 任意のファイル参照(プレビュー、レポート)
中間レスポンス(working, submitted, input-required)
中間ステータスのレスポンスは、進捗把握のために任意で AdCP 構造化データを含められます。- TextPart はステータス表示のため推奨
- DataPart は任意だが、提供する場合は AdCP スキーマに準拠
- 中間ステータス用スキーマ(
*-async-response-working.json、*-async-response-input-required.jsonなど)は策定中で変わる可能性あり - スキーマ進化を踏まえ、中間データの扱いを緩やかにする選択も可能
status: "completed" または status: "failed")、.artifacts 内に AdCP タスクレスポンスを含む DataPart が必須になります。
フレームワークのラッパー(禁止)
重要: DataPart の内容はフレームワーク固有オブジェクトでラップせず、AdCP レスポンスペイロードを直接含める必要があります。- スキーマ検証が破綻する(クライアントは
productsがルートにあると期待) - 不要なネストが増える
- プロトコル非依存設計に反する(ラッパーがフレームワーク依存)
- クライアントでのデータ抽出が複雑化
クライアントの標準的な扱い
このセクションでは、クライアントが A2A プロトコルレスポンスから AdCP レスポンスを抽出する方法を正確に定義します。クイックリファレンス
| Status | Webhook Type | Data Location | Schema Required? | Returns |
|---|---|---|---|---|
working | TaskStatusUpdateEvent | status.message.parts[] | ✅ Yes (if present) | { status, taskId, message, data? } |
submitted | TaskStatusUpdateEvent | status.message.parts[] | ✅ Yes (if present) | { status, taskId, message, data? } |
input-required | TaskStatusUpdateEvent | status.message.parts[] | ✅ Yes (if present) | { status, taskId, message, data? } |
completed | Task | .artifacts[] only | ✅ Required | { status, taskId, message, data } |
failed | Task | .artifacts[] only | ✅ Required | { status, taskId, message, data } |
- 最終ステータス は
Taskオブジェクトを用い、データは.artifactsに格納 - 中間ステータス は
TaskStatusUpdateEventを用い、status.message.parts[]に任意データ - いずれのステータスもデータがある場合は AdCP スキーマを使用
- 中間ステータスのスキーマは策定中で変わる可能性あり
ルール1: ステータスに応じた処理
Clients MUST branch onstatus field to determine the correct data extraction location:
- 中間ステータス:
TaskStatusUpdateEvent→status.message.parts[]から抽出 - 最終ステータス:
Taskオブジェクト →.artifacts[0].parts[]から抽出
Rule 2: Data Extraction Helpers
Extract data from the appropriate location based on webhook type:ルール3: スキーマ検証
すべての AdCP レスポンスはスキーマを用いますが、検証方法はステータスによって異なります:*-async-response-working.json など)は策定中です。安定するまでは緩やかな扱いにする選択も可能です。
完全な例
Task と TaskStatusUpdateEvent の両方を正しく扱う統合例:Last Data Part Authority パターン
Test Cases
✅ Correct Behavior
❌ Incorrect Behavior (Common Mistakes)
エラーハンドリング
タスクレベルのエラー(部分失敗)
タスクは実行されたが完全には完了しなかった場合。status: "completed" の DataPart に errors 配列を入れます:
- プラットフォーム認可の問題(
PLATFORM_UNAUTHORIZED) - データが部分的にしかない場合
- データの一部でバリデーション問題がある場合
プロトコルレベルのエラー(致命的)
タスクが実行できなかった場合。status: "failed" とメッセージを返します:
status: failed を使う場面:
- 認証失敗(無効/期限切れトークン)
- リクエスト不正(JSON 破損、必須フィールド欠落)
- リソース不在(未知の taskId、期限切れ context)
- システムエラー(DB 不調、内部サービス障害)
ステータスマッピング
AdCP は A2A の TaskState enum をそのまま使用します:| A2A Status | Payload Type | Data Location | AdCP Usage |
|---|---|---|---|
completed | Task | .artifacts | Task finished successfully, data in DataPart, optional errors array |
failed | Task | .artifacts | Fatal error preventing completion, optional error details |
input-required | TaskStatusUpdateEvent | status.message.parts | Need user input/approval, data + text explaining what’s needed |
working | TaskStatusUpdateEvent | status.message.parts | Processing (< 120s), optional progress data |
submitted | TaskStatusUpdateEvent | status.message.parts | Long-running (hours/days), minimal data, use webhooks/polling |
Webhook ペイロード
非同期処理(status: "submitted")では Webhook でも同じアーティファクト構造を返します:
レスポンス内の File Part
クリエイティブ系の操作ではファイル参照を含む場合があります:リトライと冪等性
TaskId による重複排除
A2A のtaskId はリトライ検出に使えます。エージェントは次を行うべきです:
taskIdが完了済みオペレーションと一致する場合(TTL 内)、キャッシュレスポンスを返す- 進行中のオペレーションに対する重複
taskId送信は拒否する
例
Implementation Checklist
When implementing A2A responses for AdCP: Final Responses (status: “completed” or “failed”) - UseTask object:
- Always include status field from TaskState enum
- Use
.artifactsarray with at least one DataPart containing AdCP response payload - Include TextPart with human-readable message (recommended for UX)
- Use single artifact with multiple parts (not multiple artifacts)
- Use last DataPart as authoritative if multiple exist
- Never nest AdCP data in custom wrappers (no
{ response: {...} }objects) - DataPart content MUST match AdCP schemas (validate against
[task]-response.json)
TaskStatusUpdateEvent:
- Use
status.message.parts[]for optional data (not.artifacts) - TextPart is recommended for human-readable status updates
- DataPart is optional but follows AdCP schemas when provided (
[task]-async-response-[status].json) - Interim schemas are work-in-progress - clients may handle more loosely
- Include progress indicators when applicable (percentage, current_step, ETA)
- Use
status: "failed"for protocol errors only (auth, invalid params, system errors) - Use
errorsarray for task failures (platform auth, partial data) withstatus: "completed"
- Include taskId and contextId for tracking
- Follow discriminated union patterns for task responses (check schemas)
- Use correct payload type:
Taskfor final states,TaskStatusUpdateEventfor interim - Support taskId-based deduplication for retry detection
See Also
- A2A Guide - Complete A2A integration guide
- Task Lifecycle - Status handling patterns
- Error Handling - Fatal vs non-fatal errors
- Protocol Comparison - MCP vs A2A differences