Codex / Claude Codeをチームで安全に使う|Azure APIM + AI Foundryでレート制限(トークン上限)を設計する

Azure

「チームでCodexやClaude Codeを使い始めたら、ある日突然AIが応答しなくなった。調べたら、誰か1人が巨大なコードベースをまるごと投げていて、共有しているAzureのAIリソースが上限に張り付いていた——」。こんな“事故”は、AIコーディングエージェントをチーム運用し始めた組織で必ず起きる問題です。

チーム全員でAzure経由のCodex/Claude Codeを共有してるんだけど、1人が使いすぎると全員巻き添えで止まるのが怖い…どう制御すればいいの?

この記事では、Codex / Claude Code といったAIコーディングエージェントを、チームで安全に共有運用するためのレート制限(トークン上限制御)を、Azure API Management(APIM)+ Azure AI Foundryを使ってどう設計するかを解説します。単なる機能紹介ではなく、「1人の暴走で全員が止まる事故を、どうやって物理的に防ぐか」という運用設計が主役です。

APIMもFoundryも触ったことがない、という方でも読めるように、TPM・サブスクリプションキー・ポリシーといった用語は初出時に一言添えます。読み終わるころには、「共有AIリソースを、キー単位でトークン上限まで割り当てる設計」を自分の言葉で説明できるようになっているはずです。

※本記事のコスト数値は、あくまで特定モデル単価・為替を仮定した「例」です。モデル単価は頻繁に変わりますし、実際の消費量は使い方で大きく変動します。数字そのものより「考え方(算出ロジック)」を持ち帰っていただくのがゴールです。

まず結論:見える化だけでは暴走は止まらない

本題に入る前に、この記事で一番伝えたい結論を先に置きます。それは、「個別キーを配って“誰が使ったか”を見える化する」だけでは、暴走そのものは止められないということです。

チームでAIを共有する話になると、多くの人がまず「利用者ごとにAPIキーを分けよう」と考えます。それ自体は正しいのですが、キーを分けても、それは「後から犯人がわかる」だけです。1人が大量リクエストを投げてリソースがダウンした瞬間、他の全員の開発が止まる——その事故そのものは、見える化では1ミリも防げません。

必要なのは、リクエストが共有リソースに届く「手前」で、キーごとに流量を物理的に絞る“遮断弁”です。その遮断弁を担うのが、今回の主役Azure API Management(APIM)です。まずはなぜそれが必要なのか、「共有地の悲劇」という切り口から見ていきます。

なぜレート制限が必要か(共有地の悲劇)

まず前提を整理します。チームでCodex / Claude Codeを使うとき、多くの場合こういう構成になります。

  • Azure上に1つの共有Foundryデプロイメント(=モデルを載せた実体。Codex用のモデルをデプロイした箱)を用意する
  • チームの10人が、その1つのデプロイメントを共有して使う

ここで鍵になるのが TPM(Tokens Per Minute=1分あたりに処理できるトークン数) という上限です。トークンとは、AIが文章やコードを処理するときの最小単位(ざっくり「単語のかけら」)のこと。Foundryのデプロイメントには、「1分間にこれ以上のトークンは受け付けない」という上限(例:5,000,000 TPM)が設定されています。この上限はデプロイメント全体で共有される1つの蛇口です。

ここで例え話です。5,000,000 TPMという共有の蛇口を、10人でシェアしている水道だと思ってください。全員が節度を持って使えば問題ありません。ところが——

  • 1人が「巨大なリポジトリをまるごと文脈に入れて」大量のリクエストを投げる
  • その1人だけで共有の5,000,000 TPMを食い尽くす
  • Foundryが上限を超過して OVERLOAD(過負荷) になり、リクエストを弾き始める
  • 結果、暴走していない残り9人まで全員、AIが応答しなくなる

これが「共有地の悲劇」です。共有資源を、各自が自分の都合で好きなだけ使うと、資源そのものが枯渇して全員が損をする——経済学で有名なこの現象が、AIリソースの共有でそっくりそのまま起きます。

共有Foundryリソース(5,000,000 TPM)を10人で共有し、1人の暴走でOVERLOADして全員が止まる「共有地の悲劇」を表した図解
1人の暴走が、残り9人の開発を止める(共有地の悲劇)。個別キーの発行だけでは暴走は止められない。

繰り返しますが、ここで個別キーを発行しても暴走は止まりません。キーの分離は「誰が蛇口を開けっぱなしにしたか」を後から特定できるようにするだけで、蛇口そのものを絞る力はないからです。共有資源を守るには、各キーが引ける水量の“上限そのもの”を物理的に設ける遮断弁が要る。ここがこの記事の出発点です。

