1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

APIM + Azure OpenAI + Logic Apps : 予算超過時にAPIアクセスを自動遮断できるようにしてみた - part①

1
Last updated at Posted at 2025-12-25

はじめに

二部構成で、APIM、Logic Apps、Azure OpenAI を利用し、予算の設定値を超過したときに、API アクセスを自動的にストップするような仕組みを構築しようと思います。

この記事では、まずは土台となる APIM と Azure OpenAI の構築を進めたいと思います。

関連する記事

想定読者

  • APIM から Azure OpenAI を呼び出す際、予算の設定値に応じて制限したい
  • 大規模なAIサービス利用における予期せぬ高額請求を防げる仕組みをつくりたい

目次

  • 全体の流れ
  • 実際に試してみよう
  • まとめ

全体の流れ

概要図

image.png

流れ

  1. APIM を作成
  2. Azure OpenAI を作成し、East US と Sweden Central にモデルをデプロイ
  3. API を作成し、APIM で Backends の作成及びロードバランサーを登録
  4. ポリシーを編集(今回は token の制御を実装しています)
  5. テスト

実際に試してみよう

1. APIM の作成

① Azure ポータルの検索窓で APIM と検索し、以下の画面で [作成] をクリック

image.png

② 以下の項目を記載

  • リソースグループやインスタンスの詳細などの項目は、ご自身の環境に合わせて設定してください。また、今回は検証用途での利用であるため、価格レベルは Developer を選択します。

image.png
image.png

  • その他の設定はデフォルトのまま、[作成] をクリック(作成に10分程度かかるため、その間に Azure OpenAI を作成します)

image.png

2. Azure OpenAI を作成し、モデルをデプロイ

今回は East US と Sweden Central の二つのリージョンに gpt4o-mini をデプロイします。
そのため、以下の操作を二回繰り返してください。

① Azure ポータル画面の検索窓で、Azure OpenAI と入力し、以下の画面で [作成] をクリック

image.png

② 以下の項目を記載

  • APIM と同様に、項目はご自身の環境に合わせて設定してください(リージョンの選択は East US と Sweden Central)

image.png

  • その他の設定はデフォルトのまま、[作成] をクリック

image.png

作成後、APIM の Backends の設定で利用するため作成した二つの Azure OpenAI のエンドポイントをメモしておきましょう

image.png

③ 以下の画面から、[Explore Foundry portal] をクリックして、モデルをデプロイする

image.png

  • デプロイタブから [基本モデルをデプロイする] をクリック

image.png

  • gpt-4o-mini を検索して、[確認] をクリック

image.png

  • デフォルト状態のまま、[デプロイ] をクリック

image.png

  • 以下の画面になっていればOK

image.png

3. API を作成し、APIM で Backends の作成及びロードバランサーを登録

API を作成

① APIM の API セクションで、[Azure OpenAI Service] をクリックして、APIを作成

image.png

  • 先ほど作成した Azure OpenAI インスタンスを選択、[improve SDK compatibility] にチェックを入れて、その他の設定はデフォルトのまま作成する

image.png

image.png

Backends を作成

East US と Sweden Central の二つのリージョンでデプロイされたモデルにリクエストをロードバランスさせるために、両リージョンの Backends を作成します。
そのため、以下の操作を二回繰り返してください。

① [新しいバックエンドの作成]をクリック

image.png

② 任意の名前を入力し、プロパティから先ほどメモした Azure OpenAI のエンドポイントに末尾に openai を付け足して、[ランタイムURL]に記載して作成をクリック
例:https://{Azure OpenAIのリソース名}.openai.azure.com/openai

image.png

ロードバランサーに Backends を登録

① ロードバランサーから [新しいプールの作成] をクリック

image.png

② 以下の画面で作成した Backends を選択し、[Send requests evenly] にチェックをいれて [作成] をクリック

image.png

4. ポリシーを編集

① 作成した API 名 → [POST Create a completion for the chat message] → [Inbound processing] の順番でクリック

image.png

② 以下のポリシーを貼り付けて、[Save] をクリック

以下のポリシーでは、token-limit と作成した二つのリージョンにリクエストをロードバランスさせる仕組みを実装しています。
token-limit とは、API Management(APIM)経由で Azure OpenAI を呼び出す際に、1分あたりに消費できるトークン数を制御する機能です。
参考:大規模言語モデル API トークンの使用を制限する

