Azure OpenAI Chat Completions から Responses API への Python アプリ移行
正式な指示 — 正確に従うこと
このスキルは Azure OpenAI Chat Completions を使用している Python コードベースを 統一された Responses API に移行します。指示に正確に従ってください。 パラメータのマッピングを即興で行ったり、API 形状を独自に作成しないでください。
トリガー
ユーザーが以下を望むときにこのスキルを有効にします:
- Azure OpenAI Chat Completions から Responses API へ Python アプリを移行する
- Python の OpenAI SDK の使用を最新の Azure OpenAI 用 API 形状にアップグレードする
- Azure で Responses が必要な GPT-5 以降のモデルに備えて Python コードを準備する
AzureOpenAI/AsyncAzureOpenAIから標準のOpenAI/AsyncOpenAIクライアントの v1 エンドポイントに切り替えるAzureOpenAIのコンストラクターやapi_versionに関する廃止警告を修正する
⚠️ モデル互換性 — まず確認すること
移行前に、Azure OpenAI 配備が Responses API をサポートしているか確認してください。
1. 配備のスモークテスト(最速)
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AZURE_OPENAI_API_KEY"],
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
)
try:
resp = client.responses.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
input="ping",
max_output_tokens=50,
store=False,
)
print(f"✅ Deployment supports Responses API: {resp.output_text}")
except Exception as e:
print(f"❌ Deployment does NOT support Responses API: {e}")
注意: Azure OpenAI では
max_output_tokensの最小値は16です。16未満は400エラーになります。スモークテストでは50以上を使用してください。
これが 404 を返す場合、その配備のモデルはまだ Responses に対応していません — 下記参照か対応モデルで再配備してください。
2. お住まいのリージョンの利用可能モデルを確認(推奨)
標準のモデル互換性ツールを実行して、お住まいのリージョンで Responses API 対応モデルを確認してください:
python migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION
これは Azure ARM のライブデータを問い合わせ、対応表を示します — Responses、構造化出力、ツールなどの対応状況が分かります。--filter gpt-5.1,gpt-5.2 で絞り込み、--json でスクリプト処理可能です。
3. 全モデルサポート参照
- ライブクエリ:
python migrate.py models(上記参照 — リージョン別、常に最新) - 利用可否ブラウズ: モデルの概要表とリージョン別可用性
- クイックスタートとガイダンス: https://aka.ms/openai/start
⚠️ 古いモデルの制限
警告: 古いモデル(
gpt-4.1より前のもの)は Responses API の全機能を完全にサポートしていない場合があります。古いモデルの既知の制限:
reasoningパラメーター: 多くの reasoninng 非対応モデルではサポートされません。元のコードにreasoningがあればそれを移行してください。seedパラメーター: Responses API では全くサポートされていません — 全リクエストから削除してください。text.formatによる構造化出力: 古いモデルはstrict: trueJSON スキーマを確実に適用しません。- ツールオーケストレーション: GPT-5+ は内部推論の一部としてツール呼び出しを統合します。古いモデルは Responses で動作しますが深い統合はありません。
- 温度制約:
gpt-5へ移行時は temperature を省略するか1に設定してください。古いモデルはこの制約がありません。
Oシリーズ推論モデル (o1, o3-mini, o3, o4-mini)
Oシリーズモデルには特殊なパラメーター制約があります。Oシリーズモデルを対象とするアプリを移行するとき:
temperature:1にするか省略してください。Oシリーズは他の値を受け付けません。max_completion_tokens→max_output_tokens: Azure固有のmax_completion_tokensはmax_output_tokensに切り替えが必要。推論トークンもカウントするため大きな値(4096以上)を指定してください。reasoning_effort: アプリがreasoning_effort(low/medium/high)を使っている場合、そのまま維持してください — Responses API は Oシリーズでこのパラメーターをサポートします。- ストリーミング動作: Oシリーズは推論終了まで出力をバッファしてからテキスト差分イベントを送る場合があります。ストリーミングは機能しますが、最初の
response.output_text.deltaが GPT モデルより遅れることがあります。 top_p: Oシリーズはサポートしません — 存在すれば削除してください。- ツールの利用: Oシリーズモデルは Responses API 経由で GPT モデルと同様にツールをサポートしますが、モデルごとにツール呼び出しのオーケストレーション品質は異なります。
対応 — 事前のモデルアドバイス: スキャン段階でアプリがターゲットとするモデル(配備名、環境変数、設定)を確認してください。gpt-4.1 より古いモデルの場合(gpt-4.1以上でない場合)、ユーザーに次のことを伝えましょう:
- 移行は現在のモデルで基本的なテキスト・チャット・ストリーミング・ツールで動作します。
- 新しいモデル(
gpt-5.1、gpt-5.2)はより良いツールオーケストレーション、構造化出力の強制、推論、リージョン横断可用性を提供します。 - 準備ができたら配備のアップグレードを検討してください — 移行を妨げるものではありません。
モデルバージョンを理由に移行を拒否・ブロックしないでください。この案内は情報提供のみです。
GitHub Models は Responses API をサポートしません
GitHub Models (
models.github.ai,models.inference.ai.azure.com) は Responses API をサポートしていません。
もしコードベースに GitHub Models のコードパスがある場合(base_url が models.github.ai または models.inference.ai.azure.com を指している)、移行時に完全に削除してください。Responses API は Azure OpenAI、OpenAI、または対応するローカルエンドポイント(例:Responses対応の Ollama)が必要です。
スキャン時のアクション:
- GitHub Models のコードパスは削除対象としてマークしてください。
フレームワークの移行
多くのアプリは OpenAI の上に高レベルのフレームワークを使っています。これらを移行するときは、フレームワーク自身の API 変更にも注意が必要で、単に基底の OpenAI 呼び出しを置き換えるだけではありません。
Microsoft Agent Framework (MAF)
まず MAF のバージョンを確認してください — 移行は MAF 1.0.0 以降か、それ以前のベータ/RCかによって異なります。
MAF 1.0.0 以降 (agent-framework-openai >= 1.0.0)
OpenAIChatClient は すでに Responses API を使用しています — 移行不要です。レガシーの OpenAIChatCompletionClient(chat.completions.create を使う)を使っている場合は OpenAIChatClient に置き換えてください。
| 以前 | 以降 |
|---|---|
from agent_framework.openai import OpenAIChatCompletionClient |
from agent_framework.openai import OpenAIChatClient |
OpenAIChatCompletionClient(...) |
OpenAIChatClient(...) |
バージョン確認コマンド: python -c "import agent_framework_openai; print(agent_framework_openai.__version__)"
MAF 1.0.0 未満 (ベータ/RC リリース)
1.0.0 未満の MAF では OpenAIChatClient が Chat Completions を使っていました。agent-framework-openai>=1.0.0 にアップグレードすると OpenAIChatClient はデフォルトで Responses API を使います。
他の変更は不要です — Agent とツールの API は変わりません。
LangChain (langchain-openai)
ChatOpenAI() に use_responses_api=True を追加し、レスポンスアクセスを .content から .text に変更してください。
| 以前 | 以降 |
|---|---|
ChatOpenAI(model=..., base_url=..., api_key=...) |
ChatOpenAI(model=..., base_url=..., api_key=..., use_responses_api=True) |
result['messages'][-1].content |
result['messages'][-1].text |
完全な変更例は cheat-sheet.md を参照してください。
フロントエンド移行ガイダンス
Responses API はサーバーサイドの関心事です。 Python バックエンドを移行してください。フロントエンドの HTTP 契約はバックエンドが薄いパススルーでない限り変更不要です — もしそうなら、Responses リクエスト形状の採用を検討し、翻訳レイヤーをなくしてください。フロントエンドがクライアント側のキーで OpenAI を直接呼び出している場合は、まずバックエンドで呼び出すようにしてください。
@microsoft/ai-chat-protocol の廃止
@microsoft/ai-chat-protocol npm パッケージは廃止されており、ndjson-readablestream に置き換えるべきです。フロントエンドで見つけたら:
- CDNスクリプトタグを置き換える:
<!-- Before --> <script src="https://cdn.jsdelivr.net/npm/@microsoft/ai-chat-protocol@.../dist/iife/index.js"></script> <!-- After --> <script src="https://cdn.jsdelivr.net/npm/ndjson-readablestream@1.0.7/dist/ndjson-readablestream.umd.js"></script> AIChatProtocolClientのインスタンス生成 (new ChatProtocol.AIChatProtocolClient("/chat")) を削除する。client.getStreamedCompletion(messages)をバックエンドのストリーミングエンドポイントへの直接fetch()呼び出しに置き換える。for await (const response of result)をfor await (const chunk of readNDJSONStream(response.body))に置き換える。- プロパティアクセスを
response.delta.content/response.errorからchunk.delta.content/chunk.errorに変更する。
目的
- Azure OpenAI に対する Chat Completions またはレガシー Completions を使っているすべての Python 呼び出し箇所を列挙する。
- Python コードベースに対し移行計画と順序を提案する。
- Responses API に切り替えるための安全かつ最小限の修正を適用する。
- 呼び出し側を Responses 出力スキーマを消費するように更新する。互換ラッパーは使わない。
- テストやリントを実行し、移行による小さな破壊を修正する。
- 小さくレビューしやすい変更セットを用意し、最終的な差分付きサマリーを提供する(コミットはしない)。
ガードレール
- git ワークスペース内のファイルのみ修正する。外部には書き込まない。
- 後方互換のシムを残さず、新しい API 形状にコードを移行する。
- 墓標/トランジション用コメントやバックアップファイルを残さない。
- 以前ストリーミングを使っていればそのまま維持し、それ以外は非ストリーミングを使用する。
- 承認モードならコマンドやネットワーク呼び出しの実行前に承認を求める。
git add/git commit/git pushは実行しない。作業ツリーの編集のみを行う。
ステップ 0: Azure OpenAI クライアントの移行(事前準備)
コードベースで AzureOpenAI や AsyncAzureOpenAI のコンストラクターを使っていれば、まず標準の OpenAI / AsyncOpenAI コンストラクターに移行してください。Azure 固有のコンストラクターは openai>=1.108.1 で廃止されました。
なぜ v1 API パスを使うのか?
新しい /openai/v1 エンドポイントは AzureOpenAI() ではなく標準の OpenAI() クライアントを使い、api_version パラメーターを不要にし、OpenAI と Azure OpenAI の両方で同じ動作を保証します。同じクライアントコードで将来も問題ありません — バージョン管理が不要です。
主な変更点
| 以前 | 以降 |
|---|---|
AzureOpenAI |
OpenAI |
AsyncAzureOpenAI |
AsyncOpenAI |
azure_endpoint |
base_url |
azure_ad_token_provider |
api_key |
api_version=... |
完全に削除 |
クリーンアップチェックリスト
- クライアント構築から
api_version引数を削除する。 .env、アプリ設定、Bicep/インフラファイルからAZURE_OPENAI_VERSION/AZURE_OPENAI_API_VERSION環境変数を削除する。.env、アプリ設定、Bicep/インフラ、テストフィクスチャでAZURE_OPENAI_CLIENT_IDをAZURE_CLIENT_IDに名前変更する(標準的な Azure Identity SDK の慣例)。requirements.txtまたはpyproject.tomlにopenai>=1.108.1を確保する。
環境変数移行
| 旧環境変数 | アクション | 備考 |
|---|---|---|
AZURE_OPENAI_VERSION |
削除 | v1 エンドポイントでは api_version 不要 |
AZURE_OPENAI_API_VERSION |
削除 | 上と同じ |
AZURE_OPENAI_CLIENT_ID |
名前変更 → AZURE_CLIENT_ID |
ManagedIdentityCredential(client_id=...) 用の標準慣例 |
AZURE_OPENAI_ENDPOINT |
保持 | base_url 構築にまだ必要 |
AZURE_OPENAI_CHAT_DEPLOYMENT |
保持 | responses.create の model パラメーターとして使用 |
AZURE_OPENAI_API_KEY |
保持 | キーベース認証の api_key として使用 |
クライアント設定コード例(同期、非同期、EntraID、APIキー、多テナント)は cheat-sheet.md を参照してください。
ステップ 1: レガシー呼び出し箇所の検出
移行が必要なすべての呼び出し箇所を見つけるために detect_legacy.py スクリプトを実行してください:
python skills/azure-openai-to-responses/scripts/detect_legacy.py .
または手動で次の検索を実行してください — マッチしたすべてが移行対象です:
# レガシーAPI呼び出し(書き換えが必要)
rg "chat\.completions\.create"
rg "ChatCompletion\.create"
rg "Completion\.create"
# 廃止予定のAzureクライアントコンストラクター(置き換えが必要)
rg "AzureOpenAI\("
rg "AsyncAzureOpenAI\("
# レスポンス形状アクセスパターン(更新が必要)
rg "choices\[0\]\.message\.content"
rg "choices\[0\]\.delta\.content"
rg "choices\[0\]\.message\.function_call"
rg "choices\[0\]\.message\.tool_calls"
# 古いネスト形式のツール定義(フラット化が必要)
rg '"function":\s*{\s*"name"'
rg "pydantic_function_tool"
# 古い形式のツール結果(function_call_outputへの変換が必要)
rg '"role":\s*"tool"'
rg '"tool_call_id"'
# 廃止予定のパラメーター(削除または名前変更が必要)
rg "response_format"
rg "max_tokens\b" # max_output_tokensに名前変更
rg "['\"]seed['\"]" # remove entirely
# 廃止予定の環境変数(整理が必要)
rg "AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION"
rg "AZURE_OPENAI_CLIENT_ID" # AZURE_CLIENT_IDであるべき
# GitHubモデルエンドポイント(削除が必要 — Responses APIは未対応)
rg "models\.github\.ai|models\.inference\.ai\.azure"
# フレームワークレベルのレガシーパターン(更新が必要)
rg "OpenAIChatCompletionClient" # MAF 1.0.0以降: OpenAIChatClientに置き換え
rg "ChatOpenAI\(" | grep -v "use_responses_api" # LangChain: use_responses_api=Trueが必要
# テスト基盤(更新が必要)
rg "ChatCompletionChunk|AsyncCompletions\.create" tests/
rg "_azure_ad_token_provider" tests/
rg "prompt_filter_results|content_filter_results" tests/
rg "choices\[0\]" tests/
# コンテンツフィルターエラーの本文アクセス(更新が必要 — 構造が変更)
rg 'innererror.*content_filter_result|error\.body\["innererror"\]'
rg "content_filter_result\[" # 古い単数形 — 現在はcontent_filters配列内のcontent_filter_results(複数形)
# Chat Completionsエンドポイントへの生のHTTP呼び出し(URLの更新が必要)
rg "/openai/deployments/.*/chat/completions"
rg "api-version="
ヒューリスティクス(検出と書き換え)
Chat Completions クライアント:
client.chat.completions.create→client.responses.create(...)。Azure クライアントコンストラクター:
AzureOpenAI(...)→OpenAI(base_url=..., api_key=...)。ツール: 関数呼び出しツールの定義をネスト形式(
{"type": "function", "function": {"name": ...}})からフラットな Responses 形式({"type": "function", "name": ...})に変換する;tool_choiceを使用する;ツール結果は{"type": "function_call_output", "call_id": ..., "output": ...}アイテムとして返す({"role": "tool", ...}ではない)。ツールの往復処理: モデルが関数呼び出しを返す場合、会話に
response.outputアイテムを追加する(手動で{"role": "assistant", "tool_calls": [...]}辞書を追加しない)、次に各結果に対してfunction_call_outputアイテムを追加する。数ショットのツール例: 会話にハードコードされたツール呼び出し例が含まれる場合、これらを
{"type": "function_call", "id": "fc_...", "call_id": "fc_...", ...}+{"type": "function_call_output", ...}アイテムに変換する。IDは必ずfc_で始まる必要がある。pydantic_function_tool(): このヘルパーはまだ旧来のネスト形式を生成し、responses.create()と互換性が ありません。手動ツール定義かフラット化ラッパーに置き換えること。マルチターン: 会話履歴はアプリ内で管理し、過去のターンは
inputアイテムとして渡す。フォーマット: Chat のトップレベル
response_formatを Responses のtext.formatに置き換える。正式な形状はtext={"format": {"type": "json_schema", "name": "Output", "strict": True, "schema": {...}}}。コンテンツアイテム: Chat の
content[].type: "text"は Responses のcontent[].type: "input_text"に置き換える(ユーザー/システムのターン)。画像コンテンツアイテム: Chat の
content[].type: "image_url"は Responses のcontent[].type: "input_image"に置き換える。image_urlフィールドはネストオブジェクト{"url": "..."}からフラットな文字列に変更される。前後の例はチートシート参照。推論努力: 元のコードですでに
reasoningが存在する場合のみ移行する。コンテンツフィルターエラー処理: エラーボディ構造が変更された。Chat Completions は
error.body["innererror"]["content_filter_result"](単数)を使用していたが、Responses API ではerror.body["content_filters"][0]["content_filter_results"](複数、配列内)となる。innererrorにアクセスするコードはKeyErrorを引き起こす。新しいパスを使うよう書き換えが必要。生の HTTP コール: アプリが Azure OpenAI REST API を直接(
requests,httpxなどで)/openai/deployments/{name}/chat/completions?api-version=...経由で呼び出している場合は/openai/v1/responsesに書き換える。リクエストボディはmessages→input、max_output_tokensとstore: falseを追加、クエリパラメータのapi-versionを削除。レスポンスボディはchoices[0].message.content→output[0].content[0].textに変更(注意:output_textは SDK の便宜的プロパティで生の REST JSON には存在しない)。
ステップ 2: 移行の適用
移行ノート(Chat Completions → Responses)
- なぜ移行するのか: Responses はテキスト、ツール、ストリーミングの統合 API であり、Chat Completions はレガシー。GPT-5 以降は最高性能のために Responses が必須。
- HTTP: Azure エンドポイントが
/openai/deployments/{name}/chat/completionsから/openai/v1/responsesに切り替わる。 - フィールド:
messages→input、max_tokens→max_output_tokens。temperatureは変更なし。 - フォーマット:
response_format→ 適切なオブジェクトのtext.format。 - コンテンツアイテム: Chat の
content[].type: "text"は Responses のcontent[].type: "input_text"に置換(システム/ユーザーターン)。 - 画像コンテンツアイテム: Chat の
content[].type: "image_url"は Responses のcontent[].type: "input_image"に置換。image_urlフィールドは{"image_url": {"url": "..."}}から{"image_url": "..."}(プレーンな文字列 — HTTPS URL またはdata:image/...;base64,...のデータ URI)にフラット化。
パラメーター対応表
| Chat Completions | Responses API |
|---|---|
prompt |
input |
messages |
input(配列) |
max_tokens |
max_output_tokens |
response_format |
text.format(オブジェクト) |
temperature |
temperature(変更なし) |
stop |
stop(変更なし) |
frequency_penalty |
frequency_penalty(変更なし) |
presence_penalty |
presence_penalty(変更なし) |
tools / 関数呼び出し |
tools(変更なし) |
seed |
削除(サポートなし) |
store |
store(false に設定) |
content[].type: "text" |
content[].type: "input_text" |
content[].type: "image_url" |
content[].type: "input_image" |
"image_url": {"url": "..."} |
"image_url": "..."(フラットな文字列) |
完全な前後のコード例は cheat-sheet.md を参照。
テスト基盤の移行(モック、スナップショット、アサーション)は test-migration.md を参照。
エラー対処や落とし穴は troubleshooting.md を参照。
データ保持と状態管理
- 全ての Responses リクエストに
store: falseを設定する。 - 以前のメッセージIDやサーバー保存のコンテキストに依存しない。状態はクライアント管理とし、メタデータを最小化する。
受け入れ基準
コードレベルのゲート(全て合格必須)
- 移行済みファイルで
rg "chat\.completions\.create|ChatCompletion\.create|Completion\.create"がゼロ。 -
rg "AzureOpenAI\(|AsyncAzureOpenAI\("がゼロ — すべてのコンストラクターは v1エンドポイントのOpenAI/AsyncOpenAIを使用。 -
rg "models\.github\.ai|models\.inference\.ai\.azure"がゼロ — GitHub Models のコードパスを削除。 -
rg "OpenAIChatCompletionClient"がゼロ — MAF 1.0.0+ のコードはOpenAIChatClient(Responses API 使用)。1.0.0未満はagent-framework-openai>=1.0.0にアップグレード。 - 全ての
ChatOpenAI(...)呼び出しにuse_responses_api=Trueが含まれる。 -
rg "choices\[0\]"がゼロ — 全レスポンスアクセスはresp.output_textまたは Responses 出力スキーマ使用。 - トップレベルに
response_formatがない;構造化出力はすべてtext={"format": {...}}を使用。 -
requirements.txtまたはpyproject.tomlにopenai>=1.108.1とazure-identityがある;依存関係を再インストール済み。 - すべての
responses.create呼び出しにstore=Falseが設定されている。 - クライアント構築に
api_versionがない;AZURE_OPENAI_API_VERSIONは環境ファイルやインフラから削除済み。
テスト基盤のゲート(全て合格必須)
-
rg "ChatCompletionChunk|AsyncCompletions\.create|chat\.completions" tests/がゼロ。 -
rg "_azure_ad_token_provider" tests/がゼロ — アサーションはisinstance(client, AsyncOpenAI)またはbase_urlを確認に更新済み。 -
rg "prompt_filter_results|content_filter_results" tests/がゼロ — Azure特有のフィルターモック削除。 - モックフィクスチャは
kwargs.get("input")を使用し、kwargs.get("messages")ではない。 - スナップショット/ゴールデンファイルは Responses ストリーミング形状に更新済み(
choices[0],function_call,logprobsなどなし)。 -
pytestは全テスト更新後に失敗ゼロで通過。
動作ゲート(手動またはテストハーネスで検証)
- 基本的な完了: 非ストリーミングの
responses.createが空でないoutput_textを返す。 - ストリームの同等性: 元コードがストリーミングを使っていた場合、移行コードもストリーミングし、非空のデルタを含む
response.output_text.deltaイベントを生成する。 - 構造化出力:
text.formatでjson_schemaを使う場合、json.loads(resp.output_text)が成功し、スキーマに合致する。 - ツール呼び出しループ: ツール使用時は、モデルがツール呼び出しを発行し、アプリが実行し、後続リクエストが最終的な
output_textを返す(無限ループなし)。 - 非同期の同等性:
AsyncAzureOpenAI使用時はAsyncOpenAIの等価物がawaitで動作する。 - エラー率: 移行前ベースラインと比較して新しい 400/401/404 エラーなし。
納品物
- 編集したファイル一覧、レガシー呼び出し箇所の移行前後の件数、次のステップを含むサマリー。
- 変更は作業ツリー編集のみ(コミットなし)。
SDK バージョン要件
| パッケージ | 最低バージョン |
|---|---|
openai |
>=1.108.1 |
azure-identity |
最新版(EntraID 認証用) |
参考資料
- チートシート — 全コードスニペット
- テスト移行 — モック、スナップショット、アサーション
- トラブルシューティング — エラー、リスク表、注意点
- detect_legacy.py — 自動スキャナー
- Azure OpenAI スターターキット
- Azure OpenAI Responses API ドキュメント
- Azure OpenAI API バージョンライフサイクル
- OpenAI Responses API リファレンス
免責事項: 本書類は AI 翻訳サービス Co-op Translator を使用して翻訳されています。正確性を期していますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知おきください。原文の原語版が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の利用により生じたいかなる誤解や解釈違いについても、当方は責任を負いかねます。
Source: microsoft/ai-agents-for-beginners → translations/ja/.agents/skills/azure-openai-to-responses/SKILL.md