Skip to main content
AdCP はリクエスト間で状態を維持するために識別子とデータフィールドを利用します。これらを理解することは、効果的な統合を行う上で不可欠です。

主要な識別子

AdCP では用途の異なる 2 種類の識別子を使用します:

context_id と task_id

IdentifierPurposeLifespanScope
context_id会話・セッションの継続約 1 時間複数のタスク呼び出しをまたぐ
task_id特定オペレーションの追跡完了まで(数時間〜数日)個別オペレーション
context_id:
  • プロトコル層から付与(A2A は自動、MCP は手動)
  • 会話履歴とセッション継続を提供
  • 複数タスク呼び出し間の状態維持に使用
  • タイムアウト後に失効(一般的に 1 時間)
task_id:
  • 非同期になり得る個別リクエストに固有
  • 会話をまたいで存続
  • オペレーションの進行状況を長期にわたり追跡
  • タスク完了まで保持(複雑なメディアバイでは数日かかることも)
  • 別の会話やセッションから参照可能

使用例

// First call - establishes context and creates task
const result = await call('create_media_buy', {
  brief: "Launch summer campaign"
});

const contextId = result.context_id;  // 会話継続に使用
const taskId = result.task_id;        // このメディアバイを追跡

// 同じ会話内の後続呼び出し - context_id を使用
const update1 = await call('update_media_buy', {
  context_id: contextId,    // Maintains conversation state
  task_id: taskId,          // References the specific media buy
  updates: {...}
});

// 数日後の別会話 - task_id のみで十分
const delivery = await call('get_media_buy_delivery', {
  task_id: taskId          // No context_id - this is a new conversation
});

プロトコルの違い

  • A2A: コンテキストはプロトコルが自動で管理
  • MCP: context_id を手動で管理する必要あり

A2A のコンテキスト(自動)

A2A はセッションをネイティブに扱うため、コンテキスト管理は不要です:
// A2A はコンテキストを自動管理
const task = await a2a.send({ message: {...} });
// contextId is managed by A2A protocol

// Follow-ups automatically use the same context
const followUp = await a2a.send({
  contextId: task.contextId,  // 任意 - A2A が追跡
  message: {...}
});

MCP のコンテキスト(手動)

MCP では状態を維持するために明示的なコンテキスト管理が必要です:
// First call - no context
const result1 = await mcp.call('get_products', {
  brief: "Video ads"
});
const contextId = result1.context_id;  // 保存しておく!

// Follow-up - must include context_id
const result2 = await mcp.call('get_products', {
  context_id: contextId,  // 継続に必須
  brief: "Focus on premium inventory"
});

MCP におけるコンテキスト管理パターン

class MCPSession {
  constructor(mcp) {
    this.mcp = mcp;
    this.contextId = null;
  }

  async call(method, params) {
    const result = await this.mcp.call(method, {
      ...params,
      context_id: this.contextId
    });
    this.contextId = result.context_id;  // 次の呼び出し用に更新
    return result;
  }
}

コンテキストが保持するもの

context_id はプロトコルに関わらず会話状態を保持します:
  • 現在議論中のメディアバイや商品
  • 検索結果と適用済みフィルター
  • 会話履歴とユーザー意図
  • セッション内で示されたユーザーの嗜好
  • ワークフロー状態と一時的な判断
Note: メディアバイのステータスやクリエイティブアセット、パフォーマンスデータなど長期的なタスク状態は context_id ではなく task_id で追跡します。

拡張フィールド (ext)

拡張フィールドはプロトコル互換性を保ちつつ、プラットフォーム固有の機能を実現します。

スキーマパターン

Extensions appear consistently across requests, responses, and domain objects:
{
  "product_id": "ctv_premium",
  "name": "Connected TV Premium Inventory",
  "ext": {
    "gam": {
      "order_id": "1234567890",
      "dashboard_url": "https://..."
    },
    "roku": {
      "content_genres": ["comedy", "drama"]
    }
  }
}
ext オブジェクトの特徴:
  • 常に 任意(必須にしない)
  • 任意の有効な JSON 構造を許容
  • 実装側は未知のフィールドでも必ず保持
  • AdCP スキーマでバリデートしない(実装側での検証は可)

名前空間(重要)

拡張は必ずベンダー/プラットフォームごとの名前空間を用います:
// ✅ Correct - Namespaced
{
  "ext": {
    "gam": { "test_mode": true },
    "roku": { "app_ids": ["123"] }
  }
}

// ❌ Incorrect - Not namespaced
{
  "ext": {
    "test_mode": true,  // Missing namespace!
    "app_ids": ["123"]  // Which platform?
  }
}

アプリケーションコンテキスト (context)

コンテキストは、レスポンスや Webhook でそのまま返される不透明な相関データを提供します。

主な特性

  • エージェントはコンテキストを解析せず、動作に利用しない
  • 呼び出し元の内部トラッキング用途のみに存在
  • レスポンスや Webhook で内容を変えずに返される

Schema Pattern

{
  "tool": "create_media_buy",
  "arguments": {
    "buyer_ref": "nike_q1_campaign_2025",
    "packages": [...],
    "context": {
      "ui_session_id": "sess_abc123",
      "trace_id": "trace_xyz789",
      "internal_campaign_id": "camp_456"
    }
  }
}
レスポンスでも同じコンテキストが返されます:
{
  "status": "input-required",
  "message": "Media buy requires manual approval before activation.",
  "context_id": "ctx_ghi789",
  "context": {
    "ui_session_id": "sess_abc123",
    "trace_id": "trace_xyz789",
    "internal_campaign_id": "camp_456"
  }
}

コンテキストの主な用途

  1. UI/セッショントラッキング - 非同期処理間の状態維持
  2. リクエスト相関 - 分散システムでのリクエスト追跡
  3. 内部 ID - 内部データ構造へのマッピング
  4. 組織コンテキスト - マルチテナントの追跡

使い分けの指針

FieldPurposeAgent Reads?Agent Modifies?
context_idセッション継続YesYes (creates/updates)
task_idオペレーション追跡YesYes (creates)
extプラットフォーム固有設定MAYMAY add response data
context不透明な相関情報NEVERNEVER

ext を使うとき:

  • プラットフォーム側でデータを解釈する必要がある
  • データがオペレーション動作に影響し得る
  • プラットフォーム固有の設定を表現する
  • 複数オペレーションにわたりデータを残す必要がある

context を使うとき:

  • 呼び出し元の内部用途に限定される
  • エージェントの動作に決して影響させない
  • 相関/トラッキングのみの目的である
  • そのままの内容で返してほしい

ベストプラクティス

A2A の場合

  • プロトコルにコンテキスト管理を任せる
  • 必要に応じて contextId で会話を明示的に紐づける
  • セッション管理を信頼する

MCP の場合

  • 呼び出し間で context_id を必ず保持
  • セッションラッパーを実装(上記パターン参照)
  • コンテキストの有効期限(1 時間)に対応
  • 新しいワークフローでは新規コンテキストを開始

拡張フィールドについて

  • 必ずベンダーキー配下で名前空間を分ける
  • 拡張仕様を十分にドキュメント化する
  • 共通パターンは標準化を提案することを検討

アプリケーションコンテキストについて

  • 不透明のままにし、エージェントが解釈する前提で構造化しない
  • 大きなペイロードは避ける(コンテキストは全レスポンスで返される)
  • 相関用途のみに使い、運用データには使わない