二段構えの制御アプローチ(即時ブレーキ+コスト打ち止め)

では具体的にどう制御するか。設計としては目的の異なる2つの制御を「二段構え」で用意します。この2つは似ているようで役割がまったく違うので、まず表で整理します。

制御分単位レート制限(Token Limit)月次クォータ(Quota / Alert)
役割暴走の即時ブレーキコスト打ち止め・アラート
目的共有TPMの保護(システムダウンの防止予算超過の防止(コスト統制)
挙動Foundryへリクエストが届くに、リアルタイムで即時遮断ログの累積値を監視し、しきい値で警告
守るもの可用性(全員が止まらないこと)お財布(月末の請求額)
二段構えの制御アプローチ。左が分単位レート制限(暴走の即時ブレーキ)、右が月次クォータ(コスト打ち止め・アラート)
二段構えの制御。まずはシステム崩壊を防ぐ「分単位レート制限」の導入を最優先とする。

① 分単位レート制限(Token Limit)=即時ブレーキ

こちらが今回の主役です。「1分あたりこのキーで使えるトークンはここまで」という上限を設け、それを超えるリクエストはFoundryに届く前の段階でその場で弾きます。前述の“遮断弁”がまさにこれです。1人が暴走しても、その人のキーの分だけがブロックされるので、共有TPMは守られ、他のメンバーは平常どおり使えます。

② 月次クォータ(Quota / Alert)=コストの打ち止め

もう一方はお金の話です。1分単位のブレーキとは別に、「今月このキーは累計どれだけ使ったか」を追跡し、予算のしきい値に近づいたらアラートを飛ばす(あるいは打ち止める)仕組みです。Azureでは、AI gateway(APIMのAI向けゲートウェイ機能)が出力するトークン消費ログを Log Analytics で集計し、累積値がしきい値を超えたら警告する、という形で実現します。

「分単位=システムを守る即時ブレーキ」「月次=お財布を守る集計アラート」。役割が別物、と覚えると混乱しないよ!

優先順位は明確です。まず導入すべきは①の分単位レート制限。なぜなら、コストの超過はお金で解決できる(後から精算できる)のに対し、システムダウンは「今この瞬間、全員が仕事できない」という取り返しのつかない被害だからです。まず崩壊を止める遮断弁を入れ、コスト統制はその上に乗せる。この順番が鉄則です。

遮断弁の正体:APIMの「llm-token-limit」ポリシー

では①の遮断弁は、技術的に何で実装するのか。ここで登場するのが、APIMの「ポリシー」という仕組みです。ポリシーとは、APIMを通るリクエストに対して「こういう条件なら通す/弾く/書き換える」といったルールを差し込む機能のこと。いわばAPIMという受付ゲートに貼るルールのシールです。

そのポリシーの中に、llm-token-limit(旧名 azure-openai-token-limit)というものがあります。これはまさに「トークン量を見てレート制限をかける」専用のポリシーで、しかもサブスクリプションキー単位でTPM上限を割り当てられるのが最大のポイントです。

用語を1つ補足します。APIMのサブスクリプションキーとは、APIMが「この利用者は誰か」を識別するために発行する鍵です。今回はこれを利用者ごと(=Codex/Claude Codeを使う開発者ごと)に1つずつ発行します。つまり、「キー=利用者」「そのキーごとにTPM上限を設定」という構図になり、キー単位の遮断弁が完成します。

イメージとしては、APIMのポリシーはこんな雰囲気です(設定値は後述の算出ロジックで決めます)。

<!-- APIMのポリシー定義(inboundセクションのイメージ) -->
<inbound>
  <base />
  <!-- サブスクリプションキー単位で、1分あたりのトークン上限を設定 -->
  <llm-token-limit
      counter-key="@(context.Subscription.Id)"   <!-- キーごとにカウント -->
      tokens-per-minute="400000"                  <!-- キー単位のTPM上限 -->
      estimate-prompt-tokens="true"               <!-- 入力トークンを事前見積もり -->
      remaining-tokens-header-name="x-remaining-tokens" />
</inbound>

要点だけ噛み砕きます。

  • counter-key="@(context.Subscription.Id)"「サブスクリプションキーごとに」トークン数をカウントする指定。これで「1人の暴走を、その1人のキーだけに閉じ込める」ことができます。
  • tokens-per-minute="400000"そのキーの1分あたりトークン上限。この400,000という数字の出し方が、次章のメインテーマです。
  • estimate-prompt-tokens="true" … リクエストがFoundryに届く前に入力トークン量を見積もり、上限超過なら即座に弾く(=リアルタイム遮断)ための設定。

細かい属性名やバージョン差はAzure公式ドキュメントで変わり得るので、実装時は必ず最新の公式リファレンスを確認してください。ここで押さえたいのは、「APIMには、キー単位でTPMを絞る専用ポリシーがちゃんと用意されている」という事実です。

キー単位TPMの算出ロジック(設計の肝)

さて、ここが設計で一番大事なところです。「1キーあたり何TPMに設定すればいいのか」。適当に決めると、大きすぎれば遮断弁の意味がなくなり、小さすぎれば全員がすぐ制限に引っかかって使い物になりません。答えはシンプルな1本の式で出せます。

キー単位のTPM上限 = Foundryデプロイメント上限(共有資源) ÷ 利用者数(個別キー) × 安全率(バッファ)

先ほどの例(共有上限5,000,000 TPM/10人)に、安全率0.8を掛けて計算すると、こうなります。

要素意味
Foundryデプロイメント上限5,000,000 TPM共有資源。全員で分け合う蛇口の総量
÷ 利用者数÷ 10人発行する個別キーの数
× 安全率(バッファ)× 0.8同時利用に備えた余裕
= キー単位のTPM上限= 400,000 TPM / キー各開発者に割り当てる分単位上限
キー単位TPMの算出ロジック。5,000,000 TPM ÷ 10人 × 0.8(安全率)= 400,000 TPM/キー
キー単位TPMの算出ロジック:デプロイメント上限 ÷ 利用者数 × 安全率0.8。

なぜ安全率0.8を掛けるのか

単純に「5,000,000 ÷ 10 = 500,000」でよさそうに見えますが、あえて0.8を掛けて余裕(バッファ)を持たせます。理由は、「全員が同時に上限ギリギリまで使っても、共有資源の総量を超えないようにするため」です。

もし1キー500,000 TPMきっちりに設定すると、10人全員が同時に上限まで使った瞬間、合計はちょうど5,000,000 TPMに達します。実運用ではトークン数の見積もり誤差や計測のタイミングずれがあるため、この“ギリギリ”は危険です。0.8を掛けておけば、全員が上限まで使っても合計は 400,000 × 10 = 4,000,000 TPM に収まり、共有上限の5,000,000 TPMに対して1,000,000 TPM分の安全マージンが残ります。この余裕が、システムを守る保険になります。

実務上のうれしい点として、デプロイメントのTPMはテナント(契約単位)ごとに決まった固定値なので、別のテナントや環境に展開するときも、この「上限 ÷ 人数 × 0.8」という基本ロジックはそのまま流用できます。上限値と人数を差し替えるだけで、新しい環境のキー単位上限がすぐ算出できる、というのがこの式の強みです。

コスト概算の前提(入出力比と実効単価)

ここからはお金の話(=二段構えの②)です。「じゃあ結局いくらかかるの?」を見積もるために、まず実効単価という考え方を用意します。ここでも数字はすべて仮定の例である点に注意してください。

Step 1:モデル単価は「入力」と「出力」で違う

生成AIの料金は、入力トークン(Input=AIに渡す文章・コード)出力トークン(Output=AIが生成した結果)で単価が別々です。しかも出力のほうが圧倒的に高いのが普通です。ここでは仮に、以下の単価(gpt-5.5相当と仮定)で考えます。

種別単価(仮定)ひとこと
入力(Input)$5.00 / 1M トークンAIに渡すコード・文脈
出力(Output)$30.00 / 1M トークン入力の6倍高額

Step 2:コーディング支援の入出力比を仮定する

次に、Codex / Claude Code の使い方の特徴を考えます。コーディング支援は、「大量のコード文脈(入力)を渡して、修正箇所(出力)を得る」という使い方が中心です。つまり入力がすごく多くて、出力は相対的に少ない。そこで、入出力比を「9 : 1」(入力90%・出力10%)と仮定します。

Step 3:混合した「実効単価」を出す

入力と出力を9:1で混ぜたときの、1Mトークンあたりの平均単価(=実効単価)を計算します。

実効単価 = (0.9 × $5.00) + (0.1 × $30.00)
        = $4.50 + $3.00
        = $7.50 / 1M トークン
コスト概算の前提。Step1モデル単価、Step2入出力比9:1、Step3混合実効単価$7.50/1Mトークンの算出
入出力比を9:1と仮定した混合実効単価:(0.9×$5)+(0.1×$30)=$7.50/1Mトークン(あくまで仮定の例)。

この実効単価 $7.50 / 1Mトークンと、為替約 ¥160 / $を、以降のコスト試算のベースにします。もう一度念押しですが、モデル単価も為替も変動します。ここでの目的は「入出力比を仮定して実効単価に落とし込む、という見積もりの型」を身につけることです。

20日間のコストシミュレーション(10名利用時)

実効単価$7.50/1Mをベースに、10名のチームが20営業日使ったときのコストを、使い方の濃さ別に3パターンで試算します(すべて仮定の概算です)。

プロファイル1人1日の消費使い方のイメージ10名20日の概算
ライト(Light)50万トークンたまに補助的に使う$75(約¥1.2万)
標準(Standard)150万トークン日常的に開発で使う$225(約¥3.6万)
ヘビー(Heavy)500万トークン常時・巨大な文脈で使い倒す$750(約¥12万)
20日間のコストシミュレーション(10名利用時)。ライト約$75、標準約$225、ヘビー約$750
20日間のコスト試算(10名・実効単価$7.50/1Mベース)。最大の変数は「実際の消費量」なので導入初期の実測が必須。

こうして並べると、使い方の濃さ(=消費トークン量)で、コストが一桁変わることがよく分かります。ライトとヘビーで10倍の開きです。ここで注意したいのは、コストを左右する最大の変数は「実際にどれだけトークンを消費するか」であり、それは導入前には正確に読めないという点です。

よく「1日1万トークンくらいでしょ」と見積もられがちですが、1万トークンはAIと1〜2往復もすれば消える“下限の床”にすぎません。コーディングでコードベースを文脈に入れれば、あっという間に何十万トークンに跳ね上がります。だからこそ、導入初期は必ず実測することが欠かせません。前章の月次クォータ(②)でトークン消費ログを取り、最初の数週間で「自分たちのチームはどのプロファイルなのか」を掴んでから予算を確定させる——これが現実的な進め方です。

「机上の見積もり」より「初期の実測」。まず遮断弁で安全を確保して、実データを取りながら予算を固めていくのが安全だよ。

全体像:この設計を1枚に

ここまでの設計を、リクエストの流れとして1枚にまとめると、こうなります。

  各開発者のCodex / Claude Code
        │  それぞれ「自分専用のサブスクリプションキー」で接続
        ▼
 ┌─────────────────────────────────────────────┐
 │        Azure API Management(APIM)          │
 │                                              │
 │  【llm-token-limit ポリシー】=遮断弁         │
 │   ・キー単位でTPMをカウント                    │
 │   ・上限(例:400,000 TPM/キー)超過は即遮断 ①    │
 │   ・消費トークンをログ出力 → 月次クォータ ②     │
 └───────────────┬──────────────────────────────┘
                 ▼  上限内のリクエストだけ通過
        Azure AI Foundry(共有デプロイメント)
             上限 5,000,000 TPM を全員で共有
  • 各開発者は自分専用のサブスクリプションキーでAPIM経由でアクセスする(=キー=利用者)。
  • APIMのllm-token-limitポリシーが、キー単位でTPMを監視し、上限超過をFoundryに届く前に遮断(①即時ブレーキ)
  • 同時に消費トークンをログに残し、Log Analyticsで累積を監視してコストを打ち止め(②月次クォータ)
  • 上限内のリクエストだけがFoundryの共有デプロイメントに流れるので、1人が暴走しても他の9人は止まらない

まとめ

Codex / Claude Code をチームで安全に共有運用するためのレート制限設計を、要点で振り返ります。

  • 問題は「共有地の悲劇」:共有Foundryを10人で使うと、1人の暴走でTPM上限を超過し、全員が止まる。個別キーの見える化だけでは暴走は止まらない。
  • 解決は二段構え:①分単位レート制限(即時ブレーキ=システム保護)を最優先で入れ、②月次クォータ(コスト打ち止め)を上に乗せる。
  • 遮断弁はAPIMのllm-token-limitポリシー:サブスクリプションキー単位でTPM上限を割り当て、Foundryに届く前に超過を遮断する。
  • キー単位TPMの式共有上限 ÷ 利用者数 × 安全率0.8(例:5,000,000 ÷ 10 × 0.8 = 400,000 TPM/キー)。0.8は同時利用に備える保険。
  • コストは実効単価で見積もる:入出力9:1と仮定した実効単価(例:$7.50/1M)で試算。ただし最大の変数は実際の消費量なので、導入初期の実測が必須。

ポイントは、「見える化(キー分離)」と「制御(遮断弁)」は別物だということ。チームでAIコーディングエージェントを導入するなら、まずAPIMで物理的な遮断弁を用意する。これが、共有地の悲劇から全員を守る設計の土台です。

あわせて読みたい

タイトルとURLをコピーしました