概要
Azure OpenAIを呼び出すときに使われていたAPI(URLの末尾にapi-versionを付けていたもの)がV1 APIという新しいAPIに変わってきています。従来APIとV1 APIの違いや移行の背景、便利になった点・困った点について、私が実際に試した内容をまとめます。
※言語はPythonで書きます。また、変わった新しいAPI(V1)に対して従来のAPIはPrevious APIと呼称します。
背景
V1 APIへの移行に関しては以下サイトに記載があります。
以前は、Azure OpenAI は新しい API バージョンの毎月の更新プログラムを受け取りました。 新機能を利用する場合は、新しい API リリースごとにコードと環境変数を常に更新する必要があります。 また、Azure OpenAI では、OpenAI と Azure OpenAI の間でコードを移行するときにオーバーヘッドが発生した Azure 固有のクライアントを使用する追加の手順も必要になりました。2025 年 8 月以降、次のサポートを追加する次世代 v1 Azure OpenAI API にオプトインできるようになりました。
Azure OpenAIを呼び出すときは従来、以下のようなコードを書いていました。
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint="https://{AOAIリソース名}.openai.azure.com",
api_key="YOUR_API_KEY",
api_version="2025-04-01-preview",
)
response = client.chat.completions.create(
model="{モデルのデプロイ名}",
messages=[
{"role": "user", "content": "こんにちは"},
],
)
この結果内部的には以下のようなURLにリクエストが飛びます。
https://{AOAIリソース名}.openai.azure.com/openai/deployments/{モデルのデプロイ名}/chat/completions?api-version=2025-04-01-preview
これはAzureではない普通のOpenAIと比べると若干特殊です。
- 使いたいモデル名がbodyではなくdeploymentsのあとurlに直接入り込む
- APIバージョンが末尾に入る
Azure OpenAIの場合、厳密にはモデル名ではなくデプロイ名です。OpenAIとの比較上モデル名を書いています。
これが以下のようになりました。
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://{AOAIリソース名}.openai.azure.com/openai/v1/"
)
response = client.chat.completions.create(
model="{モデルのデプロイ名}",
messages=[
{"role": "user", "content": "こんにちは"},
],
)
リクエストは以下に飛びます。
https://{AOAIリソース名}.openai.azure.com/openai/v1/chat/completions
つまりdeploymentsやapi-versionを個別に URL に含めない共通エンドポイントをAzure側が用意してくれたため、クライアント側は従来使っていたOpenAIライブラリ内のAzure OpenAI専用モジュールAzureOpenAIではなく、OpenAIを使えるようになりました(base_url だけで違いを吸収できるようになった!)。
これにより、クライアント側のコードはOpenAIを呼ぶときと同様のコードにできるようになり、Azure OpenAI 以外のモデルへの移植性が高まりました。
また OpenAI クライアントは本家 OpenAI のモデルを呼び出す際にも使えますが、OpenAI以外のベンダもbase-urlだけ変えてアクセスできるようにモデル公開していることはよくあるパターンです。
これにならい、Azure AI Foundryで提供されているDeepSeekやGrokなどの他モデルも呼び出すことができます。
V1 APIのメリット
エンドポイント変更により、Azure OpenAIモジュールではなくOpenAIが使えるようになり、他モデルへの移植性が上がったことは上述した通りですが、APIバージョンを毎回指定しなくてよくなった点も大きいです。
Previous APIの定義は以下にあります。添付画像の通りpreview版は月次で更新されています。
previewなのでproduction利用はないと思いますが、それでも最新モデルの特定の機能を試そうとすると最新バージョンにアップデート必須なことも多く少し不便でした。
これがV1エンドポイントでラップしてもらえたことはとても便利に思います。
ちなみにV1の定義はこちらです。
V1 APIのサポート状況
以下に記載があります。
使用頻度が高いと思われる以下のエンドポイントは、
-
chat/completions: 従来から提供されている一般的なチャット形式API -
responses: ChatCompletions から移行が進んでいる新形式チャットAPI(Responses API) -
embeddings: ベクトル化するときに使うAPI
一般提供ステータスになっているので本格的に利用することができます。
ただし、画像生成するときの/images/generationsや音声文字起こしを行う/audio/transcriptionsなどは未対応なので完全に全部移行はまだできなさそうです。
最初の v1 一般提供 (GA) API の起動では、推論とオーサリング API 機能のサブセットのみがサポートされます。 運用環境で使用するために、すべての GA 機能がサポートされています。 近日中に、より多くの機能のサポートが急速に追加される予定です。
ただ公式でも近日中に急速にサポートと書いてあるので期待して待ちましょう。
※ただ、画像生成などresponses APIでも可能そうなのでそちらを主流にして、サポートに入らないこともあるかもしれません。
V1 APIで移行で困ったこと
ここからは私が移行で困ってことを共有します。
躓きポイント概要
ニッチなケースかもしれませんが、AzureOpenAIとクライアントの間にAPI Managementなどゲートウェイを挟むパターンでは躓きがあるかもしれません。
V1 APIになったことでクライアントがAzureOpenAIモジュールではなく、OpenAIモジュールを使うようになりましたが、OpenAIでは従来と比べてAPIキーの渡し方が違います。
AzureOpenAIを利用してリクエストを送ると、APIキーはデフォルトでヘッダーのapi-keyに格納されますが、V1で使うOpenAIではAPIキーはヘッダーのapi-keyではなくAuthorization: Bearer でリクエストされます。
V1 APIはもちろんAuthorization: Bearerでの認証に対応していますが、間に挟まるAPI Managementがapi-keyで認証するような形式になっている場合は注意が必要です。
私の躓きポイント
たとえば、私はAPI ManagementでAzure OpenAIのモデルを社内で各社員向けに公開しています。その際に社員それぞれの認証をAPI Managementのサブスクリプション機能で実装しています。サブスクリプションで各社員の認証OKであれば、Azure OpenAIへはマネージドIDで認証します。
念のため付け加えると、API Managementでは、各ユーザーごとに発行したAPIキー(サブスクリプションキー)を使ってアクセス制御ができます。APIを利用する人は、発行されたAPIキーをリクエストのヘッダーに含めて送信することで認証されます。これにより、誰がAPIを使っているかを管理しやすくなります。このあたりについては以前書いたこちらの記事をご参照ください。https://qiita.com/t_yoshikawa/items/990db6bf2d1643e4b751
本来Entra IDなどよりセキュアな認証機能を用いたほうがいい話はありますが、社員がAPIを呼び出すクライアントにはDifyやCLINEなどAPIキーを設定して使うツールも含まれているため、OpenAIやAnthropicと同じくシンプルなAPIキー認証が相性がよかったため、この方法にしています。
API Managementのサブスクリプション機能では、設定でリクエストのheaderに含まれるどの要素でサブスクリプション認証をおこなうかを設定できます。
今まで、AzureOpenAIを利用していたときは、APIキーはデフォルトでヘッダーのapi-keyに格納されるため、それと合わせてAPI Management側でもapi-keyを参照するように設定していました。
こうすることで、ユーザは以下のようにazure_endpointにAPI ManagementのURLを設定するだけで、API Managementを気にすることなく、直接Azure OpenAIを使うときと同様に使えます。
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint="https://{Api Managementのリソース名}.azure-api.net",
api_key=api_key,
api_version="2025-04-01-preview",
)
response = client.chat.completions.create(
model="gpt-5",
messages=[
{"role": "user", "content": "こんにちは"},
],
)
api-keyはヘッダーに直接APIキーを入れる方式で、API Managementのサブスクリプション認証でよく使われます。以前聞いたところによるとAzure OpenAI自体も内部的にはAPI Managementが使われているようでその影響かもしれません。一方、Authorization: BearerはOAuth認証などで使われる方式で、APIキーを「Bearerトークン」として渡します。V1 APIではこの方式が標準ですが、API Managementのサブスクリプション認証とは動作が異なるため注意が必要です。
しかし、V1で使うOpenAIではAPIキーはヘッダーのapi-keyではなくAuthorization: Bearer <APIキー>でリクエストされます。
API ManagementでAuthorization: Bearerをサブスクリプション検証の対象として設定すればいいように思うものの、サブスクリプション認証ではBearerを取り除くなどの処理ができません。サブスクリプション検証はAPI Managementのポリシーより先に動作するため、ポリシーによる操作もできません。
これによってV1 API × API Management(サブスクリプション認証)の組み合わせはそのままでは使えませんでした。
回避策
簡単なものだと、クライアント側でカスタムヘッダーを追加するというものがあります。
client = OpenAI(
api_key=api_key,
base_url="https://{apim-name}.azure-api.net/openai/v1/",
default_headers={"api-key": api_key} # APIMサブスクリプション検証互換のため追加
)
default_headersは、APIリクエスト時に追加のヘッダーを指定できるオプションです。これを使うことで、必要な認証情報やカスタムヘッダーをリクエストに含めることができます。
クライアント側が少数のアプリである場合はこれでもよさそうです。
ただし、私の場合はクライアント=各社員のため、利用者全員にSDKにオプション付加して使うように強制するのも運用上は煩雑で少し難しく思っています。
多少ユーザ側の利便性は下がりますが、Entra IDなどを利用した認証に切り替える必要があるのではないかと思います。
まとめ
新しいV1 API、私はいい変更だと感じました。Azure OpenAI自体は初期リリースが速かったのもあり、今まで独自仕様でしたが、デプロイメント名をURLに入れたりAPIバージョンを毎回指定するのは少しめんどくさかったです。標準化が進んだことはよいことだと思いますし、他のモデルへの移植性もグッドだと思います。
つまづきポイントについては、正直私がだいぶニッチなだけで同じ状況になる人はそんなに多くないかもしれません。ただ、クライアントが標準化されたことでAPIキーの渡し方が変わるっていうのは、当初想定していなかったことなので、誰かに何か気付きを与えることになれば嬉しいです。
全体としては、APIの統一で運用コストも下がるし、今後の機能追加にも期待できるので、私は「便利さ9割・困りごと1割」くらいの温度感です。今後も細かい仕様変更はあると思うので、公式ドキュメントは定期的にチェックしておきますね。
We Are Hiring
BIPROGYでは一緒に働く仲間を募集しています。ご興味ある方は下記をご参照ください。
