はじめに:「キャンペーン作って」の一言で3回のAPI呼び出しが発生する
広告APIは強力ですが、使いこなすのは簡単ではありません。Spotify Ads API v3は30以上のリソースタイプ、ネストされたターゲティング構造、そしてキャンペーン > 広告セット > 広告へと続く多段階のエンティティ階層を持っています。
例えば「コネチカット州のリスナーを対象にオーディオキャンペーンを開始したい」という意図を実行に移すには、開発者はジオターゲットIDの検索、金額単位の変換、Audienceの事前検証、3つのPOSTリクエストを手動で順序立ててオーケストレーションする必要があります。意図(Intent)と実行(Execution)の間の認知的距離は非常に大きいと言えるでしょう。
Spotifyエンジニアリングチームはこのギャップを埋めるために、自然言語インターフェースを採用することを決定しました。ユーザーがプレーンな英語で希望を伝えれば、システムが残りを自動的に処理する仕組みです。その成果物が、Claude Codeプラグインとして公開された spotify-ads-api プラグインです。
この記事では、当該プラグインのアーキテクチャ、主要な技術的判断、そしてLLMベースのエージェント上に開発者ツールを構築する過程で得られた教訓について深く掘り下げます。
参考: このプラグインはGitHubおよびAnthropic Claude Pluginsマーケットプレイスでオープンソース(Apache 2.0)として公開されています。ダウンロードして、Claudeに話しかけるだけで広告キャンペーンを作成できます。

コアアーキテクチャ:Markdownだけで全てが完結する
このプラグインの最も驚くべき点は、コンパイルされたコードが1行も存在しないことです。ビルドステップ、パッケージマネージャー、バンドラー、トランスパイラーは一切ありません。すべてのコンポーネントは .md ファイルで記述されています。
Claude Codeのプラグインシステムは4つのコンポーネントタイプを提供します:
| コンポーネント | 役割 | 実装方法 |
|---|---|---|
| Skills | スラッシュコマンド定義 | 自己完結型Markdownファイル。コマンドの動作、APIエンドポイント、リクエスト形式、出力処理を含む |
| Agents | 自由形式自然言語処理 | request-builderエージェントがユーザーの会話形式リクエストを検出し、API呼び出しシーケンスに分解 |
| Hooks | ツール呼び出し前のインターセプト | PreToolUseフックでOAuthトークンの自動更新とHTTPヘッダー注入 |
| Settings | ユーザー別設定 | gitignoredローカルファイルに資格情報、広告アカウント、環境設定を保存 |
この設計の利点は、すべてのコンポーネントが人間が読め、diff可能で、バージョン管理可能であることです。テスト中に新しいAPIの癖が見つかった場合、修正は大抵Markdownファイルに一文追加するだけで済みます。
なぜMCPではなくCLI + OpenAPI仕様なのか?
Model Context Protocol (MCP) はLLMと外部ツールを接続する事実上の標準になりつつあります。しかしSpotifyチームは複数の理由から、MCPではなくCLIファースト + 生のOpenAPI仕様というアプローチを選択しました。
- APIサーフェスが広すぎる: Spotify Ads APIは数十のエンドポイントとネストされたリクエストスキーマを持ちます。それぞれをMCPツールとして定義すると巨大なツールレジストリが生成され、ユーザーがそのエンドポイントを必要としない場合でも、すべてのインタラクションでかなりのコンテキストウィンドウを消費します。Claude Codeプラグイン方式では、エージェントは必要なときにのみ関連する参照ドキュメントをロードします。
- curlコマンドは透過的でデバッグ可能: プラグインが行うすべてのAPI呼び出しはcurlコマンドとしてユーザーに表示されます。ユーザーは何が送信されているかを正確に確認し、コピーし、修正し、独立して実行できます。この透過性は、すべてのリクエストが実際の予算に影響を与える可能性のある広告システムにおいて、監査可能性(Auditability)とユーザーコントロールを提供します。
- OpenAPI仕様が真実の源(Source of Truth): Spotify Ads APIは約8,600行の包括的なOpenAPI v3仕様を提供します。この仕様をMCPツールスキーマに変換し、APIの進化に合わせてメンテナンスする代わりに、プラグインに生の仕様をそのまま搭載します。エージェントはエンドポイントのパラメータやレスポンス形式を理解する必要があるときに、この仕様を直接読みます。APIが変更された場合、1つのファイルを更新するだけで済みます。
# 例:プラグインが生成する実際のcurlコマンド(ユーザーに表示される)
# ユーザーはこのコマンドをコピーして独立して実行/検証可能
curl -X POST "https://api.spotify.com/v1/ads-api/v3/campaigns" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"ad_account_id": "ACC123",
"name": "Back to School Promo",
"objective": "AUDIO",
"status": "ACTIVE"
}'
OpenAPI Linksをナビゲーショングラフとして活用する
このプロジェクトで特に光った機能はOpenAPI Linksです。OpenAPI 3.x仕様の中でも比較的使われていない機能で、ある操作のレスポンスを別の操作の入力として使用する方法を定義します。
Spotify Ads API仕様はエンティティ階層全体をLinksでエンコードしています:
- キャンペーン作成レスポンス(201) → 広告セット作成へのリンク
- 広告セット作成レスポンス → 広告作成へのリンク + 親キャンペーンへの逆リンク
- 広告レスポンス → 参照するクリエイティブ、画像、ロゴへの横断リンク
人間の開発者にとってこれらの関係は大抵暗黙的ですが、LLMエージェントにとっては明示的に宣言されたLinksが大きな利点をもたらします。$response.body#/id、$request.path.ad_account_id のようなランタイム式は、エージェントにどのフィールドを抽出して次のリクエストに注入すべきかを正確に伝えます。
エージェントが「フルキャンペーン作成」を3つの逐次API呼び出しに分解するとき、これはOpenAPI Linksが定義したのと同じ探索パス(campaign → ad set → ad)を辿っていることになります。広告セットのレスポンスはまたターゲティング検索エンドポイントへリンクしており、エージェントはジオターゲットペイロードを構築する前に /targets/geos を呼び出す必要があることを認識します。