<!-- APIM ポリシー(例) -->
<policies>
    <inbound>
        <!-- ベースポリシーの読み込み -->
        <base />
        <!-- バックエンドサービスを指定 -->
        <set-backend-service id="lb-backend" backend-id="backend-pool" />

        <!-- マネージドIDによるバックエンド認証を設定 -->
        <authentication-managed-identity resource="https://cognitiveservices.azure.com" />

        <!-- Azure OpenAI のトークン制限を設定 -->
        <azure-openai-token-limit 
            tokens-per-minute="1000" 
            counter-key="@(context.Request.IpAddress)" 
            estimate-prompt-tokens="true" 
            tokens-consumed-header-name="consumed-tokens" 
            remaining-tokens-header-name="remaining-tokens" />

        <!-- Azure OpenAI のメトリクスを発行 -->
        <azure-openai-emit-token-metric namespace="genaimetrics">
            <!-- Subscription ID をメトリクスのディメンションとして追加 -->
            <dimension name="Subscription ID" />
            <!-- クライアント IP をメトリクスのディメンションとして追加 -->
            <dimension name="Client IP" value="@(context.Request.IpAddress)" />
        </azure-openai-emit-token-metric>
    </inbound>

    <backend>
        <!-- 429(Too Many Requests)の場合、リトライ処理を行う -->
        <retry condition="@(context.Response.StatusCode == 429)" count="2" interval="1" first-fast-retry="true">
            <!-- リトライ時にリクエストをバックエンドに再送 -->
            <forward-request />
        </retry>
    </backend>

    <outbound>
        <base />
    </outbound>

    <on-error>
        <base />
    </on-error>
</policies>

5. テスト

APIM のテストタブでテストを実施

① 画像のように [Test] タブに移動し、以下の項目を修正した上でその他の設定はデフォルトのまま [send] をクリック

image.png

# Template parameters
deployment-id : gpt-4o-mini
api-version : 2025-01-01-preview

# Request body
{
  "model": "gpt-4o-mini",
  "input": "Hello, can you write a haiku about Azure?"
}

テスト結果

以下のように 200 OK が返ってきていれば、正常に送信できています。
また x-ms-region を確認すると、Sweden Central にリクエストが送信されていることが分かります。

image.png

では、もう一度 [Send] をクリックしてみましょう!
今度は x-ms-region が East US になっていることが分かります。これで各リージョンのモデルに正常にロードバランスされていることが確認できました。

image.png

テストで返ってきたJSONペイロード
{
    "choices": [{
        "content_filter_results": {
            "hate": {
                "filtered": false,
                "severity": "safe"
            },
            "self_harm": {
                "filtered": false,
                "severity": "safe"
            },
            "sexual": {
                "filtered": false,
                "severity": "safe"
            },
            "violence": {
                "filtered": false,
                "severity": "safe"
            }
        },
        "finish_reason": "stop",
        "index": 0,
        "logprobs": null,
        "message": {
            "annotations": [],
            "content": "Azure skies so bright,  \nClouds of code and endless buzz,  \nJust another cloud.",
            "refusal": null,
            "role": "assistant"
        }
    }],
    "created": 1763954245,
    "id": "chatcmpl-CfHMry83CthvCFkrhYcei2lMdRtXY",
    "model": "gpt-4o-mini-2024-07-18",
    "object": "chat.completion",
    "prompt_filter_results": [{
        "prompt_index": 0,
        "content_filter_results": {
            "hate": {
                "filtered": false,
                "severity": "safe"
            },
            "jailbreak": {
                "filtered": false,
                "detected": false
            },
            "self_harm": {
                "filtered": false,
                "severity": "safe"
            },
            "sexual": {
                "filtered": false,
                "severity": "safe"
            },
            "violence": {
                "filtered": false,
                "severity": "safe"
            }
        }
    }],
    "system_fingerprint": "fp_efad92c60b",
    "usage": {
        "completion_tokens": 20,
        "completion_tokens_details": {
            "accepted_prediction_tokens": 0,
            "audio_tokens": 0,
            "reasoning_tokens": 0,
            "rejected_prediction_tokens": 0
        },
        "prompt_tokens": 33,
        "prompt_tokens_details": {
            "audio_tokens": 0,
            "cached_tokens": 0
        },
        "total_tokens": 53
    }
}

まとめ

  • APIM のバックエンドとして登録すると各リージョンの LLM モデルにロードバランスできる仕組みを構築できる
  • 一つのリージョンがトークン制限などの制約に引っかかった場合に、自動で別のリージョンのLLMにリクエストを転送できて便利

終わりに

本記事では、土台づくりとして、APIM とAzure OpenAI で LLM を呼び出す仕組みを構築しました。
次回の記事(APIM + Logic Apps + Azure OpenAI: 予算超過時にAPIアクセスを自動遮断できるようにしてみた - part②)では、APIM や Logic Apps の設定をもとに、予算超過時に API アクセスを自動的にストップさせるような仕掛けをつくっていきたいと思います!

この記事が、少しでもお役に立っていれば幸いです 🙌


  • Azure は、マイクロソフト 企業グループの商標です。
  • その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?