はじめに
今回は、Azure OpenAI からの新しいステートフル APIである Responses API を利用して、Azure API Management(以降、APIMと呼ぶ)経由でAzure OpenAIのモデルを呼び出すことを試してみたいと思います。
Responses API は、「入力(input)」に自然言語を渡すだけで、Chat Completions API や Completions API、Embeddings API など複数のエンドポイントへの出力を統一した形式で返してくれる新しい API です。
2025年10月時点では、利用可能なリージョンに制限があります。最新情報は以下を参照してください。
Azure OpenAI Responses API
目次
- 想定読者 / 前提条件
- 全体の流れ
- 実際に試してみよう
- まとめ
想定読者 / 前提条件
- APIM から Responses API を使って LLM を呼び出す構成を実装したい
- Azure サブスクリプションを保有している
- Azure OpenAI、APIM を作成する権限を持っている
全体の流れ
- APIM を作成
- Azure OpenAI を作成し、モデルをデプロイ
- API / Operation を作成し、APIM にバックエンドを登録する
- ポリシーを編集(今回は token の制御を実装しています)
- テスト
実際に試してみよう
1. APIM の作成
① Azure ポータルの検索窓で APIM と検索し、以下の画面で [作成] をクリック
② 以下の項目を記載
- リソースグループやインスタンスの詳細などの項目は、ご自身の環境に合わせて設定してください。また、今回は検証用途での利用であるため、価格レベルは Developer を選択します。
- その他の設定はデフォルトのまま、[作成] をクリック(作成に10分程度かかるため、その間に Azure OpenAI を作成します)
2. Azure OpenAI を作成し、モデルをデプロイ
① Azure ポータル画面の検索窓で、Azure OpenAI と入力し、以下の画面で [作成] をクリック
② 以下の項目を記載
- APIM 同様に項目は、ご自身の環境に合わせて設定してください。
- その他の設定はデフォルトのまま、[作成] をクリック
③ 以下の画面から、[Azure AI Foundry ポータルの詳細] をクリックして、モデルをデプロイする
- デプロイタブから [基本モデルをデプロイする] をクリック
- gpt-4o-mini を検索して、[確認] をクリック
- デフォルト状態のまま、[デプロイ] をクリック
- 以下の画面になっていればOK
3. API / Operation を作成し、APIM にバックエンドを登録する
API を作成
① APIM の API セクションで、[Azure OpenAI Service] をクリックして、APIを作成
- 先ほど作成した Azure OpenAI インスタンスを選択、[improve SDK compatibility] にチェックを入れて、その他の設定はデフォルトのまま作成する
Operation を作成
① 以下の画面で [Add operation] をクリック
② Frontend を以下のように記載し、[Save] をクリック
Backends を登録
① デフォルトで作成されているバックエンドをクリック
② プロパティから 先ほどメモした Azure OpenAI のエンドポイントを最後の / を削除して記載し、保存をクリック
例:https://{Azure OpenAIのリソース名}.openai.azure.com
4. ポリシーを編集(今回は token の制御を実装しています)
① 以下の画面で Inbound processing の [Policies] をクリック
② 以下のポリシーを貼り付けて、[Save] をクリック
以下のポリシーでは、token-limit を実装しているため、必要ない場合は適宜削除してください。
token-limit とは、API Management(APIM) 経由で Azure OpenAI を呼び出すときに、1分あたりに消費できるトークン数を制御する機能です。
参考:大規模言語モデル API トークンの使用を制限する
<!-- APIM ポリシー(例) -->
<policies>
<inbound>
<base />
<!-- backend-id に登録した Backends のバックエンド名を記載-->
<set-backend-service id="azure-openai-backend" backend-id="responsesapi-openai-endpoint" />
<!-- Entra ID (Managed Identity) を使ってアクセストークンを取得 -->
<authentication-managed-identity resource="https://cognitiveservices.azure.com" />
<!-- (任意)token-limit で100トークン / 分の制限を実施 -->
<azure-openai-token-limit tokens-per-minute="100" counter-key="@(context.Request.IpAddress)" estimate-prompt-tokens="true" tokens-consumed-header-name="consumed-tokens" remaining-tokens-header-name="remaining-tokens" />
<azure-openai-emit-token-metric namespace="genaimetrics">
<dimension name="Subscription ID" />
<dimension name="Client IP" value="@(context.Request.IpAddress)" />
</azure-openai-emit-token-metric>
<!-- 呼び出し先パスを Responses API に書き換え -->
<rewrite-uri template="/openai/v1/responses" />
<!-- Content-Type ヘッダ ( Policyに記載するかテストをする際に Headers で指定しても良い)-->
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
</inbound>
<backend>
<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 のテストタブでテストを実施
① 画像の Request body に以下を記載し、その他の設定はデフォルトのまま [send] をクリック
{
"model": "gpt-4o-mini",
"input": "Hello, can you write a haiku about Azure?"
}
テスト結果
以下のように 200 OK が返ってきていれば、正常に送信できています。
また APIM のポリシーで、consumed-tokens や remaining-tokens を含めるようにしているため、このリクエストでどのくらいトークンを消費したかが確認できるようになっています。
テストで返ってきたJSONペイロード
{
"id": "xxxxxx",
"object": "response",
"created_at": "xxxxxx",
"status": "completed",
"background": false,
"content_filters": null,
"error": null,
"incomplete_details": null,
"instructions": null,
"max_output_tokens": null,
"max_tool_calls": null,
"model": "gpt-4o-mini",
"output": [{
"id": "xxxxxx",
"type": "message",
"status": "completed",
"content": [{
"type": "output_text",
"annotations": [],
"logprobs": [],
"text": "Endless skies unfold, \nClouds weave whispers of the breeze\u2014 \nAzure dreams take flight."
}],
"role": "assistant"
}],
"parallel_tool_calls": true,
"previous_response_id": null,
"prompt_cache_key": null,
"reasoning": {
"effort": null,
"summary": null
},
"safety_identifier": null,
"service_tier": "default",
"store": true,
"temperature": 1.0,
"text": {
"format": {
"type": "text"
},
"verbosity": "medium"
},
"tool_choice": "auto",
"tools": [],
"top_logprobs": 0,
"top_p": 1.0,
"truncation": "disabled",
"usage": {
"input_tokens": 18,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 21,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 39
},
"user": null,
"metadata": {}
}
(Ubuntu環境で)curl でテストしたい場合の参考となるコマンドを記載しておきます。
前提:
- APIM の API タブ>(該当の API )>Settingsの [Subscription required] がチェックされている
- APIM 側の製品 (Product) と API が紐づけされている(参考)
curl -X POST "https://{APIMのリソース名}.azure-api.net/responsesapi/openai/responses" \
-H "api-key: <subscription-key>" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","input":"Write a haiku about Azure."}'
(おまけ)token-limit でトークン制限ができているかの確認
Request body を以下に変更して、複数回連続で [Send] をクリックしてください。
{
"model": "gpt-4o-mini",
"input": "100文字程度の小説を考えてください"
}
すると以下のような 429エラーが返ってくるはずです。これが返ってこれば、ポリシーで定義したトークン制限が正常に機能していることが分かります。
まとめ
- 従来の Chat Completions API と同様にAPIM 経由で、新しい呼び出し方法である Responses API を利用して、 Azure OpenAI を呼び出すことが可能に
- api-version や deployment-id などをパラメータとして指定せずにリクエストを送信できるため、非常に使い勝手が良い
- APIM をフロントに置くことで、Azure OpenAI の呼び出しを安全に隠蔽でき、認証・レート制御・レスポンス整形などを一元管理できるため、実運用でも十分に威力を発揮してくれそう
終わりに
本記事では、APIM を経由して Azure OpenAI の Responses API を利用する方法を紹介しました。
実際に試してみると、ヘッダ設定やポリシー適用など細かい部分でつまずくこともありましたが、それらを理解することで APIM と ResponsesAPI の強力さを改めて実感できました。
この記事が、少しでもお役に立っていれば幸いです 🙌
- Azure は、マイクロソフト 企業グループの商標です。
- その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。























