Documentation Index
Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
Use this file to discover all available pages before exploring further.
AdCP はリクエスト間で状態を維持するために識別子とデータフィールドを利用します。これらを理解することは、効果的な統合を行う上で不可欠です。
主要な識別子
AdCP では用途の異なる 2 種類の識別子を使用します:
context_id と task_id
| Identifier | Purpose | Lifespan | Scope |
|---|
| 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;
}
}
MCP エージェント側: セッション ID フォールバック
多くの MCP クライアント(ChatGPT、Claude など)は context_id を渡しません。エージェントはトランスポートのセッション ID をフォールバックとして使用することで、自動的なセッション永続化を実現できます:
server.tool('get_products', schema, async (args, extra) => {
// 明示的な context_id があればそれを使用し、なければ MCP sessionId にフォールバック
const contextId = args.context_id ?? extra?.sessionId;
const products = await generateProducts(args.brief, contextId);
await productStore.save(contextId, products);
return products;
});
これにより、シンプルなクライアントでも自動セッション永続化を利用しながら、再開可能なセッションを必要とする高度なバイヤーには明示的な制御を残せます。実装例は Snap AdCP Agent を参照してください。
コンテキストが保持するもの
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": {
"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"
}
}
コンテキストの主な用途
- UI/セッショントラッキング - 非同期処理間の状態維持
- リクエスト相関 - 分散システムでのリクエスト追跡
- 内部 ID - 内部データ構造へのマッピング
- 組織コンテキスト - マルチテナントの追跡
使い分けの指針
| Field | Purpose | Agent Reads? | Agent Modifies? |
|---|
context_id | セッション継続 | Yes | Yes (creates/updates) |
task_id | オペレーション追跡 | Yes | Yes (creates) |
ext | プラットフォーム固有設定 | MAY | MAY add response data |
context | 不透明な相関情報 | NEVER | NEVER |
ext を使うとき:
- プラットフォーム側でデータを解釈する必要があります
- データがオペレーション動作に影響し得ます
- プラットフォーム固有の設定を表現します
- 複数オペレーションにわたりデータを残す必要があります
context を使うとき:
- 呼び出し元の内部用途に限定されます
- エージェントの動作に決して影響させない
- 相関/トラッキングのみの目的です
- そのままの内容で返してほしい
ベストプラクティス
A2A の場合
- プロトコルにコンテキスト管理を任せる
- 必要に応じて contextId で会話を明示的に紐づける
- セッション管理を信頼します
MCP の場合
- 呼び出し間で context_id を必ず保持
- セッションラッパーを実装(上記パターン参照)
- コンテキストの有効期限(1 時間)に対応
- 新しいワークフローでは新規コンテキストを開始
- Agents:
context_id が提供されない場合はトランスポートのセッション ID をフォールバックとして使用(セッション ID フォールバック参照)
拡張フィールドについて
- 必ずベンダーキー配下で名前空間を分ける
- 拡張仕様を十分にドキュメント化します
- 共通パターンは標準化を提案することを検討
アプリケーションコンテキストについて
- 不透明のままにし、エージェントが解釈する前提で構造化しません
- 大きなペイロードは避ける(コンテキストは全レスポンスで返されます)
- 相関用途のみに使い、運用データには使わない