広告

私はAIエージェントのためのトークン課金システムを構築しました――仕組みはこうです

Dev.to / 2026/4/1

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical Usage

要点

  • 著者は、複数のLLMプロバイダー(例:OpenAIやAnthropic)にリクエストをルーティングするAIエージェントに対して、タスクやモデルごとにトークン使用量が変動するため、定額サブスクリプションでは実態を反映できないという前提で、従量課金のトークン課金システムを構築したことを説明している。
  • Stripe Billingのようにトークン計測をゼロから実装するのではなく、また別個のメータリングベンダーを統合するのでもなく、Kong AI Gateway と Kong Konnect Metering & Billing を利用する。これにより、リクエストがすでに流れているゲートウェイ段階でトークン数を取得できる。
  • 提案されているワークフローは、LLM呼び出しをゲートウェイ経由でルーティングし、コンシューマごとにトークンを計測し、価格レートカードを適用して請求書を生成し、その後 Stripe に接続して請求の検証とエクスポートを行う。
  • 設定は、コンシューマの作成、AIプロキシの設定、トークン計測の有効化、機能とプランの定義、メータリング出力を Stripe の請求書と紐づけるところまで、段階的に手順化して説明されている。
  • 全体としてこの記事は、ゲートウェイ段階でのトークン可視性と、メータリングおよびサブスクリプション/請求インフラを組み合わせることで、公正なAIトークン課金を実運用する方法に焦点を当てている。

私は、タスクに応じてOpenAIAnthropicなど複数のLLMプロバイダにリクエストを振り分けるAIエージェントを構築してきました。 しかし、すぐに現実的な問題にぶつかりました:どうすればこれを公平に課金できるのでしょうか?

定額サブスクリプションはしっくりきません。トークンコストはモデルによって異なり、入力と出力でも変わり、さらに実際の使用量も違います。2行の要約を作るユーザーと、3,000語の記事を大量に生成するユーザーは同じではないのに、定額価格では同じ扱いになってしまいます。

そこで使用量ベースの課金の選択肢をいくつか調べました。Stripe Billing はメータリングされたサブスクリプションに対応していますが、その上に自前のトークン追跡パイプラインを作る必要があります。OrbMetronome は良い選択肢ですが、別々のベンダーであり、LLM呼び出しからトークンデータを取得してパイプしていく仕組みは結局必要になります。私が欲しかったのは、トラフィックがすでに流れているゲートウェイのレベルでの仕組みです。

最終的に、Kong AI GatewayKonnect Metering & BillingOpenMeter に基づいています)を使うことにしました。ゲートウェイはすべてのLLMリクエストをプロキシするため、トークン数をすでに把握しています。メータリング層はそこに直接組み込まれます。別のベンダーも不要ですし、カスタムのパイプラインも不要です。

そこで、価格モデルについて議論する代わりに、課金レイヤーをセットアップしました。すべてのAPIリクエストがゲートウェイを経由し、追跡され、実際の使用量に基づいて料金が計算される、動作する仕組みです:

  1. AI Gateway 経由でリクエストをルーティング
  2. 消費者ごとにトークンをメータリング
  3. 料金を適用
  4. 請求書を生成

以下が、全体のセットアップを手順ごとに説明します。

  • ゲートウェイをセットアップ
  • ステップ1:コンシューマーを作成
  • ステップ2:AIプロキシを設定
  • ステップ3:トークンのメータリングを有効化
  • ステップ4:機能(feature)を作成
  • ステップ5:レートカード付きのプランを作成
  • ステップ6:サブスクリプションを作成
  • ステップ7:請求書を検証
  • ステップ8:Stripe を接続

セットアップ

課金パイプラインには3つの層があります:

Kong AI Gateway は LLMリクエストをプロキシします。アプリとプロバイダの間に位置し、認証を処理します。そして課金の観点で重要なのは、すべてのリクエストについてトークン統計をログに記録する部分です。

Konnect Metering & Billing(これは OpenMeter に基づいています)は、これらのトークンイベントをコンシューマーごと・課金サイクルごとに集計します。生の使用データの上に、機能定義、価格モデル、プランを設定できます。

Stripe が支払いを回収します。メータリング層が請求書を生成し、それがStripeと同期します。

それぞれのパーツを順に説明します。

前提条件

これはUIだけでもCLI経由でも可能です。進めながら両方を説明します。

  1. Kong Konnect のアカウント
  2. OpenAI APIキー(または任意のLLMプロバイダのキー)