エージェント設計:ドメインエキスパートに変身させる
自然言語エージェント(agents/spotify-ads-request-builder.md)は、LLMをSpotify Ads APIの専門家にするMarkdownファイルです。システムプロンプトには以下のようなドメイン知識が含まれています:
- 値の変換: ドル → マイクロ単位、日付表現 → ISO 8601、プラットフォーム名 → API Enum値
- マルチステップオーケストレーション: 「フルキャンペーン作成」を3つの逐次API呼び出し(キャンペーン→広告セット→広告)に分解し、ステップ間でIDを引き継ぐ
- ジオターゲティング検索: ユーザーが「コネチカットをターゲット」と言った場合、エージェントはジオターゲティング検索エンドポイントを呼び出して地域IDを見つけ、正しい構造で
geo_targetsオブジェクトを構築 - 事前検証(Pre-flight Validation): 広告セット作成前にAudience Estimateエンドポイントを呼び出し、ターゲティングが最小しきい値を満たしているか確認
- 実行制御: ユーザーの
auto_execute設定を尊重し、curlコマンドを表示して確認を取るか、直接実行する
日本の開発現場における適用コンテキスト
このアプローチは、日本のSIer環境や大企業の内部API連携プロジェクトにおいて特に有用性が高いと考えられます。日本の開発現場では:
- 複雑なレガシーAPIのドキュメント化とメンテナンスに多大なコストがかかっています。
- API変更時にSDKやクライアントライブラリを同時に更新する負担があります。
- ビジネスユーザーが直接APIを呼び出すことが難しく、常に開発者が仲介する必要があります。
Markdownベースのプラグインアプローチは、これらの問題に対する実用的な代替案を提示します。OpenAPI仕様を真実の源とし、LLMエージェントがそれを直接読むようにすることで:
- APIドキュメントと実装が分離しません。
- API変更時に仕様ファイル1つを更新するだけで、エージェントが自動的に適応します。
- ビジネスユーザーは自然言語で問い合わせ、エージェントが内部API呼び出しを処理します。
もちろん、日本特有のAPIゲートウェイ、セキュリティポリシー、レガシーシステムとの統合など、追加の考慮事項はあります。しかし、このアーキテクチャの核となる価値である「透過性」と「ドキュメント駆動実行」は、日本の企業におけるAPIガバナンスにもポジティブな示唆を与えるでしょう。

まとめ:このアプローチの限界と次のステップ
この技術の限界または注意点
このプラグインは特定の命題に賭けています:「複雑なAPIのための最良のインターフェースは自然言語であり、詳細なドキュメントで基盤を固め、透過的に実行すること」。しかし、このアプローチがすべてのAPI統合にスケールするかは、まだ未解決の問いです。
- 非常に複雑なワークフロー: 数十のエンドポイントが絡み合う超大規模APIでは、Markdownプロンプトだけですべてのエッジケースを処理するのは難しい可能性があります。
- レイテンシ: エージェントがOpenAPI仕様(8,600行)を必要に応じて参照すると、トークン消費とレイテンシが増加する可能性があります。
- マルチターンコンテキスト: 複数回のAPI呼び出しが必要な長いワークフローで、エージェントがコンテキストを失うリスクがあります。
次のステップとしての学習方向
- Idempotency Keyのサポート: ネットワーク再試行やエージェント再実行時の重複キャンペーン作成を防ぐための冪等性キー導入が計画されています。
- 他のプラットフォームへの展開: Claude以外にも、Codex、Gemini CLIなどのLLMプラットフォームを探求中です。特にGPT-5.5とImages 2.0の画像生成機能をクリエイティブ制作に活用することに注目しています。
- ユーザーフローの観察と最適化: 現在のエージェントロジックは比較的単純な広告フローを基準に記述されています。実際の使用パターンを観察し、エージェントが最も多くの説明を要求するポイント(Decomposition Bottleneck)を特定し、システムプロンプトを事前最適化する計画です。
合わせて読みたい記事
このプラグインはフレームワークもランタイムも、curl、jq、python3 以外の依存関係もありません。真実の源はOpenAPI仕様であり、ビジネスロジックは散文(Prose)です。複雑なAPIを自然言語で操るこの実験が、今後の開発者ツールにどのような影響を与えるのか、注目していきたいと思います。
本記事はSpotify Engineeringブログの投稿を基に再構成したものです。