Skip to content
NEWNano Banana 2.1 が登場 — Google の最新画像生成モデル、1 枚 $0.0336 から、ネイティブ 4K、前世代の約半額モデルを見る
HopBase
← ブログに戻る

LLM API の使用量照合と部門別チャージバック

結論から言うと、LLM API の請求を照合するには、ベンダーの「透明な課金」という約束ではなく、自分で再計算できる 3 層のデータが必要です。第 1 層は個々のタスクです。HopBase では、動画や非同期画像のタスクが終了すると、その照会レスポンスに usage.cost_usd が含まれます。これはそのタスクで残高から実際に差し引かれた金額で(非ストリーミングの同期レスポンスにも同じフィールドがあります)、課金されなかった失敗は 0 と表示され、curl コマンド 1 本で確認できます。第 2 層は明細記録です。コンソールの使用記録ページから、日付・キー・メンバー・部門・キー作成者で絞り込んだ CSV をエクスポートでき、各行に公式費用・割引・換算レート・課金額が入っているので、公式費用 × 割引 ÷ 換算レート = 課金額を 1 行ずつ検算できます。第 3 層は配賦です。すべてのキーに作成者が表示され、キーごとの消費グラフがあり、部門責任者は自部門のキーと使用量を確認・管理でき、クォータはキー・メンバー・部門ごとに設定できます。この 3 つが揃えば、部門ごとのチャージバックは絞り込みとエクスポートだけで済みます。

LLM の請求照合が難しい理由

チャット・画像・動画のモデルを同時に運用する企業は、少なくとも 4 つの課金単位を扱うことになります。チャットはトークン、多くの画像モデルは枚数、動画は秒数または動画トークン、一部のモデルは 1 回あたりの定額です。さらにいくつかの実務上の問題が加わると、数字が合わなくなります。

  • 非同期タスクは終了時に金額が確定する。動画の投入時点では見積もりしか分からず、実際の課金額はタスク終了後に判明します。失敗したタスクに課金するか、いくら課金するかはベンダーによって異なります。
  • 失敗したリクエスト。失敗したリクエストは通常無料ですが、出力がすでに生成された後にクライアントが切断した場合は、生成済みの部分が課金されるのが一般的です。請求書にそれが書かれていないと、「エラーになったのに課金された」という典型的な揉め事になります。
  • 通貨。公式の定価はほとんどが米ドル建てですが、アカウント残高は別の通貨で管理されている場合があります。間に入る換算レートが分からなければ、誰も課金額を再計算できません。
  • 共有キー。複数のプロジェクトで 1 本のキーを共有すると、後から誰がいくら使ったのか誰にも分からなくなります。

したがって目標は具体的です。すべての課金がタスクまたはリクエスト、キー、そのキーの作成者、部門まで遡れること、そして金額が公開されている定価から再計算できること。

第 1 層:タスク照会から直接得られる実際の課金額

非同期タスク(動画、非同期画像など)が完了・失敗・キャンセルのいずれかになると、単一タスクの照会レスポンスにトップレベルの usage オブジェクトが追加されます。

  • usage.cost_usd は、そのタスクで USD 残高から実際に差し引かれた金額で、使用記録の数字と同じです。
  • usage.cost は同じ課金額を人民元で表したもので、usage.currency は cost の通貨(常に CNY)を示します。照合には cost_usd を使ってください。
  • 課金されなかった失敗タスクは 0 を返します。まれに、課金確定後に画像タスクが失敗した場合(たとえばモデルが使える画像を返さなかった場合)は、実際の課金額が返されます。
  • タスク実行中はこのフィールドは存在せず、タスクを作成したキーだけが参照できます。

対象は GET /v1/video/tasks/{task_id}(Seedance、Grok Imagine、Kling、MiniMax、Midjourney)、GET /api/v1/tasks/{task_id}(Wan、HappyHorse)、GET /v1/images/tasks?task_id=...(GPT Image と Gemini 画像の非同期タスク)です。確認はコマンド 1 本で済みます。

# Query with the key that submitted the task; jq keeps only status and cost
curl -s https://api.hop-base.com/v1/video/tasks/$TASK_ID \
  -H "Authorization: Bearer $HOPBASE_API_KEY" \
  | jq '{status: (.task.status // .status), usage}'

# Once the task has finished you get something like (amount illustrative):
# { "status": "completed", "usage": { "cost": 2.4, "cost_usd": 0.352941, "currency": "CNY" } }

Seedance のレスポンスでは、task.usage は課金対象のトークン数で、トップレベルの usage.cost_usd が金額です。混同しないでください。もともとトップレベルの usage を返す MiniMax と Wan では、cost_usd・cost・currency がそこにマージされます。実務上の利点は、タスクが終わった瞬間に、自社システムが実際の課金額を注文やジョブの記録に書き込めることです。コンソールをポーリングしたり、投入時の見積もりをコストとして計上したりする必要はありません。

第 2 層:1 行ずつ再計算できる明細記録

同期リクエストではタスクが作成されません。非ストリーミングの JSON レスポンスには同じ usage.cost_usd / usage.cost フィールド(および X-HopBase-Cost-USD レスポンスヘッダー)が含まれますが、ストリーミングのレスポンスには含められないため、その金額は使用記録に残ります。コンソールの使用記録ページのエクスポートボタンでダウンロードされる CSV は、ページ上の絞り込み条件(期間、キー、メンバー、部門、キー作成者)に連動し、1 ファイルあたり最大 50,000 行・400 日分です。各行は 13 列です。

  1. 時刻、モデル、使用量(キャッシュの読み書きを含む合計トークン数)
  2. 公式定価の通貨、公式費用(定価通貨建て)
  3. 割引、換算レート、課金額(USD)
  4. 備考
  5. API キー、キーのステータス、ユーザー、部門