CLIの場合は、さらに decK (v1.43+) をインストールして、Kong Konnect から取得したPAT が必要です。

ゲートウェイのセットアップ

ログインしたら、API Gateway をクリックして1つ作成します。

ここでは Serverless を使います。セルフホスト(Self-managed)でも構いません。ゲートウェイ名を ai-service と入力し、Create and configure をクリックします。完了したら、Add a service and route をクリックして、次を入力してください:

  • Service Name: ai-service
  • Service URL: http://httpbin.konghq.com/anything
  • Route Name: ai-chat
  • Route Path: /chat

CLI

コマンドラインを好む場合は、PATを生成して次を実行します:

export KONNECT_TOKEN='your_konnect_pat'
curl -Ls https://get.konghq.com/quickstart | bash -s -- \
  -k $KONNECT_TOKEN --deck-output

これで、Konnect に接続された Kong Gateway が起動します。いくつかの環境変数が出力されるので、指示どおりにそれらをエクスポートしてください。さらに必要です:

export DECK_OPENAI_API_KEY='your_openai_api_key'

次にサービスとルートを設定します:

_format_version: "3.0"
services:
  - name: ai-service
    url: http://httpbin.konghq.com/anything
routes:
  - name: ai-chat
    paths:
      - "/chat"
    service:
      name: ai-service

deck gateway apply で適用します。これで、LLM に接続する /chat のルートが用意できました。

ステップ1:コンシューマーを作成

返却形式: {"translated": "翻訳されたHTML"}

ゲートウェイが がリクエストを行っているのかを認識していない限り、誰にも請求を行えません。コンシューマは、Kong が API 呼び出し元を識別するためのものです。後ほど、各コンシューマを請求先の顧客に紐づけます。

キー認証のクレデンシャルでコンシューマを追加します:

キーの値は acme-secret-key と入力できます。

次に、ゲートウェイが実際に認証を要求するように、サービスへ key-auth プラグインを追加する必要があります:

  1. 左サイドバーの Plugins をクリックします
  2. New Plugin をクリックします
  3. プラグイン一覧から Key Authentication を選択します
  4. スコープとして Service を選ぶか、Global のままにします
  5. Save をクリックします

CLI

_format_version: "3.0"
consumers:
  - username: acme-corp
    keyauth_credentials:
      - key: acme-secret-key

次に、ゲートウェイが実際に認証を要求するように、サービスへ key-auth プラグインを有効化します:

_format_version: "3.0"
plugins:
  - name: key-auth
    service: ai-service
    config:
      key_names:
        - apikey

deck gateway apply で両方適用します。

これで /chat へのすべてのリクエストは、apikey ヘッダーを含める必要があります。ゲートウェイは呼び出し元を acme-corp として識別し、その身元はメータリングに渡されます。この手順を行わないと、使用状況イベントに主語(subject)がありません。つまり匿名になり、誰に紐づけることもできません。

Step 2: Configure the AI Proxy

次に、ルートを実際の LLM に接続します。AI Proxy プラグインは、OpenAI のチャット形式でリクエストを受け取り、設定済みのプロバイダへ転送します。

  1. Plugins に移動します
  2. New Plugin をクリックします
  3. プラグイン一覧から AI Proxy を選択します

以下の yaml を(CLI 用として)参考にして、プラグインの各フィールドをそれに合わせて設定します:

_format_version: "3.0"
plugins:
  - name: ai-proxy
    config:
      route_type: llm/v1/chat
      auth:
        header_name: Authorization
        header_value: Bearer ${{ env "DECK_OPENAI_API_KEY" }}
      model:
        provider: openai
        name: gpt-4o
      logging:
        log_payloads: true
        log_statistics: true

ここで注意すべき点は2つあります:

log_statistics: true が、請求(billing)を可能にします。これがないと、ゲートウェイはリクエストをプロキシしますが、トークン数を記録しません。有効にすると、すべてのレスポンスについてプロンプトトークン、完了トークン、合計トークンを取得します。これは、下流のメータリングが消費するデータです。

log_payloads: true は、実際のリクエスト/レスポンスの内容をログに出力します。これは任意で、デバッグに役立ちますが、プライバシー上の理由から本番ではオフにしておくのが一般的です。

deck gateway apply で適用し、テストします:

