0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【要約】SpotifyのPortalでClaude Codeのトークン使用量を90%削減した話

0
Posted at

AIコーディングエージェント(Claude Codeなど)の導入が進む中、懸念されるのがトークンコストの膨張です。Spotifyのエンジニアが、自社製のエージェントプラットフォーム「Portal by Spotify」の機能を活用し、Claude Codeのトークン使用量を最大90%削減したアーキテクチャと手法を公開しました。

その核心は、「すべての処理を高価な最先端モデルに任せるのではなく、単純作業は安価なモデルにルーティングする」というモデルルーティングの実現にあります。

🎯 抱えていた課題:AIのコストを食うのは「推論」ではなく「I/O」

AIコーディングエージェントが行う作業の大部分は、実は高度な推論ではなく、以下のようなI/O中心の単純作業です。

  • 1つのメソッドについて知るために、5つのファイルを丸ごと読み込ませる
  • 隣にある20個のテストファイルと全く同じパターンのテストファイルを生成する
  • 会議後のドキュメントを更新する

これらの作業で数千トークンが消費されますが、推論価値はほぼゼロです。座席ライセンス料よりも、こうした「不必要に高価なモデルに渡されるトークン」の方がコストを圧迫しています。

💡 解決策:Portalの「AiKA Modes」によるモデルルーティング

この問題を解決するために導入されたのが、SpotifyのPortalプラットフォームにある「AiKA Modes」という機能です。

Mode(モード)とは、宣言的に定義されたエージェントのことです(AWS Lambdaのエージェント版のようなもの)。指示(Instructions)、使用するモデル、温度(Temperature)、MCPツールを定義するだけで、インフラ管理やAPIキーの管理、常時起動サーバーなしでエフェメラルなランタイムで実行できます。

今回は、以下の2つのModeを作成し、安価なワーカーモデル(例: gemini-2.5-flash)に処理を委譲しました。

Mode 1: bulk-reader(一括ファイル読み込み)

Claudeが複数の巨大なファイルを読む代わりに、質問に対する構造化された簡潔な回答のみを返すモード。

name: bulk-reader
description: Bulk file reader for code analysis - delegates I/O from Claude Code
instructions: |
  You are a precise code analyst. Read the provided files and answer the question concisely. 
  Output structured bullets only. No greetings, no prose, no preambles. 
  Lead every bullet with the exact name, type, or line number. Use nested bullets for details. 
  Skip anything the caller did not ask for.
visibility: public
model: gemini-2.5-flash
resourceLimits:
  temperature: 0.2
tags:
  - coding
  - delegation

Mode 2: code-writer(定型コード生成)

テスト、設定ファイルのスケルトン、型スタブなど、既存のパターンから出力が予測可能な作業を担当するモード。

name: code-writer
description: Boilerplate code generator - delegates output-heavy work from Claude Code
instructions: |
  You generate code files based on a spec and reference files. 
  Match the existing patterns, conventions, naming, and style exactly. 
  Output only the code — no explanations, no markdown fences unless asked. 
  If the spec is ambiguous, make reasonable choices that match the reference code's patterns.
visibility: public
model: gemini-2.5-flash
resourceLimits:
  temperature: 0.2
tags:
  - coding
  - delegation

ポイント: 「コードのみを出力する(Output only the code)」という指示が重要です。これがないと、モデルがMarkdownのフェンスや説明文で包んで出力してしまい、それをClaudeが再度パースする必要が出てトークンが無駄になります。

⚙️ 実装アーキテクチャ:Claude Codeプラグイン shunt

当初は CLAUDE.md にルーティングルールを記述してClaudeに自律的に判断させていましたが、「ルールが無視される」「プロジェクトごとにコピペが必要」という課題がありました。

そこで、shunt というClaude Codeプラグインを作成し、以下の3層アーキテクチャで強制的かつスムーズに委譲を実現しました。

Layer 1: Hooks(フック)

Claude Codeのツール呼び出し前に発火するPreToolUseフックを使用します。

  • check-file-size: Read 呼び出しごとに発火。ファイルが設定された行数(デフォルト: 350行)を超える場合、読み込みをブロックし、「代わりに /bulk-reader スキルを使うように」とClaudeに指示します。
  • check-bash-read: 巨大なファイルに対する cat, head, tail などをキャッチします(cat file | grep のようなパイプ処理は対象的な読み込みとみなし通過させます)。