左から右へ読むと、このうち 4 列がそのまま検算式になっています。公式費用 × 割引 ÷ 換算レート = 課金額。定価の通貨と残高の通貨が同じ場合、換算レートの欄は空になり、式は公式費用 × 割引 = 課金額になります。公式費用はベンダー自身の料金ページから計算でき、割引はご利用プランのグループの割引率なので、誰かの集計値を信用しなくても、すべての行を独立して確認できます。この式を満たせない行(定価のスナップショットがない初期の記録や、1 枚あたり・1 回あたりの固定単価で課金された呼び出し)では、誤解を招くゼロを表示するのではなく、この 4 列を空欄にしています。

失敗したリクエストには「Request failed, not charged」、出力が生成された後に中断されたリクエストには「Request interrupted, charged for the usage already generated」と備考が付き、ファイルの末尾で両方の件数が集計されます。揉め事の原因になるのはまさにこうした行なので、後から説明するよりも記録の中でルールを明示するほうが確実です。自動化には、API キーを使って GET /v1/usage を呼び出すと、残高とそのキーのクォータ使用状況が返されます。

第 3 層:キー別・部門別の配賦

配賦はコストセンターごとにキーを 1 本用意するところから始まります。HopBase の企業アカウントにはメンバーと部門があり、配賦が実際に機能するかどうかは次のいくつかの点で決まります。

  • すべてのキーに作成者が表示される。メンバー自身が作成したキーと、企業オーナーや部門責任者が作成してメンバーに割り当てたキーを区別でき、エクスポートも作成者で絞り込めます。
  • キーごとの消費グラフ。コンソールではキーごとに消費の推移、リクエスト数、モデル構成を確認できるので、異常な消費がどのキーによるものかすぐに分かります。
  • 部門責任者の権限範囲。部門責任者は自部門のメンバーのキーと使用量を確認・管理でき、そのメンバー向けにキーを作成できますが、他部門は見えません。企業オーナーは全社を確認できます。メンバーが異動すると、権限範囲もそれに追従します。
  • 階層化されたクォータ。クォータはキーごと・メンバーごと・部門ごとに設定でき、どれかに達するとリクエストは 402 で拒否されます。メッセージにはキー・メンバー・部門のどのクォータが尽きたかが示され、曖昧な「残高不足」にはなりません。

月次の部門チャージバックは、使用記録ページで部門と月を選んでエクスポートするだけです。各部門は自分専用の明細ファイルを受け取り、上記の式で再計算できます。

どのベンダーにも使える照合チェックリスト

  1. 非同期タスクの終了後、見積もりや基礎原価ではなく、そのタスクの実際の課金額を API から取得できるか?
  2. 公式費用・割引・換算レートを含む明細をエクスポートでき、各行を再計算できるか?
  3. 失敗したリクエストと「出力生成後に中断した」リクエストは区別して明記されているか?
  4. すべての金額に通貨が明記され、定価と残高の通貨が異なる場合に換算レートが見えるか?
  5. キー・メンバー・部門でエクスポートを絞り込めるか、各キーに作成者が記録されているか?
  6. クォータを階層化でき、クォータエラーがどの層が尽きたかを教えてくれるか?
  7. 支払っているモデルを本当に受け取っているか? 私たちのモデル忠実度の検証方法でご自身で確かめてください。

どの項目も curl かエクスポートファイルで確認できるため、このリストは私たちを含め、どのベンダーにも使えます。

よくある質問

タスク照会の usage.cost_usd は、コンソールの課金額と同じですか?

はい。usage.cost_usd はそのタスクの使用記録にある課金額、つまり残高が実際に減った金額なので、エクスポートした記録と 1 対 1 で突き合わせられます。

タスク実行中に usage.cost_usd がないのはなぜですか?

非同期タスクの最終的な課金額は終了時にしか確定せず、それより前に返す数字は見積もりにしかなりません。そのため、このフィールドはタスクが完了・失敗・キャンセルになった時点で現れます。実行中はこれまでどおりポーリングを続けてください。

失敗したタスクは課金されますか?

失敗した動画タスクは課金されることはなく、照会結果の usage.cost_usd は 0 になります。まれに、画像タスクが課金確定後に失敗することがあり、その場合は照会結果に実際の課金額が返され、同じ金額が使用記録にも表示されます。失敗した同期リクエストは無料です。出力生成後に中断したリクエストは生成済みの分が課金され、エクスポートにその旨が明記されます。

別のキーから自分のタスクの費用が見えないのはなぜですか?

費用はタスクを作成したキーにだけ返されます。これにより「コストセンターごとにキー 1 本」という境界が保たれ、同じアカウントの他のキーから自分のものではない消費が見えることを防ぎます。

チャットのリクエストにもリクエストごとの金額がありますか?

非ストリーミングのリクエストにはあります。レスポンス本文に usage.cost_usd、ヘッダーに X-HopBase-Cost-USD が含まれます。ストリーミングのレスポンスには含まれません。課金額はストリーム終了後にしか確定しないためです。コンソールの使用記録を使ってください。CSV エクスポートで各行を再計算でき、絞り込みとエクスポートでキー別・部門別の合計も得られます。