curl -X POST "$KONNECT_PROXY_URL/chat" \
  -H "Content-Type: application/json" \
  -H "apikey: acme-secret-key" \
  --json '{
    "messages": [
      {"role": "system", "content": "You are a mathematician."},
      {"role": "user", "content": "What is 1+1?"}
    ]
  }'

GPT-4o からのレスポンスが得られるはずです。ゲートウェイは認証を処理し、リクエストを転送し、トークン統計情報をログに記録しました。

複数のプロバイダ(たとえば、OpenAI と Anthropic を自動フォールバックで使う)をプロキシしたい場合は、ロードバランシングの設定を伴って [ai-proxy-advanced](https://developer.konghq.com/plugins/ai-proxy-advanced/) を代わりに使います。ここでは請求のウォークスルーに集中するため、1つのプロバイダのみに固定しました。

Step 3: Enable Token Metering

ここで、ゲートウェイのトークンログをメータリングシステムに接続します。

Konnect で、サイドバーの Metering & Billing に移動します。AI Gateway Tokens セクションが表示されます。Enable Related API Gateways をクリックし、コントロールプレーン(クイックスタートのもの)を選択して確認します。

これは kong_konnect_llm_tokens という内蔵メーターを有効化します。トークン数に対して SUM 集計を行い、以下でグループ化します:

  • $.model :どの LLM がリクエストを処理したか
  • $.type :トークンが入力(request)か出力(response)か

グループ化が重要なのは、LLM プロバイダーが入力トークンと出力トークンで課金体系が異なるためです。出力トークンは通常、入力より 3〜5倍高価です。理由は、入力は GPU 間で並列化できる一方で、出力生成は逐次的であり、各トークンはそれまでのすべてのトークンに依存するからです。メータリングがこれらを分けていないと、料金が誤ってしまいます。

現時点では、AI Gateway を通過するすべての認証済みリクエストが使用状況イベントを生成し、メーターによって集計されます。しかし、使用状況だけでは請求書は作られません。何を課金対象にするか、またどういう価格で請求するかを定義する必要があります。

Step 4: Create a Feature

フィーチャーとは、生の計測データと、請求書に載る何かとの結び目です。これがないと、利用は追跡されるものの、請求されることはありません。

Metering & Billing → Product Catalog → Features に移動し、次のように 1 つ作成します:

  • Name: ai-token
  • Meter: AI Gateway Tokens
  • Group by filters:
    • Provider = openai
    • Type = request (これは入力トークンを追跡します。もし入力と別のレートで価格付けしたいなら、出力トークン用に別のフィーチャーを作成してください)

フィルターによって、メーターの対象が利用状況の特定の切り口に絞り込まれます。実運用では、複数のフィーチャーを作り、モデルごと、トークンの方向(入力/出力)ごとに分けることで、異なるレートを適用することになるでしょう。この手順では、流れを示すためにフィーチャーを 1 つだけにしてあります。

Step 5: Create a Plan with a Rate Card

プランはフィーチャーを価格とともにまとめます。Product Catalog → Plans に移動して、次のように 1 つ作成します:

  • Name: Starter
  • Billing cadence: 1 month

レートカードを追加します:

  • Feature: ai-token
  • Pricing model: Usage Based
  • Price per unit: 1
  • Entitlement type: Boolean(フィーチャーへのアクセスを許可する)

ここで言う「unit あたりの price」が意味するものについての注意:1 unit = 1 token です。メーターが個々のトークンを SUM するためです。つまり 1 を入力するとトークンあたり $1.00 になり、実運用ではかなり高額です。ここでそれを使っているのは、公式チュートリアル が同じことをしているためです。テスト中に請求の変化を見つけやすくするための、四捨五入された(キリの良い)数字を使っています。

本番では、例えば GPT-4o の入力トークンなら 0.000003($3.00 / 1M tokens)、GPT-4o の出力トークンなら 0.00001($10.00 / 1M tokens)のように入力します。UI には「1,000 あたり」切り替えはありません。自分で計算して、小数としてトークンあたりの価格を入力します。

プランを公開します。これでサブスクリプションで利用可能になります。

Step 6: Create a Customer and Start a Subscription

ここで Step 1 のコンシューマーが、請求システムに接続されます。

Metering & Billing → Billing → Customers に移動し、次のように 1 つ作成します:

  • Name: Acme Corp
  • Include usage from: acme-corp コンシューマーを選択

このマッピングが、ゲートウェイのトラフィックを課金対象の実体に結び付けます。コンシューマーはゲートウェイのレベルでアイデンティティを扱います。一方で、顧客(カスタマー)は請求のレベルでアイデンティティを扱います。ここではこれらは別概念として扱われ、結び付けられます。

次にサブスクリプションを作成します:

  • Acme Corp の顧客を開き、Subscriptions → Create a Subscription を選択
  • Plan: Starter
  • サブスクリプションを開始する

重要な点が 1 つあります:メータリングは、サブスクリプション開始後に発生した「請求書イベント」だけをインボイス化します。 サブスクリプションを作成する前にテストリクエストを送っていた場合、そのトークンはどの請求書にも表示されません。私はこれをドキュメントで見つけるまで少し混乱していました。

Step 7: Validate the Invoice

ゲートウェイ経由でいくつかリクエストを送信します:

for i in {1..6}; do
  curl -s -X POST "$KONNECT_PROXY_URL/chat" \
    -H "Content-Type: application/json" \
    -H "apikey: acme-secret-key" \
    --json '{
      "messages": [
        {"role": "user", "content": "Explain what a Fourier transform does in two sentences."}
      ]
    }'
  echo ""
