私のエージェント・オーケストレーターは、タスクごとに100万〜200万のOpusトークンを消費していました。

コストが爆発した理由

このオーケストレーターはClaude Code向けに構築され、サブエージェントの階層構造を使用していました。各サブエージェントは親の設定を継承し、独自のプロンプトを実行し、レビュアーが結果を「クリーン」と宣言するまで、その結果をループにフィードバックしていました。ツールはタスクを完了させましたが、そのコストは天文学的なものでした。

3つの隠れた「税金」がトークン数を増幅させていました:

  • モデル税 – サブエージェントがモデルを指定していなかったため、最も高価なティアであるOpusがデフォルトで使用されていました。より安価なモデル(HaikuやSonnet)で十分だった些細な操作も、Opusの料金で請求されていました。
  • キャッシュ税 – プロンプトキャッシュは、バイト単位で完全に一致する場合にのみ再利用されます。各サブエージェントがカスタム指示を追加していたため、呼び出しのたびにコールドキャッシュの書き込みが発生していました。親のキャッシュを再利用できず、共有キャッシュが通常提供する節約効果が台無しになっていました。
  • ループ税 – 「クリーンになるまでループする」というルールにより、レビュアーが少しでも欠陥を見つける限り、プロセスが継続されていました。明確な上限がなかったため、ループはモデルが停止するまで走り続けました。

これらの乗数が組み合わさることで、わずか数行のコードがトークンの雪崩へと変わりました。

プロンプト内の予算ルールが失敗した理由

当初の設計では、システムプロンプトに予算ルールを直接埋め込むことで支出を抑制しようとしていました。理論上は、モデルに「Xトークン以内に収めてください」と伝えることで使用量を制限できるはずでした。しかし実際には、プロンプトベースのルールは単なる「好み」に過ぎません。セッションが長くなると、モデルはコンテキストを圧縮するため、それらの指示を落としたり、完全に無視したりすることがあります。その結果、モデルはルールが最初から存在しなかったかのように振る舞いました。

制御をプロンプトからコードへ移行する

再設計では、予算ロジックをプロンプトから排除し、モデルが上書きできない決定論的なフックシステムへと移行しました。

  1. 明示的なモデル選択 – すべてのサブエージェントのディスパッチにおいて、具体的なモデルの選択(Haiku、Sonnet、またはOpus)が必須となりました。暗黙的な継承を廃止したことで、安価なタスクは安価なまま維持されます。
  2. PreToolUseフックによるハードガード – ツールが実行される前に、フックが以下を確認します:
    • セッション内ですでに実行されたディスパッチの回数。
    • 選択されたモデルが最低ティアを満たしているか(誤ってOpusを使用するのを防ぐため)。
    • ループの最大回数(これを超えるとプロセスが中断されます)。

ガードに抵触した場合、コードがサブエージェントを中断させます。言語モデルが議論して無理やり実行させる術はありません。

開発者にとっての意味

支出制限、セキュリティポリシー、または破壊的なコマンドの制限を課すシステムは、それらの制約を「会話によるガイダンス」ではなく「コード」として扱うべきです。プロンプトは上書きされたり、無視されたり、モデルの内部圧縮の中で失われたりする可能性があります。一方で、コードは決定論的に実行され、監査も可能です。