Skill v1.0.0
currentTrusted Publisher100/100version: "1.0.0" name: azure-openai-to-responses description: >- Migrate Python apps from Azure OpenAI Chat Completions to the Responses API. Covers AzureOpenAI/AsyncAzureOpenAI client migration to the v1 endpoint, streaming, tools, structured output, multi-turn, EntraID auth, and model compatibility checks. Python-focused, Azure OpenAI-specific. USE FOR: migrate to responses API, switch from chat completions, openai responses, upgrade openai SDK, responses API migration, move from completions to responses, gpt-5 migration, azure openai python migration, chat completions to responses, AzureOpenAI to OpenAI client, python azure openai upgrade. DO NOT USE FOR: building new apps from scratch (start with responses directly), Node/TypeScript/C#/Java/Go migrations (this skill is Python-only), Azure infrastructure setup (use azure-prepare), deploying models (use microsoft-foundry). license: MIT source: https://github.com/Azure-Samples/azure-openai-to-responses
Migrate Python Apps from Azure OpenAI Chat Completions to Responses API
AUTHORITATIVE GUIDANCE — FOLLOW EXACTLYThis skill migrates Python codebases using Azure OpenAI Chat Completionsto the unified Responses API. Follow these instructions precisely.Do not improvise parameter mappings or invent API shapes.
Installed from Azure-Samples/azure-openai-to-responses (MIT).
Triggers
Activate this skill when the user wants to:
- Migrate a Python app from Azure OpenAI Chat Completions to Responses API
- Upgrade Python OpenAI SDK usage to the latest API shape against Azure OpenAI
- Prepare Python code for GPT-5 or newer models that require Responses on Azure
- Switch from
AzureOpenAI/AsyncAzureOpenAIto standardOpenAI/AsyncOpenAIclient with the v1 endpoint - Fix deprecation warnings related to
AzureOpenAIconstructors orapi_version
Why migrate
GPT-5 and newer models require the Responses API. The new /openai/v1/ endpoint uses the standard OpenAI() client instead of AzureOpenAI(), requires no api_version parameter, and works identically across OpenAI and Azure OpenAI.
What changes
| Chat Completions (before) | Responses API (after) | |
|---|---|---|
AzureOpenAI() / AsyncAzureOpenAI() | OpenAI(base_url=...) / AsyncOpenAI(base_url=...) | |
azure_endpoint=... | base_url=f"{endpoint.rstrip('/')}/openai/v1/" | |
api_version="2024-..." | Remove entirely — /openai/v1/ is stable | |
azure_ad_token_provider=... | api_key=token_provider | |
client.chat.completions.create(messages=...) | client.responses.create(input=...) | |
resp.choices[0].message.content | resp.output_text | |
max_tokens | max_output_tokens (min 16 on Azure) | |
response_format | text={"format": {...}} | |
seed | Remove (not supported) | |
tools nested {"type":"function","function":{...}} | flat {"type":"function","name":...} | |
tool result {"role":"tool","tool_call_id":...} | {"type":"function_call_output","call_id":...,"output":...} | |
content[].type: "text" | content[].type: "input_text" | |
content[].type: "image_url" + {"url": "..."} | content[].type: "input_image" + flat "image_url": "..." | |
streaming chunk.choices[0].delta.content | event.type == "response.output_text.delta" → event.delta |
Model compatibility — CHECK FIRST
Verify the deployed model supports the Responses API before migrating. GPT-4o and GPT-4 support Responses for basic text/chat/streaming/tools but not all features. Newer models (gpt-4.1+, gpt-5.x) have full support. GitHub Models (`models.github.ai`, `models.inference.ai.azure.com`) do NOT support the Responses API — remove those code paths and switch to Azure OpenAI, OpenAI, or a compatible local endpoint.
Smoke test:
import osfrom openai import OpenAIclient = OpenAI(api_key=os.environ["AZURE_OPENAI_API_KEY"],base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",)resp = client.responses.create(model=os.environ["AZURE_OPENAI_DEPLOYMENT"],input="ping",max_output_tokens=50,store=False,)print(resp.output_text)
Step 0: Client migration (prerequisite)
AzureOpenAI/AsyncAzureOpenAI constructors are deprecated in openai>=1.108.1.
Before:
from openai import AzureOpenAIclient = AzureOpenAI(api_version=os.environ["AZURE_OPENAI_API_VERSION"],azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],api_key=os.environ["AZURE_OPENAI_API_KEY"],)
After:
from openai import OpenAIclient = OpenAI(api_key=os.environ["AZURE_OPENAI_API_KEY"],base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",)
Cleanup: remove api_version args, remove AZURE_OPENAI_API_VERSION / AZURE_OPENAI_VERSION from .env/infra, rename AZURE_OPENAI_CLIENT_ID → AZURE_CLIENT_ID, ensure openai>=1.108.1.
Step 1: Detect legacy call sites
rg "chat\.completions\.create" # legacy API callsrg "ChatCompletion\.create|Completion\.create"rg "AzureOpenAI\(|AsyncAzureOpenAI\(" # deprecated constructorsrg "choices\[0\]\.message\.content" # response accessrg "choices\[0\]\.delta\.content" # streaming accessrg "max_tokens\b" # rename to max_output_tokensrg "['\"]seed['\"]" # remove entirelyrg "response_format" # → text.formatrg "AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION"rg "models\.github\.ai|models\.inference\.ai\.azure" # GitHub Models: remove
Step 2: Apply migration
client.chat.completions.create(messages=...)→client.responses.create(input=...)resp.choices[0].message.content→resp.output_textmax_tokens→max_output_tokens(min 16); removeseedresponse_format→text={"format": {"type": "json_schema", "name": "Output", "strict": True, "schema": {...}}}- Set
store=Falseon every request (client-managed state) - Streaming: iterate events, handle
event.type == "response.output_text.delta"(useevent.delta) andresponse.completed - Tools: flat format,
tool_choice, return results asfunction_call_outputitems; appendresponse.outputitems for round-trips - Multi-turn: maintain conversation in an
inputarray, or useprevious_response_id(requiresstore=True) - Reasoning models (o-series, GPT-5):
max_completion_tokens→max_output_tokens(4096+),reasoning_effort→reasoning={"effort": ...}, omittemperature/top_p(GPT-5 rejectstemperatureoutright; to vary output use a non-reasoning model likeLlama-3.3-70B-Instructvia Foundry Models)
Acceptance criteria (all must pass)
- Zero matches for
chat.completions.create|ChatCompletion.create|Completion.create - Zero matches for
AzureOpenAI(|AsyncAzureOpenAI(— all useOpenAI/AsyncOpenAI+ v1 endpoint - Zero matches for
models.github.ai|models.inference.ai.azure - Zero matches for
choices[0]— all access usesresp.output_text/ Responses schema - No top-level
response_format; structured output usestext={"format": {...}} openai>=1.108.1in requirements;store=Falseon every call; noapi_versionin client construction- Tests updated (mocks use
kwargs.get("input"), snapshots use Responses shape);pytestpasses
See references/cheat-sheet.md for complete before/after code examples.