done

イベントが伝播するまで1、2分待ってから、Metering & Billing → Billing → Invoices に進みます。Acme Corp をクリックし、Invoicing タブに移動して、Preview Invoice を押します。

ai-token 機能が、集計されたトークン数と、レートカードに基づいて計算された請求額とともに表示されているはずです。これは、API リクエストからインボイスの明細行まで、請求パイプラインがエンドツーエンドで動作していることを意味します。

Stripe を接続

Konnect は請求書を Stripe に同期し、Stripe が支払いの回収、レシート、失敗した支払いのリトライロジックを処理します。Metering & Billing の設定で Stripe アカウントを接続すると、請求サイクルの末尾で請求書が自動的に流れていきます。

エンドユーザーにとっての結果は、消費した内容がそのまま分かる透明性のある請求書です。トークン数、モデル、適用されたレートが表示されます。内訳のない定額料金ではありません。

## 私がぶつかったこと

コンシューマーとカスタマーの対応付けは、最初は混乱しました。 Kong Gateway には「コンシューマー」(API の識別子)があります。Metering & Billing には「カスタマー」(請求上の識別子)があります。どちらも別物です。両方を作成してからリンクします。コンシューマーをスキップしたり、リンクを忘れたりすると、使用状況のイベントは入ってくるものの、請求可能な誰かに紐づけられません。トラフィックを送り始める前に、これを設定してください。

入力と出力の料金は、思っていた以上に重要でした。 OpenAI の GPT-4o における出力トークンは $10.00/1M で、入力は $2.50/1M です。「トークン」という1つの定額レートで見積もると、出力が多いワークロードを大幅に安く見積もってしまいます。トークン種別(リクエスト vs レスポンス)ごとに機能を分けて、それぞれ別に料金設定するのが、追加の設定分に見合う価値があります。

処理の順序が重要です。 具体的には、請求のために関係するトラフィックを送信し始める に、コンシューマーを作成し、それをカスタマーにリンクしてください。サブスクリプションが存在しない状態で到着したイベントは、インボイスに遡って表示されることはありません。

次にここから進めるなら

このウォークスルーでは、単一のプロバイダーと単一の機能を使います。プロダクション環境なら、より次のようになります:

  • 複数の機能:モデルごと・トークン方向ごとに1つ(GPT-4o の入力、GPT-4o の出力、Claude の入力、Claude の出力)
  • 段階的な価格設定:使用量が増えるほどトークン単価を下げ、成長を促す
  • 従量上限付きのエンタイトルメント:プラン階層ごとに月あたりの総トークン数を上限で制限し、Starter(500K トークン)、Pro(5M トークン)、Enterprise(無制限)を提供できるようにする
  • AI Proxy Advanced:負荷分散を使って複数のプロバイダーにルーティング(最低レイテンシー、ラウンドロビン、またはコストベースのルーティング)

これらすべてのドキュメントは、developer.konghq.com/metering-and-billingdeveloper.konghq.com/ai-gateway にあります。

AI エージェントを作っていて、どう課金するかを考えているなら、ぜひあなたのアプローチを聞いてみたいです。トークン単位、クレジット、定額料金のいずれですか? うまくいっている点、うまくいっていない点は何でしょう。コメント欄にあなたの考えを投稿してください。

広告