しきい値は環境変数 SHUNT_MIN_LINES で設定可能です。

// .claude/settings.json
{
  "env": {
    "SHUNT_MIN_LINES": "500"
  }
}

Layer 2: Scripts(スクリプト)

Portal CLIの呼び出しをラップする2つのBashスクリプトを用意し、Claudeは名前付き引数でこれを呼び出します。

  • bulk-read: ファイルをXMLタグで囲み、質問とともに bulk-reader モードに送信します。
  • code-write: 仕様(spec)と参考ファイル(reference)を code-writer モードに送信し、出力からMarkdownフェンスを削除して直接ディスクに書き込みます。Claudeはこの生成されたコードを一切「見ない」ため、出力トークンが完全に節約されます。
# bulk-read の使用例
bulk-read --question "What does this service do?" --paths src/Service.java src/Handler.java

# code-write の使用例
code-write --spec "Write tests for UserService" --reference tests/OrderTest.java --target tests/UserTest.java

Layer 3: Skills(スキル)

Claudeに「いつ」「どのように」スクリプトを呼び出すかを教えるMarkdownファイルです。フックが読み込みをブロックした際、ブロックメッセージが /bulk-reader スキルを参照し、正確な呼び出し構文をClaudeに提示します。

📊 成果とベンチマーク

Javaモノレポでの4つのシナリオで検証した結果、ファイルを直接読み込む場合に比べて、bulk-reader の要約を介すことでトークン使用量が平均 90% 削減されました。

code-write シナリオでは、従来はClaudeが「参考ファイルの読み込み」と「高コストな出力トークンの生成」の両方を行っていましたが、shunt を介すことでコードが直接ディスクに書き込まれ、Claudeのコンテキストに一切入らなくなったため、さらに大きなコスト削減が実現しています。

⚠️ 機能しないこと(限界とトレードオフ)

このアプローチには明確な限界もあります。

  1. 編集(Editing)の委譲は不可
    ワーカーモデルの要約には信頼性の高い行番号が含まれません。分析に基づいてコードを編集する必要がある場合、Claudeは依然として特定のセクションを直接読み込む必要があります(フックはオフセット/制限付きの「対象を絞った読み込み」を許可するように設計されています)。
  2. 推論(Reasoning)の委譲は不可
    テストにおいて、安価なワーカーモデルは表面的なパターンは見つけられても、微妙なスレッドセーフティのバグを見逃しました。デバッグ、アーキテクチャの決定、安全上重要なコードは、明示的にClaude(高価なモデル)にルーティングされます。
  3. レイテンシの増加
    委譲のたびに「Claude Code → Portalバックエンド → ワーカーモデル → 戻り」というネットワーク往復が発生します。応答には通常10〜30秒かかり、Portalは1回の呼び出しを30秒で制限しています。小さなファイルでこれを行うと、委譲のオーバーヘッドが節約効果を上回ってしまうため、行数のしきい値設定が重要になります。

🚀 まとめ:トークン節約は単なる始まりに過ぎない

このプラグイン自体はClaude Code用のアーティファクトですが、その根底にある「AiKA modesによるモデルルーティング」というアイデアが真に強力です。

  • 再利用可能(Reusable): 同じ bulk-readercode-writer を、Portal CLIを呼び出せるあらゆるプロジェクトやツールで横断的に使用できる。
  • 共有可能(Shareable): 両モードはAiKAで公開されており、誰でも自作せずにすぐに利用できる。
  • 合成可能(Composable): ドキュメント作成用の doc-writer、コードレビュー要約用の reviewer、i18n用の translator など、数クリックで新たなモードを追加できる。
  • ルーティングとワーカーのデカップリング: プラグインは「いつ(when)」委譲するかを決定し、Modeは「どのように(how)」応答するかを決定する。ワーカーモデルを切り替えたり、システムプロンプトを変更しても、プラグイン側の変更は不要。

モデルルーティングを「システムエンジニアリングの課題」から「単なる設定(Configuration)の課題」へと引き下げた点に、最大の価値があります。


本記事は Spotify Engineering Blog の「Portal by Spotify cut my Claude Code token usage by 90%」を元に構成しています。 https://engineering.atspotify.com/2026/9/portal-by-spotify-cut-my-claude-code-token-usage-by-90

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?