microsoft/ai-agents-for-beginners-.agents-azure-openai-to-responses
Ilipat ang mga Python app mula sa Azure OpenAI Chat Completions papuntang Responses API. Saklaw nito ang pag-migrate ng AzureOpenAI/AsyncAzureOpenAI client sa v1 endpoint, streaming, tools, structured output, multi-turn, EntraID auth, at mga pagsusuri sa compatibility ng modelo. Nakatuon sa Python, para sa Azure OpenAI. openai responses, pag-upgrade ng openai SDK, migration sa responses API, paglipat mula completions sa responses, gpt-5 migration, azure openai python migration, chat completions papuntang responses, AzureOpenAI papuntang OpenAI client, python azure (simulan direkta sa responses), Node/TypeScript/C#/Java/Go migrations (Python lang ang kasanayang ito), Azure infrastructure setup (gumamit ng azure-prepare), pag-deploy ng mga modelo (gumamit ng microsoft-foundry).'
npx skills add https://github.com/microsoft/ai-agents-for-beginners --skill azure-openai-to-responses
> 權威指南 — 請嚴格遵循
>
> 本技能將使用 Azure OpenAI Chat Completions 的 Python 代碼庫
> 遷移到統一的 Responses API。請精確遵循這些指令。
> 不得自行即興映射參數或創建 API 形態。
當用戶想要:
AzureOpenAI / AsyncAzureOpenAI 切換到使用標準的 OpenAI / AsyncOpenAI 客戶端,搭配 v1 端點AzureOpenAI 建構子或 api_version 相關的棄用警告> 遷移前,請確認您的 Azure OpenAI 部署支援 Responses API。
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}")
> <strong>注意</strong>:Azure OpenAI 上 max_output_tokens 的<strong>最小值為 16</strong>。低於 16 的值會回傳 400 錯誤。用 50 以上進行快速測試。
如果回傳 404,表示該部署的模型尚不支援 Responses,請參考下方參考資料或用支援的模型重新部署。
執行內建模型相容性工具,查看您所在區域有哪些模型支援 Responses API:
python migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION
該指令會向 Azure ARM 實時查詢並顯示相容性矩陣 — 包含支援 Responses、結構化輸出、工具等的模型。可用 --filter gpt-5.1,gpt-5.2 篩選結果,或用 --json 做腳本化處理。
python migrate.py models(參見上方 — 區域特定,且始終保持最新)> <strong>警告</strong>:早期模型(gpt-4.1 之前的版本)可能無法完整支援所有 Responses API 功能。
>
> 已知的舊版模型限制:
> - reasoning 參數:許多非推理模型不支援。如原始程式碼未使用,勿遷移 reasoning。
> - seed 參數:Responses API 完全不支援,請從所有請求中移除。
> - 透過 text.format 使用結構化輸出:舊版模型可能無法可靠執行 strict: true 的 JSON schema 驗證。
> - <strong>工具協調</strong>:GPT-5+ 將工具呼叫整合於推理過程中,舊模型的 Responses 支援仍有效,但缺乏深度整合。
> - <strong>溫度限制</strong>:遷移到 gpt-5 時,溫度參數必須省略或設定為 1。舊模型沒有此限制。
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 系列模型。response.output_text.delta 可能比 GPT 模型出現得晚。top_p:O 系列不支援,若出現請移除。行動 — 前瞻性模型建議:掃描階段檢查應用目標模型(部署名稱、環境變數、配置)。若模型早於 gpt-4.1(非 gpt-4.1+),請主動告知用戶:
gpt-5.1、gpt-5.2)提供更完善的工具協調、結構化輸出強制、推理與跨區域可用性。不應依模型版本阻擋或拒絕執行遷移,此建議僅供參考資訊。
> GitHub Models (models.github.ai, models.inference.ai.azure.com) 不支援 Responses API。
若代碼庫含有 GitHub Models 程式碼路徑(尋找 base_url 指向 models.github.ai 或 models.inference.ai.azure.com),遷移時<strong>必須完全移除</strong>。Responses API 需 Azure OpenAI、OpenAI 或相容本機端點(如支持 Responses 的 Ollama)。
掃描階段行動:
許多應用使用 OpenAI 之上高階框架。遷移這些時,框架的 API 也會改變 — 不僅是底層的 OpenAI 調用。
先檢查您的 MAF 版本 — 遷移作業依賴您使用的是 MAF 1.0.0+ 還是 1.0.0 以前的 beta/rc 版。
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__)"
1.0.0 以前的 MAF 中,OpenAIChatClient 仍使用 Chat Completions。請升級至 agent-framework-openai>=1.0.0,改用預設的 Responses API。
無需其他變更 — Agent 與工具 API 保持不變。
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。前端若遇到:
<!-- 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/[email protected]/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。git add / git commit / git push;僅產生工作樹修改。若代碼庫使用 AzureOpenAI 或 AsyncAzureOpenAI 建構子,請先遷移到標準 OpenAI / AsyncOpenAI 建構子。Azure 專用建構子在 openai>=1.108.1 已棄用。
新的 /openai/v1 端點使用標準的 OpenAI() 客戶端,非 AzureOpenAI(),無需 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 | <strong>移除</strong> | v1 端點不需 api_version |
| AZURE_OPENAI_API_VERSION | <strong>移除</strong> | 同上 |
| AZURE_OPENAI_CLIENT_ID | <strong>改名</strong> → AZURE_CLIENT_ID | 用於 ManagedIdentityCredential(client_id=...),符合 Azure Identity SDK 慣例 |
| AZURE_OPENAI_ENDPOINT | <strong>保留</strong> | 用於建構 base_url |
| AZURE_OPENAI_CHAT_DEPLOYMENT | <strong>保留</strong> | 用於 responses.create 的 model 參數 |
| AZURE_OPENAI_API_KEY | <strong>保留</strong> | 用於基於金鑰的認證 api_key |
更多客戶端設定代碼範例(同步、非同步、EntraID、API 金鑰、多租戶),請參閱 cheat-sheet.md。
執行 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 Models 端點(必須移除 — 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="
client.chat.completions.create → client.responses.create(...)。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": [...]} dict),接著為每個結果附加 function_call_output 項目。{"type": "function_call", "id": "fc_...", "call_id": "fc_...", ...} + {"type": "function_call_output", ...} 項目。ID 必須以 fc_ 開頭。pydantic_function_tool()<strong>:此幫助函式仍產生舊的巢狀格式,且</strong>不相容於 responses.create()。請改用手動工具定義或平鋪的包裝器替代。input 項目傳遞先前回合。response_format 替換成 Responses 的 text.format。標準格式為:text={"format": {"type": "json_schema", "name": "Output", "strict": True, "schema": {...}}}。content[].type: "text" 替換為 Responses content[].type: "input_text"(適用於用戶/系統回合)。content[].type: "image_url" 替換為 Responses content[].type: "input_image"。image_url 欄位由巢狀物件 {"url": "..."} 改為平面字串。請參考備忘單了解前後範例。reasoning 時才遷移。error.body["innererror"]["content_filter_result"](單數);Responses API 使用 error.body["content_filters"][0]["content_filter_results"](複數且在陣列中)。存取 innererror 的程式碼會引發 KeyError,需改寫為新路徑。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 不存在)。/openai/deployments/{name}/chat/completions 換到 /openai/v1/responses。messages → input,max_tokens → max_output_tokens。temperature 保持不變。response_format → 用正確物件的 text.format。content[].type: "text" 替換為 Responses 的 content[].type: "input_text"。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 | <strong>移除</strong>(不支援) |
| 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。
store: false。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" 匹配。rg "_azure_ad_token_provider" 匹配 — 斷言改為檢查 isinstance(client, AsyncOpenAI) 或 base_url。rg "prompt_filter_results|content_filter_results" 匹配 — 移除 Azure 特定過濾模擬。kwargs.get("input") 而非 kwargs.get("messages")。choices[0]、function_call、logprobs 等)。pytest 輸出零失敗。responses.create 回傳非空 output_text。response.output_text.delta 事件。json_schema 的 text.format,json.loads(resp.output_text) 成功且符合 schema。output_text(無無限迴圈)。AsyncAzureOpenAI,遷移後 AsyncOpenAI 等效且可用 await。| 套件 | 最低版本 |
|---------|----------------|
| openai | >=1.108.1 |
| azure-identity | 最新版(用於 EntraID 認證) |
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
免責聲明:
此文件已使用 AI 翻譯服務 Co-op Translator 進行翻譯。雖然我們努力追求準確性,但請注意自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應視為權威來源。對於關鍵資訊,建議採用專業人工翻譯。我們不對因使用此翻譯所產生的任何誤解或誤譯承擔責任。
<!-- CO-OP TRANSLATOR DISCLAIMER END -->
Take microsoft/ai-agents-for-beginners-.agents-azure-openai-to-responses from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.