事例 01 · Enterprise AI · 製品開発
企業向け AI アプリケーション基盤
モデル呼び出しを一回ずつ、きちんと数える。失敗したタスクは、失敗したところだけやり直す。基盤はチームで開発している。ここに書くのは、私が担当した部分。
仕事一覧へ概要
一分で読む
問題
利用枠のチェック、使用量の計算、失敗時の処理が複数のサービスに散らばっていた。利用枠はトークン数で数えていたが、価格はモデルとトークンの種類で違う。失敗したバックグラウンドタスクは際限なく再試行し、終わった作業とそのコストを繰り返していた。
担当
製品チームの一員として、モデル呼び出しのゲートウェイでの利用量計測と組織ごとの利用枠、モデルの価格設定、バックグラウンド AI タスクの信頼性を担当。
段階
開発環境でマージ済み、動作中。本番環境にはこの先のバージョンごとのリリースで反映。
主な変更
- 計測、利用枠のチェック、エラー処理をゲートウェイに集約。ローカルの利用記録を持つので、計測サービスが遅くてもリクエストを待たせない。
- 利用枠を金額で数える。モデルごとに入力・キャッシュ・出力トークンの原価と販売価格を持ち、デプロイ設定の生成前に販売価格が原価を上回るかを検査する。
- 長いタスクはセグメントごとに進捗を保存。再試行は失敗したセグメントだけで、回数の上限と、回を追って長くなる待ち時間がある。
- 二重送信の防止、停止・削除時のキュー内タスクの取り消し、閲覧専用ロールのフロントエンドでの制限、Windows 開発環境への対応。
結果
≈80%
同じジョブのトークン使用量を削減
テスト環境の一つのジョブでの測定。基盤全体、本番環境、コストの数字ではない。
検証
どの変更も、まずローカルで再現し、テストを書いてから直し、Kubernetes 環境のログで動作を確かめた。
仕組み長いジョブはセグメントごとに進捗を保存し、再試行は失敗したセグメントだけをやり直す。
- セグメント 1: 完了、保存済み
- セグメント 2: 完了、保存済み
- セグメント 3: 失敗
- セグメント 4: 未実行
- セグメント 5: 未実行
セグメント 1・2 はやり直さない
再試行はセグメント 3 だけ
再試行のたびに待ち時間を延ばす。上限に達したら止める。
チーム・段階・限界
- 開発環境
- マージ済み、動作中
- 本番環境
- この先のバージョンごとのリリースで反映
- 販売価格での課金
- 実際のクラウド請求コストと突き合わせたあとに、本番環境で有効化
- チーム
- 基盤はチームで開発している。組織間のデータ分離は製品の前提で、私の担当ではない。
- 数字
- 約 80% は、テスト環境の一つのジョブについての数字で、それ以上のことは示さない。
01製品の背景
会社が開発しているのは、企業向け AI アプリケーション基盤。チームが大規模言語モデルでデータや業務を処理できるようにし、組織間のデータ分離、AI の利用量とコストを管理する。私は 2026 年 10 月にチームに加わった。
02主な判断
四つの判断について、問題、何を決めたか、何と引き換えにしたかを書く。
-
判断 01
計測が遅れても、利用者は待たない
- 問題
- 利用枠のチェック、使用量の計算、失敗時の処理が、複数のサービスに散らばっていた。呼び出しのたびに計測サービスの応答を待つなら、そこが遅れたとき利用者まで止まってしまう。
- 決めたこと
- この三つをモデル呼び出しのゲートウェイに集め、組織ごとにリアルタイムで計測する。ゲートウェイは使用量の記録を手元に持ち、計測サービスが遅れてもリクエストを止めない。
- 引き換え
- ゲートウェイが面倒を見る状態はひとつ増える。そのかわり、ルールはすべてのリクエストが通る一か所に集まり、依存先の遅れが利用者の待ち時間にならない。
失敗もここで分けた。利用枠の使い切り、モデルの混雑、接続の失敗は、それぞれ明確なエラー応答を返す。三つは対処の仕方が違う。一つのエラーにまとめれば、利用者は推測するしかない。
示していることルールはすべてのリクエストが通る場所に置き、依存先が遅れたとき誰が待つのかを先に決めておく。
概念図・本番画面ではありません タスク
モデル呼び出しのゲートウェイ
- 利用枠のチェック
- 組織ごとのリアルタイム計測
- 手元の使用量記録
モデル
計測サービス
遅れても、リクエストは待たない
返すエラーは三つに分ける
- 利用枠の使い切り
- モデルの混雑
- 接続の失敗
-
判断 02
利用枠が尽きたら、新規は止め、実行中は終わらせる
- 問題
- 月の利用枠を使い切ったとき、いちばん単純なルールは全部止めることだ。だがそれでは、途中まで進んだタスクも、そこまでに使った分も無駄になる。
- 決めたこと
- 利用枠を使い切ったあとは、新しいタスクを開始させない。すでに実行中のタスクは、限られた猶予のなかで完了できる。
- 引き換え
- 使用量がわずかに利用枠を超えることがあるので、猶予には上限を設けた。限られた超過は許しても、支払い済みの作業を捨てないほうを選んだ。
示していること新しい支出を止めることと、始まった作業を守ることを、別の問題として扱う。
概念図・本番画面ではありません 利用枠を使い切る
実行中のタスク: 猶予のなかで完了
新しいタスク: 開始できない
限られた猶予
時間
-
判断 03
再試行は、失敗したところだけ
- 問題
- バックグラウンドの AI タスクが失敗すると、際限なく再試行し、終わった作業までやり直して、コストを生み続けていた。
- 決めたこと
- 長いタスクをセグメントに分けて実行し、セグメントごとに進捗を保存する。再試行は失敗したセグメントだけをやり直し、回数に上限を設け、試すたびに待ち時間を延ばす。
- 引き換え
- 分割と進捗の保存のぶん、仕組みは複雑になる。そのかわり、失敗しても終わった分を二度払うことはなく、際限なく繰り返すこともない。
上限と延びていく待ち時間は、一時的な失敗には回復の余地を残し、続く失敗はコストを積み上げる前に止めるためのもの。
結果テスト環境の同じジョブで、修正後のトークン使用量は修正前より約 80% 減った。一つのテストジョブでの測定であり、基盤全体のコストではない。
示していること失敗したあとに何を払うことになるかまで、設計に含めて考える。
-
判断 04
価格のルールを、デプロイ前のチェックに
- 問題
- 利用枠はトークン数で数えていた。だが価格はモデルごと、トークンの種類ごとに違い、トークン数では使った金額がわからない。
- 決めたこと
- 利用枠を金額に切り替え、モデルごとに入力・キャッシュ・出力トークンそれぞれの原価と販売価格を持たせた。デプロイ設定を生成する前に販売価格が原価を上回るかを確かめ、満たさなければ設定は生成しない。
- 引き換え
- 価格表を変えるたびに、関門をひとつ通ることになる。そのかわり、原価を下回る価格は、請求のあとで気づくのではなく、設定ができる前に止まる。
原価は別に記録し、あとで利益率を分析できるようにした。
示していること商売上のルールを、システムが自分で守るチェックに書き換えられる。
概念図・本番画面ではありません モデルごとに利用枠は金額で数える
- 入力トークン
- 原価 販売価格
- キャッシュトークン
- 原価 販売価格
- 出力トークン
- 原価 販売価格
デプロイ設定を生成する前に
すべての販売価格が原価を上回るか
- はい デプロイ設定を生成
- いいえ 停止:設定は生成しない
原価は別に記録し、あとで利益率を分析
03検証のしかた
どの変更も、まずローカルで問題を再現し、テストを書いてから直し、Kubernetes 環境のログで修正後の動作を確かめた。だから検証できるのは、主に動作だ。
- 利用枠を使い切ると、新しいタスクは始まらず、実行中のタスクは猶予のなかで完了する。
- 利用枠の使い切り、モデルの混雑、接続の失敗は、それぞれ別のエラー応答を返す。
- 販売価格が原価を上回らなければ、デプロイ設定は生成されない。
- 再試行は失敗したセグメントだけをやり直し、上限に達すると止まる。
- 二重送信は止められ、タスクを停止・削除するとキュー内のタスクも取り消され、閲覧専用ロールはフロントエンドでも制限される。
- 関係するプロセス間通信を Unix ソケットから名前付きパイプに替え、Windows の開発環境と互換性をもたせた。