[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699XJ5Y3B2S6KTXS02M3XWD":3,"skill-same:01M699XJ5Y3B2S6KTXS02M3XWD":62},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":29,"ownerHtmlUrl":30,"ownerBlogUrl":31,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M699XJ5Y3B2S6KTXS02M3XWD","azure-openai-to-responses",null,"microsoft\u002Fai-agents-for-beginners","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M6998ZK2275KMJE6Y5SEA2X2",79423,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fth\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002FSKILL.md",[],[18],"azure openai to responses","2026-11-10 10:12:30",false,"---\nname: azure-openai-to-responses\nlicense: MIT\n---\n# ย้ายแอป Python จาก Azure OpenAI Chat Completions ไปยัง Responses API\n\n> **คำแนะนำอย่างเป็นทางการ — ทำตามอย่างเคร่งครัด**\n>\n> ทักษะนี้จะย้ายฐานโค้ด Python ที่ใช้ Azure OpenAI Chat Completions\n> ไปยัง Responses API แบบรวมศูนย์ โปรดทำตามคำแนะนำเหล่านี้อย่างแม่นยำ\n> หลีกเลี่ยงการปรับแม็ปพารามิเตอร์เองหรือคิดค้นรูปแบบ API ใหม่\n\n---\n\n## ตัวจุดเริ่มต้น\n\nเปิดใช้งานทักษะนี้เมื่อผู้ใช้ต้องการ:\n- ย้ายแอป Python จาก Azure OpenAI Chat Completions ไปยัง Responses API\n- อัพเกรดการใช้งาน Python OpenAI SDK ไปยังรูปแบบ API ล่าสุดกับ Azure OpenAI\n- เตรียมโค้ด Python สำหรับโมเดล GPT-5 หรือใหม่กว่าที่ต้องการ Responses บน Azure\n- เปลี่ยนจากไคลเอนต์ `AzureOpenAI`\u002F`AsyncAzureOpenAI` เป็น `OpenAI`\u002F`AsyncOpenAI` แบบมาตรฐานที่ใช้ปลายทาง v1\n- แก้ไขคำเตือนการเลิกใช้ที่เกี่ยวกับตัวสร้าง `AzureOpenAI` หรือ `api_version`\n\n---\n\n## ⚠️ ความเข้ากันได้ของโมเดล — ตรวจสอบก่อน\n\n> **ก่อนย้าย ตรวจสอบให้แน่ใจว่า deployment Azure OpenAI ของคุณรองรับ Responses API**\n\n### 1. ทดสอบอย่างรวดเร็ว (เร็วที่สุด)\n\n```python\nimport os\nfrom openai import OpenAI\n\nclient = OpenAI(\n    api_key=os.environ[\"AZURE_OPENAI_API_KEY\"],\n    base_url=f\"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('\u002F')}\u002Fopenai\u002Fv1\u002F\",\n)\n\ntry:\n    resp = client.responses.create(\n        model=os.environ[\"AZURE_OPENAI_DEPLOYMENT\"],\n        input=\"ping\",\n        max_output_tokens=50,\n        store=False,\n    )\n    print(f\"✅ Deployment supports Responses API: {resp.output_text}\")\nexcept Exception as e:\n    print(f\"❌ Deployment does NOT support Responses API: {e}\")\n```\n\n> **หมายเหตุ**: บน Azure OpenAI `max_output_tokens` มีค่าขั้นต่ำ **16** ค่าที่ต่ำกว่า 16 จะส่งคืนข้อผิดพลาด 400 ใช้ค่า 50+ สำหรับการทดสอบแบบรวดเร็ว\n\nหากส่งคืน 404 โมเดลใน deployment นี้ยังไม่รองรับ Responses — ตรวจสอบข้อมูลอ้างอิงด้านล่างหรือเปิดใช้งานใหม่ด้วยโมเดลที่รองรับ\n\n### 2. ตรวจสอบโมเดลที่มีในภูมิภาคของคุณ (แนะนำ)\n\nใช้เครื่องมือรองรับโมเดลในตัวเพื่อดูว่ามีอะไรพร้อมใช้งานกับ Responses API ในภูมิภาคของคุณ:\n\n```bash\npython migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION\n```\n\nเครื่องมือนี้เรียก Azure ARM สดและแสดงแมทริกซ์ความเข้ากันได้ — โมเดลใดรองรับ Responses, การส่งออกแบบมีโครงสร้าง, เครื่องมือ ฯลฯ ใช้ `--filter gpt-5.1,gpt-5.2` เพื่อลดผลลัพธ์หรือ `--json` สำหรับสคริปต์\n\n### 3. อ้างอิงการรองรับโมเดลเต็มรูปแบบ\n\n- **การเรียกดูสด**: `python migrate.py models` (ดูด้านบน — เฉพาะภูมิภาค, อัปเดตเสมอ)\n- **เรียกดูความพร้อมใช้งาน**: [ตารางสรุปโมเดลและความพร้อมใช้งานในภูมิภาค](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Ffoundry\u002Ffoundry-models\u002Fconcepts\u002Fmodels-sold-directly-by-azure?tabs=global-standard-aoai%2Cglobal-standard&pivots=azure-openai#model-summary-table-and-region-availability)\n- **เริ่มต้นใช้งานและคำแนะนำ**: **https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart**\n\n### ⚠️ ข้อจำกัดของโมเดลเก่า\n\n> **คำเตือน**: โมเดลเก่า (ก่อน `gpt-4.1`) อาจไม่รองรับฟีเจอร์ Responses API ทุกอย่างอย่างเต็มที่\n>\n> จำกัดการใช้งานที่ทราบกับโมเดลเก่า:\n> - **พารามิเตอร์ `reasoning`**: ไม่รองรับในหลายโมเดลที่ไม่มี reasoning หากจะย้ายให้ย้ายเฉพาะกรณีที่มี `reasoning` อยู่แล้วในโค้ดต้นทาง\n> - **พารามิเตอร์ `seed`**: ไม่รองรับใน Responses API เลย — ลบออกจากคำขอทั้งหมด\n> - **ผลลัพธ์แบบมีโครงสร้างผ่าน `text.format`**: โมเดลเก่าอาจไม่บังคับใช้สคีมา JSON แบบ `strict: true` ได้อย่างน่าเชื่อถือ\n> - **การประสานเครื่องมือ**: GPT-5+ จัดการการเรียกเครื่องมือเป็นส่วนหนึ่งของ reasoning ภายใน โมเดลเก่าบน Responses ยังใช้งานได้แต่ไม่มีการรวมลึกนี้\n> - **ข้อจำกัดอุณหภูมิ**: เมื่อย้ายไป `gpt-5` อุณหภูมิต้องไม่กำหนดหรือกำหนดเป็น `1` โมเดลเก่าไม่มีข้อจำกัดนี้\n\n### โมเดล reasoning ซีรีส์ O (o1, o3-mini, o3, o4-mini)\n\nโมเดลซีรีส์ O มีข้อจำกัดพารามิเตอร์เฉพาะตัว เมื่อย้ายแอปที่มุ่งเป้าไปยังโมเดลซีรีส์ O:\n\n- **`temperature`**: ต้องเป็น `1` (หรือละเว้น) โมเดลซีรีส์ O ไม่รับค่าที่ต่างจากนี้\n- **`max_completion_tokens` → `max_output_tokens`**: แอปที่ใช้ `max_completion_tokens` เฉพาะ Azure ต้องเปลี่ยนเป็น `max_output_tokens` ตั้งค่าสูง (4096+) เพราะโทเค็น reasoning นับในขีดจำกัดนี้\n- **`reasoning_effort`**: หากแอปใช้ `reasoning_effort` (ต่ำ\u002Fกลาง\u002Fสูง) ให้เก็บไว้ — Responses API รองรับพารามิเตอร์นี้สำหรับโมเดลซีรีส์ O\n- **พฤติกรรมการสตรีม**: โมเดลซีรีส์ O อาจเก็บบัฟเฟอร์ผลลัพธ์จน reasoning เสร็จก่อนส่งเหตุการณ์ delta ข้อความ การสตรีมยังทำงาน แต่ delta แรกอาจช้ากว่าโมเดล GPT\n- **`top_p`**: ไม่รองรับในซีรีส์ O — ให้ลบออกหากมี\n- **การใช้เครื่องมือ**: โมเดลซีรีส์ O รองรับเครื่องมือผ่าน Responses API เช่นเดียวกับโมเดล GPT แต่คุณภาพการประสานการเรียกเครื่องมือขึ้นกับแต่ละโมเดล\n\n**คำแนะนำเชิงรุก — ระหว่างสแกน**: ตรวจสอบว่าแอปใช้โมเดลใด (ชื่อ deployment, ตัวแปรสภาพแวดล้อม, การตั้งค่า) หากเป็นโมเดลก่อน `gpt-4.1` (ไม่ใช่ gpt-4.1+) แจ้งผู้ใช้ล่วงหน้า:\n- การย้ายจะทำงานกับข้อความพื้นฐาน แชท การสตรีม และเครื่องมือบนโมเดลปัจจุบันได้\n- โมเดลใหม่กว่า (`gpt-5.1`, `gpt-5.2`) ให้การประสานเครื่องมือที่ดีกว่า การบังคับใช้ผลลัพธ์แบบมีโครงสร้าง reasoning และความพร้อมใช้งานข้ามภูมิภาค\n- ควรพิจารณาอัปเกรด deployment เมื่อพร้อม — ไม่มีผลขัดขวางการย้ายตอนนี้\n\nหลีกเลี่ยงการบล็อกหรือปฏิเสธให้ย้ายตามเวอร์ชันโมเดล คำแนะนำนี้เป็นข้อมูลเท่านั้น\n\n### GitHub Models ไม่รองรับ Responses API\n\n> **GitHub Models (`models.github.ai`, `models.inference.ai.azure.com`) ไม่รองรับ Responses API**\n\nหากฐานโค้ดมีเส้นทางโค้ด GitHub Models (ดูที่ `base_url` ชี้ไปยัง `models.github.ai` หรือ `models.inference.ai.azure.com`) **ให้ลบออกทั้งหมด** ในการย้าย Responses API ต้องใช้ Azure OpenAI, OpenAI หรือปลายทางในเครื่องที่เข้ากันได้ (เช่น Ollama ที่รองรับ Responses)\n\nการดำเนินการระหว่างสแกน:\n- ให้ติดธงเส้นทางโค้ด GitHub Models เพื่อการลบ\n\n---\n\n## การย้ายเฟรมเวิร์ก\n\nแอปหลายแอปใช้เฟรมเวิร์กระดับสูงบน OpenAI เมื่อย้ายเฟรมเวิร์กเหล่านี้ จะมีการเปลี่ยนแปลง API เฟรมเวิร์กเอง — ไม่ใช่แค่การเรียก OpenAI ขั้นต่ำ\n\n### Microsoft Agent Framework (MAF)\n\n**ตรวจสอบเวอร์ชัน MAF ของคุณก่อน** — การย้ายขึ้นกับว่าคุณใช้ MAF 1.0.0+ หรือเบต้า\u002Frc ก่อน 1.0.0\n\n#### MAF 1.0.0+ (agent-framework-openai >= 1.0.0)\n\n`OpenAIChatClient` **ใช้ Responses API แล้ว** — ไม่ต้องย้าย หากฐานโค้ดยังใช้ `OpenAIChatCompletionClient` แบบเก่า (ที่ใช้ `chat.completions.create`) ให้เปลี่ยนเป็น `OpenAIChatClient`\n\n| ก่อน | หลัง |\n|--------|-------|\n| `from agent_framework.openai import OpenAIChatCompletionClient` | `from agent_framework.openai import OpenAIChatClient` |\n| `OpenAIChatCompletionClient(...)` | `OpenAIChatClient(...)` |\n\nตรวจสอบเวอร์ชันของคุณด้วย: `python -c \"import agent_framework_openai; print(agent_framework_openai.__version__)\"`\n\n#### MAF ก่อน 1.0.0 (รุ่นเบต้า\u002Frc)\n\nใน MAF ก่อน 1.0.0 `OpenAIChatClient` ใช้ Chat Completions อัพเกรดเป็น `agent-framework-openai>=1.0.0` ซึ่ง `OpenAIChatClient` ใช้ Responses API โดยดีฟอลต์\n\nไม่มีการเปลี่ยนแปลงอื่น — API ของ `Agent` และเครื่องมือเหมือนเดิม\n\n### LangChain (`langchain-openai`)\n\nเพิ่ม `use_responses_api=True` ให้กับ `ChatOpenAI()` และอัพเดตการเข้าถึงผลลัพธ์จาก `.content` เป็น `.text`\n\n| ก่อน | หลัง |\n|--------|-------|\n| `ChatOpenAI(model=..., base_url=..., api_key=...)` | `ChatOpenAI(model=..., base_url=..., api_key=..., use_responses_api=True)` |\n| `result['messages'][-1].content` | `result['messages'][-1].text` |\n\nดูตัวอย่างโค้ดทั้งก่อนและหลังใน [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md)\n\n---\n\n## คำแนะนำการย้ายส่วนหน้า\n\n> **Responses API เป็นเรื่องฝั่งเซิร์ฟเวอร์** ย้าย backend Python ของคุณ ส่วนหน้า (frontend) ควรยังคงตามสัญญา HTTP เดิมเว้นแต่ว่า backend เป็นเพียงชั้นผ่านบาง ๆ — กรณีนั้นให้พิจารณาใช้รูปแบบคำขอ Responses เพื่อกำจัดชั้นแปลง หาก frontend เรียก OpenAI โดยตรงด้วยคีย์ฝั่งไคลเอนต์ ให้ย้ายการเรียกเหล่านั้นไป backend ก่อน\n\n### การเลิกใช้งาน `@microsoft\u002Fai-chat-protocol`\n\nแพ็กเกจ npm `@microsoft\u002Fai-chat-protocol` ถูกเลิกใช้และควรเปลี่ยนเป็น [`ndjson-readablestream`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fndjson-readablestream) หากพบในส่วนหน้า:\n\n1. แก้แท็กสคริปต์ CDN:\n   ```html\n   \u003C!-- Before -->\n   \u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@microsoft\u002Fai-chat-protocol@...\u002Fdist\u002Fiife\u002Findex.js\">\u003C\u002Fscript>\n   \u003C!-- After -->\n   \u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fndjson-readablestream@1.0.7\u002Fdist\u002Fndjson-readablestream.umd.js\">\u003C\u002Fscript>\n   ```\n2. ลบการสร้างอินสแตนซ์ `AIChatProtocolClient` (`new ChatProtocol.AIChatProtocolClient(\"\u002Fchat\")`)\n3. เปลี่ยน `client.getStreamedCompletion(messages)` เป็นเรียก `fetch()` ตรงไปยังจุดสตรีมของ backend\n4. เปลี่ยน `for await (const response of result)` เป็น `for await (const chunk of readNDJSONStream(response.body))`\n5. ปรับเปลี่ยนการเข้าถึงคุณสมบัติจาก `response.delta.content` \u002F `response.error` เป็น `chunk.delta.content` \u002F `chunk.error`\n\n---\n\n## เป้าหมาย\n\n- ระบุทุกจุดเรียก Python ที่ใช้ Chat Completions หรือ Completions แบบเก่าที่เรียกกับ Azure OpenAI\n- เสนอแผนการย้ายและลำดับขั้นสำหรับฐานโค้ด Python\n- ใช้การแก้ไขอย่างปลอดภัยและน้อยที่สุดเพื่อสลับไป Responses API\n- อัปเดตผู้เรียกเพื่อใช้สคีมาผลลัพธ์ของ Responses; ไม่มีหุ้มหลังความเข้ากันได้\n- รันการทดสอบ\u002Fตรวจสอบ; แก้ไขปัญหาเล็กน้อยที่เกิดจากการย้าย\n- เตรียมชุดการเปลี่ยนแปลงที่เล็กและตรวจสอบได้ พร้อมสรุปสุดท้ายพร้อมการเปรียบเทียบ (ไม่ต้อง commit)\n\n---\n\n## กฎข้อบังคับ\n\n- แก้ไขเฉพาะไฟล์ในพื้นที่ git เท่านั้น ห้ามเขียนนอกพื้นที่นี้\n- ไม่ต้องเก็บไว้ในช่องทางหลังความเข้ากันได้; ย้ายโค้ดไปยังรูปแบบ API ใหม่\n- หลีกเลี่ยงการทิ้งคอมเมนต์รอยตาย\u002Fเปลี่ยนผ่านหรือไฟล์สำรอง\n- รักษาลักษณะการสตรีมหากเคยใช้; มิฉะนั้นใช้แบบไม่สตรีม\n- ขออนุมัติก่อนรันคำสั่งหรือเรียกเครือข่ายถ้าอยู่ในโหมดอนุมัติ\n- หลีกเลี่ยงการรัน `git add`\u002F`git commit`\u002F`git push`; ผลลัพธ์ต้องเป็นใน working-tree เท่านั้น\n\n---\n\n## ขั้นตอนที่ 0: ย้ายไคลเอนต์ Azure OpenAI (เงื่อนไขเบื้องต้น)\n\nหากฐานโค้ดใช้ตัวสร้าง `AzureOpenAI` หรือ `AsyncAzureOpenAI` ให้ย้ายไปใช้ตัวสร้าง `OpenAI` \u002F `AsyncOpenAI` แบบมาตรฐานก่อน ตัวสร้างเฉพาะ Azure ถูกเลิกใช้ใน `openai>=1.108.1`\n\n### ทำไมต้องใช้ปลายทาง v1 API?\n\nปลายทางใหม่ `\u002Fopenai\u002Fv1` ใช้ไคลเอนต์ `OpenAI()` แบบมาตรฐานแทน `AzureOpenAI()` ไม่ต้องใช้พารามิเตอร์ `api_version` และทำงานเหมือนกันทั้ง OpenAI และ Azure OpenAI โค้ดไคลเอนต์เดียวกันนี้รองรับอนาคต — ไม่ต้องจัดการเวอร์ชัน\n\n### การเปลี่ยนแปลงสำคัญ\n\n| ก่อน | หลัง |\n|--------|-------|\n| `AzureOpenAI` | `OpenAI` |\n| `AsyncAzureOpenAI` | `AsyncOpenAI` |\n| `azure_endpoint` | `base_url` |\n| `azure_ad_token_provider` | `api_key` |\n| `api_version=...` | ลบทิ้งทั้งหมด |\n\n### รายการล้างข้อมูล\n\n- ลบอาร์กิวเมนต์ `api_version` จากการสร้างไคลเอนต์\n- ลบตัวแปรสภาพแวดล้อม `AZURE_OPENAI_VERSION` \u002F `AZURE_OPENAI_API_VERSION` จาก `.env`, การตั้งค่าแอป และไฟล์ Bicep\u002Fโครงสร้างพื้นฐาน\n- เปลี่ยนชื่อ `AZURE_OPENAI_CLIENT_ID` → `AZURE_CLIENT_ID` ใน `.env`, การตั้งค่าแอป, Bicep\u002Fโครงสร้างพื้นฐาน และไฟล์ตัวอย่างทดสอบ (ตามแนวทางมาตรฐาน Azure Identity SDK)\n- แน่ใจว่า `openai>=1.108.1` ใน `requirements.txt` หรือ `pyproject.toml`\n\n### ย้ายตัวแปรสภาพแวดล้อม\n\n| ตัวแปรสภาพแวดล้อมเดิม | การดำเนินการ | หมายเหตุ |\n|-------------|--------|-------|\n| `AZURE_OPENAI_VERSION` | **ลบ** | ไม่ต้องใช้ `api_version` กับปลายทาง v1 |\n| `AZURE_OPENAI_API_VERSION` | **ลบ** | เหมือนกันกับด้านบน |\n| `AZURE_OPENAI_CLIENT_ID` | **เปลี่ยนชื่อ** → `AZURE_CLIENT_ID` | ตามมาตรฐาน Azure Identity SDK สำหรับ `ManagedIdentityCredential(client_id=...)` |\n| `AZURE_OPENAI_ENDPOINT` | **เก็บไว้** | ยังคงต้องใช้สำหรับสร้าง `base_url` |\n| `AZURE_OPENAI_CHAT_DEPLOYMENT` | **เก็บไว้** | ใช้เป็นพารามิเตอร์ `model` ใน `responses.create` |\n| `AZURE_OPENAI_API_KEY` | **เก็บไว้** | ใช้เป็น `api_key` สำหรับการยืนยันตัวตนด้วยคีย์ |\n\nตัวอย่างการตั้งค่าไคลเอนต์ (ซิงค์, อะซิงค์, EntraID, คีย์ API, หลาย tenant) ดูใน [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md)\n\n---\n\n## ขั้นตอนที่ 1: ตรวจจับจุดเรียกใช้งานแบบเก่า\n\nรันสคริปต์ [detect_legacy.py](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py) เพื่อค้นหาจุดเรียกใช้งานทั้งหมดที่ต้องย้าย:\n\n```bash\npython skills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py .\n```\n\nหรือรันการค้นหาเหล่านี้ด้วยตนเอง — ทุกคำที่ตรงเป็นเป้าหมายการย้าย:\n\n```bash\n# การเรียก API รุ่นเก่า (ต้องเขียนใหม่)\nrg \"chat\\.completions\\.create\"\nrg \"ChatCompletion\\.create\"\nrg \"Completion\\.create\"\n\n# ตัวสร้างไคลเอ็นต์ Azure ที่เลิกใช้แล้ว (ต้องเปลี่ยนใหม่)\nrg \"AzureOpenAI\\(\"\nrg \"AsyncAzureOpenAI\\(\"\n\n# รูปแบบการเข้าถึงโครงสร้างการตอบกลับ (ต้องอัปเดต)\nrg \"choices\\[0\\]\\.message\\.content\"\nrg \"choices\\[0\\]\\.delta\\.content\"\nrg \"choices\\[0\\]\\.message\\.function_call\"\nrg \"choices\\[0\\]\\.message\\.tool_calls\"\n\n# นิยามเครื่องมือในรูปแบบซ้อนเก่า (ต้องปรับเป็นโครงสร้างแบน)\nrg '\"function\":\\s*{\\s*\"name\"'\nrg \"pydantic_function_tool\"\n\n# ผลลัพธ์เครื่องมือในรูปแบบเก่า (ต้องแปลงเป็น function_call_output)\nrg '\"role\":\\s*\"tool\"'\nrg '\"tool_call_id\"'\n\n# พารามิเตอร์ที่เลิกใช้แล้ว (ต้องลบหรือเปลี่ยนชื่อ)\nrg \"response_format\"\nrg \"max_tokens\\b\"        # เปลี่ยนชื่อเป็น max_output_tokens\nrg \"['\\\"]seed['\\\"]\"      # remove entirely\n\n# ตัวแปรสภาพแวดล้อมที่เลิกใช้แล้ว (ต้องทำความสะอาด)\nrg \"AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION\"\nrg \"AZURE_OPENAI_CLIENT_ID\"  # ควรเป็น AZURE_CLIENT_ID\n\n# จุดเชื่อมต่อโมเดล GitHub (ต้องลบ — API ตอบกลับไม่ได้รับการสนับสนุน)\nrg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"\n\n# รูปแบบเก่าของเฟรมเวิร์กระดับสูง (ต้องอัปเดต)\nrg \"OpenAIChatCompletionClient\"  # MAF 1.0.0+: เปลี่ยนเป็น OpenAIChatClient\nrg \"ChatOpenAI\\(\" | grep -v \"use_responses_api\"  # LangChain: ต้องใช้ use_responses_api=True\n\n# โครงสร้างพื้นฐานการทดสอบ (ต้องอัปเดต)\nrg \"ChatCompletionChunk|AsyncCompletions\\.create\" tests\u002F\nrg \"_azure_ad_token_provider\" tests\u002F\nrg \"prompt_filter_results|content_filter_results\" tests\u002F\nrg \"choices\\[0\\]\" tests\u002F\n\n# การเข้าถึงข้อมูลข้อผิดพลาดตัวกรองเนื้อหา (ต้องอัปเดต — โครงสร้างเปลี่ยนแปลง)\nrg 'innererror.*content_filter_result|error\\.body\\[\"innererror\"\\]'\nrg \"content_filter_result\\[\" # รูปแบบเอกพจน์เก่า — ตอนนี้เป็น content_filter_results (พหูพจน์) ภายในอาร์เรย์ content_filters\n\n# การเรียก HTTP ดิบไปยังจุดสิ้นสุด Chat Completions (ต้องอัปเดต URL)\nrg \"\u002Fopenai\u002Fdeployments\u002F.*\u002Fchat\u002Fcompletions\"\nrg \"api-version=\"\n```\n\n### การประมาณ (ตรวจจับและเขียนใหม่)\n\n- **ไคลเอนต์ Chat Completions**: `client.chat.completions.create` → `client.responses.create(...)`.\n\n- **ตัวสร้างลูกค้า Azure**: `AzureOpenAI(...)` → `OpenAI(base_url=..., api_key=...)`.\n- **เครื่องมือ**: แปลงคำจำกัดความเครื่องมือเรียกฟังก์ชันจากรูปแบบซ้อนกัน (`{\"type\": \"function\", \"function\": {\"name\": ...}}`) เป็นรูปแบบแบนของ Responses (`{\"type\": \"function\", \"name\": ...}`); ใช้ `tool_choice`; ส่งคืนผลลัพธ์ของเครื่องมือเป็นรายการ `{\"type\": \"function_call_output\", \"call_id\": ..., \"output\": ...}` (ไม่ใช่ `{\"role\": \"tool\", ...}`).\n- **รอบเครื่องมือ**: เมื่อโมเดลส่งคืนการเรียกฟังก์ชัน ให้แนบรายการ `response.output` ลงในการสนทนา (ไม่ใช่ dict แบบแมนนวล `{\"role\": \"assistant\", \"tool_calls\": [...]}`) จากนั้นแนบรายการ `function_call_output` สำหรับแต่ละผลลัพธ์.\n- **ตัวอย่างเครื่องมือแบบ few-shot**: หากการสนทนารวมตัวอย่างการเรียกเครื่องมือแบบกำหนดไว้ล่วงหน้า ให้แปลงเป็นรายการ `{\"type\": \"function_call\", \"id\": \"fc_...\", \"call_id\": \"fc_...\", ...}` + `{\"type\": \"function_call_output\", ...}` ต้องให้ ID เริ่มต้นด้วย `fc_`.\n- **`pydantic_function_tool()`**: ตัวช่วยนี้ยังคงสร้างรูปแบบซ้อนแบบเก่าและ **ไม่เข้ากันได้** กับ `responses.create()` ให้แทนที่ด้วยคำจำกัดความเครื่องมือแบบแมนนวลหรือใช้ตัวห่อแปลงรูปแบบแบน.\n- **หลายรอบ**: รักษาประวัติการสนทนาในแอป; ส่งผ่านรอบก่อนหน้าผ่านรายการ `input`.\n- **การจัดรูปแบบ**: แทนที่ `response_format` บนระดับบนสุดของ Chat ด้วย `text.format` ใน Responses รูปแบบมาตรฐาน: `text={\"format\": {\"type\": \"json_schema\", \"name\": \"Output\", \"strict\": True, \"schema\": {...}}}`.\n- **รายการเนื้อหา**: แทนที่ Chat `content[].type: \"text\"` ด้วย Responses `content[].type: \"input_text\"` สำหรับรอบของผู้ใช้\u002Fระบบ.\n- **รายการเนื้อหารูปภาพ**: แทนที่ Chat `content[].type: \"image_url\"` ด้วย Responses `content[].type: \"input_image\"` ฟิลด์ `image_url` เปลี่ยนจากออบเจ็กต์ซ้อน `{\"url\": \"...\"}` เป็นสตริงแบน ดูตารางสรุปสำหรับตัวอย่างก่อน\u002Fหลัง.\n- **ความพยายามในการให้เหตุผล**: **ย้ายเฉพาะ `reasoning` หากมีอยู่แล้วในโค้ดเดิม**.\n- **การจัดการข้อผิดพลาดตัวกรองเนื้อหา**: โครงสร้าง body ของข้อผิดพลาดเปลี่ยนจากเดิม Chat Completions ใช้ `error.body[\"innererror\"][\"content_filter_result\"]` (เอกพจน์); Responses API ใช้ `error.body[\"content_filters\"][0][\"content_filter_results\"]` (พหูพจน์ อยู่ในอาเรย์) โค้ดที่เข้าถึง `innererror` จะเกิด `KeyError` ให้เขียนใหม่ใช้เส้นทางใหม่.\n- **การเรียก HTTP แบบดิบ**: หากแอปเรียก REST API ของ Azure OpenAI โดยตรง (ผ่าน `requests`, `httpx` ฯลฯ) ใช้ `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions?api-version=...` ให้เขียนใหม่เป็น `\u002Fopenai\u002Fv1\u002Fresponses` ร่างคำขอเปลี่ยน: `messages` → `input` เพิ่ม `max_output_tokens` และ `store: false` ลบพารามิเตอร์ query `api-version` ร่างการตอบกลับเปลี่ยน: `choices[0].message.content` → `output[0].content[0].text` (หมายเหตุ: `output_text` เป็นคุณสมบัติสะดวกของ SDK ซึ่งไม่มีใน REST JSON ต้นฉบับ).\n\n---\n\n## ขั้นตอนที่ 2: ใช้การย้ายข้อมูล\n\n### หมายเหตุการย้ายข้อมูล (Chat Completions → Responses)\n\n- **ทำไมต้องย้าย**: Responses คือ API รวมสำหรับข้อความ, เครื่องมือ, และการสตรีม; Chat Completions เป็นของเดิม กับ GPT-5 จำเป็นต้องใช้ Responses เพื่อประสิทธิภาพดีที่สุด.\n- **HTTP**: จุดสิ้นสุด Azure เปลี่ยนจาก `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions` เป็น `\u002Fopenai\u002Fv1\u002Fresponses`.\n- **ฟิลด์**: `messages` → `input`, `max_tokens` → `max_output_tokens` อุณหภูมิยังคงเหมือนเดิม.\n- **การจัดรูปแบบ**: `response_format` → `text.format` โดยใช้วัตถุที่ถูกต้อง.\n- **รายการเนื้อหา**: แทนที่ Chat `content[].type: \"text\"` ด้วย Responses `content[].type: \"input_text\"` สำหรับรอบระบบ\u002Fผู้ใช้.\n- **รายการเนื้อหารูปภาพ**: แทนที่ Chat `content[].type: \"image_url\"` ด้วย Responses `content[].type: \"input_image\"` แบนฟิลด์ `image_url` จาก `{\"image_url\": {\"url\": \"...\"}}` เป็น `{\"image_url\": \"...\"}` (เป็นสตริงธรรมดา — อาจเป็น URL HTTPS หรือ data URI ประเภท `data:image\u002F...;base64,...`).\n\n### แผนที่พารามิเตอร์อ้างอิง\n\n| Chat Completions | Responses API |\n|-----------------|---------------|\n| `prompt` | `input` |\n| `messages` | `input` (อาเรย์ของรายการ) |\n| `max_tokens` | `max_output_tokens` |\n| `response_format` | `text.format` (วัตถุ) |\n| `temperature` | `temperature` (ไม่เปลี่ยนแปลง) |\n| `stop` | `stop` (ไม่เปลี่ยนแปลง) |\n| `frequency_penalty` | `frequency_penalty` (ไม่เปลี่ยนแปลง) |\n| `presence_penalty` | `presence_penalty` (ไม่เปลี่ยนแปลง) |\n| `tools` \u002F function-calling | `tools` (ไม่เปลี่ยนแปลง) |\n| `seed` | **ลบ** (ไม่รองรับ) |\n| `store` | `store` (ตั้งเป็น `false`) |\n| `content[].type: \"text\"` | `content[].type: \"input_text\"` |\n| `content[].type: \"image_url\"` | `content[].type: \"input_image\"` |\n| `\"image_url\": {\"url\": \"...\"}` | `\"image_url\": \"...\"` (สตริงแบน) |\n\nสำหรับตัวอย่างโค้ดก่อน\u002Fหลังแบบสมบูรณ์ ดูที่ [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\nสำหรับการย้ายโครงสร้างทดสอบ (mocks, snapshots, assertions) ดูที่ [test-migration.md](.\u002Freferences\u002Ftest-migration.md).\n\nสำหรับการแก้ไขปัญหาข้อผิดพลาดและปัญหาต่าง ๆ ดูที่ [troubleshooting.md](.\u002Freferences\u002Ftroubleshooting.md).\n\n---\n\n## การเก็บรักษาข้อมูล & สถานะ\n\n- ตั้งค่า `store: false` ในคำขอ Responses ทั้งหมด.\n- อย่าพึ่งพา ID ข้อความก่อนหน้าหรือบริบทที่เก็บไว้ในเซิร์ฟเวอร์; เก็บสถานะแบบจัดการโดยไคลเอนต์และลดเมตาดาต้าให้น้อยที่สุด.\n\n---\n\n## เกณฑ์การยอมรับ\n\n### ด่านระดับโค้ด (ต้องผ่านทั้งหมด)\n\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"chat\\.completions\\.create|ChatCompletion\\.create|Completion\\.create\"` ในไฟล์ที่ย้ายแล้ว.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"AzureOpenAI\\(|AsyncAzureOpenAI\\(\"` — ตัวสร้างทั้งหมดใช้ `OpenAI`\u002F`AsyncOpenAI` กับจุดสิ้นสุด v1.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"` — ลบเส้นทางโค้ด GitHub Models.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"OpenAIChatCompletionClient\"` — โค้ด MAF 1.0.0+ ใช้ `OpenAIChatClient` (ซึ่งใช้ Responses API) ในเวอร์ชันก่อน 1.0.0 ให้ปรับเป็น `agent-framework-openai>=1.0.0`.\n- [ ] ทุกการเรียก `ChatOpenAI(...)` รวม `use_responses_api=True`.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"choices\\[0\\]\"` — ทุกการเข้าถึงผลลัพธ์ใช้ `resp.output_text` หรือสคีม่าเอาต์พุต Responses.\n- [ ] ไม่มี `response_format` บนระดับบนสุด; ทุกผลลัพธ์มีโครงสร้างใช้ `text={\"format\": {...}}`.\n- [ ] ใน `requirements.txt` หรือ `pyproject.toml` มี `openai>=1.108.1` และ `azure-identity`; ติดตั้ง dependencies ใหม่แล้ว.\n- [ ] ตั้งค่า `store=False` ในทุกการเรียก `responses.create`.\n- [ ] ไม่มี `api_version` ในการสร้างไคลเอนต์; ลบ `AZURE_OPENAI_API_VERSION` ออกจากไฟล์ env และโครงสร้างพื้นฐาน.\n\n### ด่านโครงสร้างทดสอบ (ต้องผ่านทั้งหมด)\n\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"ChatCompletionChunk|AsyncCompletions\\.create|chat\\.completions\" tests\u002F`.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"_azure_ad_token_provider\" tests\u002F` — ปรับปรุง assertions ให้ตรวจสอบ `isinstance(client, AsyncOpenAI)` หรือ `base_url`.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"prompt_filter_results|content_filter_results\" tests\u002F` — ลบ mocks ตัวกรองเฉพาะ Azure.\n- [ ] ใช้ fixture mocks `kwargs.get(\"input\")` แทน `kwargs.get(\"messages\")`.\n- [ ] ปรับปรุงไฟล์ snapshot \u002F golden เป็นรูปแบบสตรีมของ Responses (ไม่มี `choices[0]`, `function_call`, `logprobs` ฯลฯ).\n- [ ] `pytest` ผ่านโดยไม่มีข้อผิดพลาดหลังจากแก้ไขการทดสอบทั้งหมด.\n\n### ด่านพฤติกรรม (ตรวจสอบด้วยตนเองหรือผ่านชุดทดสอบ)\n\n- [ ] **การคอมพลีตพื้นฐาน**: `responses.create` แบบไม่สตรีมส่งคืน `output_text` ที่ไม่ว่าง.\n- [ ] **ความเท่าเทียมแบบสตรีม**: หากโค้ดเดิมใช้การสตรีม โค้ดที่ย้ายจะสตรีมและให้เหตุการณ์ `response.output_text.delta` ที่มีเดลต้าไม่ว่าง.\n- [ ] **เอาต์พุตโครงสร้าง**: หากใช้ `text.format` กับ `json_schema` `json.loads(resp.output_text)` ผ่านและตรงกับสคีม่า.\n- [ ] **ลูปเรียกเครื่องมือ**: หากใช้เครื่องมือ โมเดลจะส่งคำสั่งเรียกเครื่องมือ, แอปจะประมวลผล, และคำขอต่อไปจะส่งคืน `output_text` สุดท้าย (ไม่มีลูปไม่สิ้นสุด).\n- [ ] **ความเท่าเทียมแบบ Async**: หากใช้ `AsyncAzureOpenAI`, การใช้ `AsyncOpenAI` แบบเทียบเท่าทำงานด้วย `await`.\n- [ ] **อัตราข้อผิดพลาด**: ไม่มีข้อผิดพลาด 400\u002F401\u002F404 ใหม่เมื่อเทียบกับเส้นฐานก่อนย้าย.\n\n### ผลงานที่ส่งมอบ\n\n- สรุปรายการไฟล์ที่แก้ไข, จำนวนจุดเรียกใช้เดิมและใหม่, และขั้นตอนถัดไป.\n- การเปลี่ยนแปลงเป็นการแก้ไขใน working-tree เท่านั้น (ไม่มี commit).\n\n---\n\n## เวอร์ชันที่ต้องใช้ของ SDK\n\n| แพ็กเกจ | เวอร์ชันขั้นต่ำ |\n|---------|----------------|\n| `openai` | `>=1.108.1` |\n| `azure-identity` | ล่าสุด (สำหรับการรับรองความถูกต้อง EntraID) |\n\n---\n\n## แหล่งอ้างอิง\n\n- [ใบสรุปการโกง — ตัวอย่างโค้ดทั้งหมด](.\u002Freferences\u002Fcheat-sheet.md)\n- [การย้ายทดสอบ — mocks, snapshots, assertions](.\u002Freferences\u002Ftest-migration.md)\n- [แก้ไขปัญหา — ข้อผิดพลาด, ตารางความเสี่ยง, ปัญหาที่พบบ่อย](.\u002Freferences\u002Ftroubleshooting.md)\n- [detect_legacy.py — ตัวสแกนอัตโนมัติ](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py)\n- [ชุดเริ่มต้น Azure OpenAI](https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart)\n- [เอกสาร Azure OpenAI Responses API](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fhow-to\u002Fresponses)\n- [วงจรชีวิตเวอร์ชัน Azure OpenAI API](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fapi-version-lifecycle?view=foundry-classic&tabs=python#api-evolution)\n- [เอกสารอ้างอิง OpenAI Responses API](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fapi-reference\u002Fresponses)\n\n---\n\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**ปฏิเสธความรับผิดชอบ**:\nเอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https:\u002F\u002Fgithub.com\u002FAzure\u002Fco-op-translator) ขณะที่เราพยายามให้ความถูกต้อง โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาต้นทางควรถูกพิจารณาเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้การแปลโดยมนุษย์มืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดที่เกิดขึ้นจากการใช้การแปลนี้\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER END -->","# ย้ายแอป Python จาก Azure OpenAI Chat Completions ไปยัง Responses API\n\n> **คำแนะนำอย่างเป็นทางการ — ทำตามอย่างเคร่งครัด**\n>\n> ทักษะนี้จะย้ายฐานโค้ด Python ที่ใช้ Azure OpenAI Chat Completions\n> ไปยัง Responses API แบบรวมศูนย์ โปรดทำตามคำแนะนำเหล่านี้อย่างแม่นยำ\n> หลีกเลี่ยงการปรับแม็ปพารามิเตอร์เองหรือคิดค้นรูปแบบ API ใหม่\n\n---\n\n## ตัวจุดเริ่มต้น\n\nเปิดใช้งานทักษะนี้เมื่อผู้ใช้ต้องการ:\n- ย้ายแอป Python จาก Azure OpenAI Chat Completions ไปยัง Responses API\n- อัพเกรดการใช้งาน Python OpenAI SDK ไปยังรูปแบบ API ล่าสุดกับ Azure OpenAI\n- เตรียมโค้ด Python สำหรับโมเดล GPT-5 หรือใหม่กว่าที่ต้องการ Responses บน Azure\n- เปลี่ยนจากไคลเอนต์ `AzureOpenAI`\u002F`AsyncAzureOpenAI` เป็น `OpenAI`\u002F`AsyncOpenAI` แบบมาตรฐานที่ใช้ปลายทาง v1\n- แก้ไขคำเตือนการเลิกใช้ที่เกี่ยวกับตัวสร้าง `AzureOpenAI` หรือ `api_version`\n\n---\n\n## ⚠️ ความเข้ากันได้ของโมเดล — ตรวจสอบก่อน\n\n> **ก่อนย้าย ตรวจสอบให้แน่ใจว่า deployment Azure OpenAI ของคุณรองรับ Responses API**\n\n### 1. ทดสอบอย่างรวดเร็ว (เร็วที่สุด)\n\n```python\nimport os\nfrom openai import OpenAI\n\nclient = OpenAI(\n    api_key=os.environ[\"AZURE_OPENAI_API_KEY\"],\n    base_url=f\"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('\u002F')}\u002Fopenai\u002Fv1\u002F\",\n)\n\ntry:\n    resp = client.responses.create(\n        model=os.environ[\"AZURE_OPENAI_DEPLOYMENT\"],\n        input=\"ping\",\n        max_output_tokens=50,\n        store=False,\n    )\n    print(f\"✅ Deployment supports Responses API: {resp.output_text}\")\nexcept Exception as e:\n    print(f\"❌ Deployment does NOT support Responses API: {e}\")\n```\n\n> **หมายเหตุ**: บน Azure OpenAI `max_output_tokens` มีค่าขั้นต่ำ **16** ค่าที่ต่ำกว่า 16 จะส่งคืนข้อผิดพลาด 400 ใช้ค่า 50+ สำหรับการทดสอบแบบรวดเร็ว\n\nหากส่งคืน 404 โมเดลใน deployment นี้ยังไม่รองรับ Responses — ตรวจสอบข้อมูลอ้างอิงด้านล่างหรือเปิดใช้งานใหม่ด้วยโมเดลที่รองรับ\n\n### 2. ตรวจสอบโมเดลที่มีในภูมิภาคของคุณ (แนะนำ)\n\nใช้เครื่องมือรองรับโมเดลในตัวเพื่อดูว่ามีอะไรพร้อมใช้งานกับ Responses API ในภูมิภาคของคุณ:\n\n```bash\npython migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION\n```\n\nเครื่องมือนี้เรียก Azure ARM สดและแสดงแมทริกซ์ความเข้ากันได้ — โมเดลใดรองรับ Responses, การส่งออกแบบมีโครงสร้าง, เครื่องมือ ฯลฯ ใช้ `--filter gpt-5.1,gpt-5.2` เพื่อลดผลลัพธ์หรือ `--json` สำหรับสคริปต์\n\n### 3. อ้างอิงการรองรับโมเดลเต็มรูปแบบ\n\n- **การเรียกดูสด**: `python migrate.py models` (ดูด้านบน — เฉพาะภูมิภาค, อัปเดตเสมอ)\n- **เรียกดูความพร้อมใช้งาน**: [ตารางสรุปโมเดลและความพร้อมใช้งานในภูมิภาค](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Ffoundry\u002Ffoundry-models\u002Fconcepts\u002Fmodels-sold-directly-by-azure?tabs=global-standard-aoai%2Cglobal-standard&pivots=azure-openai#model-summary-table-and-region-availability)\n- **เริ่มต้นใช้งานและคำแนะนำ**: **https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart**\n\n### ⚠️ ข้อจำกัดของโมเดลเก่า\n\n> **คำเตือน**: โมเดลเก่า (ก่อน `gpt-4.1`) อาจไม่รองรับฟีเจอร์ Responses API ทุกอย่างอย่างเต็มที่\n>\n> จำกัดการใช้งานที่ทราบกับโมเดลเก่า:\n> - **พารามิเตอร์ `reasoning`**: ไม่รองรับในหลายโมเดลที่ไม่มี reasoning หากจะย้ายให้ย้ายเฉพาะกรณีที่มี `reasoning` อยู่แล้วในโค้ดต้นทาง\n> - **พารามิเตอร์ `seed`**: ไม่รองรับใน Responses API เลย — ลบออกจากคำขอทั้งหมด\n> - **ผลลัพธ์แบบมีโครงสร้างผ่าน `text.format`**: โมเดลเก่าอาจไม่บังคับใช้สคีมา JSON แบบ `strict: true` ได้อย่างน่าเชื่อถือ\n> - **การประสานเครื่องมือ**: GPT-5+ จัดการการเรียกเครื่องมือเป็นส่วนหนึ่งของ reasoning ภายใน โมเดลเก่าบน Responses ยังใช้งานได้แต่ไม่มีการรวมลึกนี้\n> - **ข้อจำกัดอุณหภูมิ**: เมื่อย้ายไป `gpt-5` อุณหภูมิต้องไม่กำหนดหรือกำหนดเป็น `1` โมเดลเก่าไม่มีข้อจำกัดนี้\n\n### โมเดล reasoning ซีรีส์ O (o1, o3-mini, o3, o4-mini)\n\nโมเดลซีรีส์ O มีข้อจำกัดพารามิเตอร์เฉพาะตัว เมื่อย้ายแอปที่มุ่งเป้าไปยังโมเดลซีรีส์ O:\n\n- **`temperature`**: ต้องเป็น `1` (หรือละเว้น) โมเดลซีรีส์ O ไม่รับค่าที่ต่างจากนี้\n- **`max_completion_tokens` → `max_output_tokens`**: แอปที่ใช้ `max_completion_tokens` เฉพาะ Azure ต้องเปลี่ยนเป็น `max_output_tokens` ตั้งค่าสูง (4096+) เพราะโทเค็น reasoning นับในขีดจำกัดนี้\n- **`reasoning_effort`**: หากแอปใช้ `reasoning_effort` (ต่ำ\u002Fกลาง\u002Fสูง) ให้เก็บไว้ — Responses API รองรับพารามิเตอร์นี้สำหรับโมเดลซีรีส์ O\n- **พฤติกรรมการสตรีม**: โมเดลซีรีส์ O อาจเก็บบัฟเฟอร์ผลลัพธ์จน reasoning เสร็จก่อนส่งเหตุการณ์ delta ข้อความ การสตรีมยังทำงาน แต่ delta แรกอาจช้ากว่าโมเดล GPT\n- **`top_p`**: ไม่รองรับในซีรีส์ O — ให้ลบออกหากมี\n- **การใช้เครื่องมือ**: โมเดลซีรีส์ O รองรับเครื่องมือผ่าน Responses API เช่นเดียวกับโมเดล GPT แต่คุณภาพการประสานการเรียกเครื่องมือขึ้นกับแต่ละโมเดล\n\n**คำแนะนำเชิงรุก — ระหว่างสแกน**: ตรวจสอบว่าแอปใช้โมเดลใด (ชื่อ deployment, ตัวแปรสภาพแวดล้อม, การตั้งค่า) หากเป็นโมเดลก่อน `gpt-4.1` (ไม่ใช่ gpt-4.1+) แจ้งผู้ใช้ล่วงหน้า:\n- การย้ายจะทำงานกับข้อความพื้นฐาน แชท การสตรีม และเครื่องมือบนโมเดลปัจจุบันได้\n- โมเดลใหม่กว่า (`gpt-5.1`, `gpt-5.2`) ให้การประสานเครื่องมือที่ดีกว่า การบังคับใช้ผลลัพธ์แบบมีโครงสร้าง reasoning และความพร้อมใช้งานข้ามภูมิภาค\n- ควรพิจารณาอัปเกรด deployment เมื่อพร้อม — ไม่มีผลขัดขวางการย้ายตอนนี้\n\nหลีกเลี่ยงการบล็อกหรือปฏิเสธให้ย้ายตามเวอร์ชันโมเดล คำแนะนำนี้เป็นข้อมูลเท่านั้น\n\n### GitHub Models ไม่รองรับ Responses API\n\n> **GitHub Models (`models.github.ai`, `models.inference.ai.azure.com`) ไม่รองรับ Responses API**\n\nหากฐานโค้ดมีเส้นทางโค้ด GitHub Models (ดูที่ `base_url` ชี้ไปยัง `models.github.ai` หรือ `models.inference.ai.azure.com`) **ให้ลบออกทั้งหมด** ในการย้าย Responses API ต้องใช้ Azure OpenAI, OpenAI หรือปลายทางในเครื่องที่เข้ากันได้ (เช่น Ollama ที่รองรับ Responses)\n\nการดำเนินการระหว่างสแกน:\n- ให้ติดธงเส้นทางโค้ด GitHub Models เพื่อการลบ\n\n---\n\n## การย้ายเฟรมเวิร์ก\n\nแอปหลายแอปใช้เฟรมเวิร์กระดับสูงบน OpenAI เมื่อย้ายเฟรมเวิร์กเหล่านี้ จะมีการเปลี่ยนแปลง API เฟรมเวิร์กเอง — ไม่ใช่แค่การเรียก OpenAI ขั้นต่ำ\n\n### Microsoft Agent Framework (MAF)\n\n**ตรวจสอบเวอร์ชัน MAF ของคุณก่อน** — การย้ายขึ้นกับว่าคุณใช้ MAF 1.0.0+ หรือเบต้า\u002Frc ก่อน 1.0.0\n\n#### MAF 1.0.0+ (agent-framework-openai >= 1.0.0)\n\n`OpenAIChatClient` **ใช้ Responses API แล้ว** — ไม่ต้องย้าย หากฐานโค้ดยังใช้ `OpenAIChatCompletionClient` แบบเก่า (ที่ใช้ `chat.completions.create`) ให้เปลี่ยนเป็น `OpenAIChatClient`\n\n| ก่อน | หลัง |\n|--------|-------|\n| `from agent_framework.openai import OpenAIChatCompletionClient` | `from agent_framework.openai import OpenAIChatClient` |\n| `OpenAIChatCompletionClient(...)` | `OpenAIChatClient(...)` |\n\nตรวจสอบเวอร์ชันของคุณด้วย: `python -c \"import agent_framework_openai; print(agent_framework_openai.__version__)\"`\n\n#### MAF ก่อน 1.0.0 (รุ่นเบต้า\u002Frc)\n\nใน MAF ก่อน 1.0.0 `OpenAIChatClient` ใช้ Chat Completions อัพเกรดเป็น `agent-framework-openai>=1.0.0` ซึ่ง `OpenAIChatClient` ใช้ Responses API โดยดีฟอลต์\n\nไม่มีการเปลี่ยนแปลงอื่น — API ของ `Agent` และเครื่องมือเหมือนเดิม\n\n### LangChain (`langchain-openai`)\n\nเพิ่ม `use_responses_api=True` ให้กับ `ChatOpenAI()` และอัพเดตการเข้าถึงผลลัพธ์จาก `.content` เป็น `.text`\n\n| ก่อน | หลัง |\n|--------|-------|\n| `ChatOpenAI(model=..., base_url=..., api_key=...)` | `ChatOpenAI(model=..., base_url=..., api_key=..., use_responses_api=True)` |\n| `result['messages'][-1].content` | `result['messages'][-1].text` |\n\nดูตัวอย่างโค้ดทั้งก่อนและหลังใน [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md)\n\n---\n\n## คำแนะนำการย้ายส่วนหน้า\n\n> **Responses API เป็นเรื่องฝั่งเซิร์ฟเวอร์** ย้าย backend Python ของคุณ ส่วนหน้า (frontend) ควรยังคงตามสัญญา HTTP เดิมเว้นแต่ว่า backend เป็นเพียงชั้นผ่านบาง ๆ — กรณีนั้นให้พิจารณาใช้รูปแบบคำขอ Responses เพื่อกำจัดชั้นแปลง หาก frontend เรียก OpenAI โดยตรงด้วยคีย์ฝั่งไคลเอนต์ ให้ย้ายการเรียกเหล่านั้นไป backend ก่อน\n\n### การเลิกใช้งาน `@microsoft\u002Fai-chat-protocol`\n\nแพ็กเกจ npm `@microsoft\u002Fai-chat-protocol` ถูกเลิกใช้และควรเปลี่ยนเป็น [`ndjson-readablestream`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fndjson-readablestream) หากพบในส่วนหน้า:\n\n1. แก้แท็กสคริปต์ CDN:\n   ```html\n   \u003C!-- Before -->\n   \u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@microsoft\u002Fai-chat-protocol@...\u002Fdist\u002Fiife\u002Findex.js\">\u003C\u002Fscript>\n   \u003C!-- After -->\n   \u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fndjson-readablestream@1.0.7\u002Fdist\u002Fndjson-readablestream.umd.js\">\u003C\u002Fscript>\n   ```\n2. ลบการสร้างอินสแตนซ์ `AIChatProtocolClient` (`new ChatProtocol.AIChatProtocolClient(\"\u002Fchat\")`)\n3. เปลี่ยน `client.getStreamedCompletion(messages)` เป็นเรียก `fetch()` ตรงไปยังจุดสตรีมของ backend\n4. เปลี่ยน `for await (const response of result)` เป็น `for await (const chunk of readNDJSONStream(response.body))`\n5. ปรับเปลี่ยนการเข้าถึงคุณสมบัติจาก `response.delta.content` \u002F `response.error` เป็น `chunk.delta.content` \u002F `chunk.error`\n\n---\n\n## เป้าหมาย\n\n- ระบุทุกจุดเรียก Python ที่ใช้ Chat Completions หรือ Completions แบบเก่าที่เรียกกับ Azure OpenAI\n- เสนอแผนการย้ายและลำดับขั้นสำหรับฐานโค้ด Python\n- ใช้การแก้ไขอย่างปลอดภัยและน้อยที่สุดเพื่อสลับไป Responses API\n- อัปเดตผู้เรียกเพื่อใช้สคีมาผลลัพธ์ของ Responses; ไม่มีหุ้มหลังความเข้ากันได้\n- รันการทดสอบ\u002Fตรวจสอบ; แก้ไขปัญหาเล็กน้อยที่เกิดจากการย้าย\n- เตรียมชุดการเปลี่ยนแปลงที่เล็กและตรวจสอบได้ พร้อมสรุปสุดท้ายพร้อมการเปรียบเทียบ (ไม่ต้อง commit)\n\n---\n\n## กฎข้อบังคับ\n\n- แก้ไขเฉพาะไฟล์ในพื้นที่ git เท่านั้น ห้ามเขียนนอกพื้นที่นี้\n- ไม่ต้องเก็บไว้ในช่องทางหลังความเข้ากันได้; ย้ายโค้ดไปยังรูปแบบ API ใหม่\n- หลีกเลี่ยงการทิ้งคอมเมนต์รอยตาย\u002Fเปลี่ยนผ่านหรือไฟล์สำรอง\n- รักษาลักษณะการสตรีมหากเคยใช้; มิฉะนั้นใช้แบบไม่สตรีม\n- ขออนุมัติก่อนรันคำสั่งหรือเรียกเครือข่ายถ้าอยู่ในโหมดอนุมัติ\n- หลีกเลี่ยงการรัน `git add`\u002F`git commit`\u002F`git push`; ผลลัพธ์ต้องเป็นใน working-tree เท่านั้น\n\n---\n\n## ขั้นตอนที่ 0: ย้ายไคลเอนต์ Azure OpenAI (เงื่อนไขเบื้องต้น)\n\nหากฐานโค้ดใช้ตัวสร้าง `AzureOpenAI` หรือ `AsyncAzureOpenAI` ให้ย้ายไปใช้ตัวสร้าง `OpenAI` \u002F `AsyncOpenAI` แบบมาตรฐานก่อน ตัวสร้างเฉพาะ Azure ถูกเลิกใช้ใน `openai>=1.108.1`\n\n### ทำไมต้องใช้ปลายทาง v1 API?\n\nปลายทางใหม่ `\u002Fopenai\u002Fv1` ใช้ไคลเอนต์ `OpenAI()` แบบมาตรฐานแทน `AzureOpenAI()` ไม่ต้องใช้พารามิเตอร์ `api_version` และทำงานเหมือนกันทั้ง OpenAI และ Azure OpenAI โค้ดไคลเอนต์เดียวกันนี้รองรับอนาคต — ไม่ต้องจัดการเวอร์ชัน\n\n### การเปลี่ยนแปลงสำคัญ\n\n| ก่อน | หลัง |\n|--------|-------|\n| `AzureOpenAI` | `OpenAI` |\n| `AsyncAzureOpenAI` | `AsyncOpenAI` |\n| `azure_endpoint` | `base_url` |\n| `azure_ad_token_provider` | `api_key` |\n| `api_version=...` | ลบทิ้งทั้งหมด |\n\n### รายการล้างข้อมูล\n\n- ลบอาร์กิวเมนต์ `api_version` จากการสร้างไคลเอนต์\n- ลบตัวแปรสภาพแวดล้อม `AZURE_OPENAI_VERSION` \u002F `AZURE_OPENAI_API_VERSION` จาก `.env`, การตั้งค่าแอป และไฟล์ Bicep\u002Fโครงสร้างพื้นฐาน\n- เปลี่ยนชื่อ `AZURE_OPENAI_CLIENT_ID` → `AZURE_CLIENT_ID` ใน `.env`, การตั้งค่าแอป, Bicep\u002Fโครงสร้างพื้นฐาน และไฟล์ตัวอย่างทดสอบ (ตามแนวทางมาตรฐาน Azure Identity SDK)\n- แน่ใจว่า `openai>=1.108.1` ใน `requirements.txt` หรือ `pyproject.toml`\n\n### ย้ายตัวแปรสภาพแวดล้อม\n\n| ตัวแปรสภาพแวดล้อมเดิม | การดำเนินการ | หมายเหตุ |\n|-------------|--------|-------|\n| `AZURE_OPENAI_VERSION` | **ลบ** | ไม่ต้องใช้ `api_version` กับปลายทาง v1 |\n| `AZURE_OPENAI_API_VERSION` | **ลบ** | เหมือนกันกับด้านบน |\n| `AZURE_OPENAI_CLIENT_ID` | **เปลี่ยนชื่อ** → `AZURE_CLIENT_ID` | ตามมาตรฐาน Azure Identity SDK สำหรับ `ManagedIdentityCredential(client_id=...)` |\n| `AZURE_OPENAI_ENDPOINT` | **เก็บไว้** | ยังคงต้องใช้สำหรับสร้าง `base_url` |\n| `AZURE_OPENAI_CHAT_DEPLOYMENT` | **เก็บไว้** | ใช้เป็นพารามิเตอร์ `model` ใน `responses.create` |\n| `AZURE_OPENAI_API_KEY` | **เก็บไว้** | ใช้เป็น `api_key` สำหรับการยืนยันตัวตนด้วยคีย์ |\n\nตัวอย่างการตั้งค่าไคลเอนต์ (ซิงค์, อะซิงค์, EntraID, คีย์ API, หลาย tenant) ดูใน [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md)\n\n---\n\n## ขั้นตอนที่ 1: ตรวจจับจุดเรียกใช้งานแบบเก่า\n\nรันสคริปต์ [detect_legacy.py](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py) เพื่อค้นหาจุดเรียกใช้งานทั้งหมดที่ต้องย้าย:\n\n```bash\npython skills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py .\n```\n\nหรือรันการค้นหาเหล่านี้ด้วยตนเอง — ทุกคำที่ตรงเป็นเป้าหมายการย้าย:\n\n```bash\n# การเรียก API รุ่นเก่า (ต้องเขียนใหม่)\nrg \"chat\\.completions\\.create\"\nrg \"ChatCompletion\\.create\"\nrg \"Completion\\.create\"\n\n# ตัวสร้างไคลเอ็นต์ Azure ที่เลิกใช้แล้ว (ต้องเปลี่ยนใหม่)\nrg \"AzureOpenAI\\(\"\nrg \"AsyncAzureOpenAI\\(\"\n\n# รูปแบบการเข้าถึงโครงสร้างการตอบกลับ (ต้องอัปเดต)\nrg \"choices\\[0\\]\\.message\\.content\"\nrg \"choices\\[0\\]\\.delta\\.content\"\nrg \"choices\\[0\\]\\.message\\.function_call\"\nrg \"choices\\[0\\]\\.message\\.tool_calls\"\n\n# นิยามเครื่องมือในรูปแบบซ้อนเก่า (ต้องปรับเป็นโครงสร้างแบน)\nrg '\"function\":\\s*{\\s*\"name\"'\nrg \"pydantic_function_tool\"\n\n# ผลลัพธ์เครื่องมือในรูปแบบเก่า (ต้องแปลงเป็น function_call_output)\nrg '\"role\":\\s*\"tool\"'\nrg '\"tool_call_id\"'\n\n# พารามิเตอร์ที่เลิกใช้แล้ว (ต้องลบหรือเปลี่ยนชื่อ)\nrg \"response_format\"\nrg \"max_tokens\\b\"        # เปลี่ยนชื่อเป็น max_output_tokens\nrg \"['\\\"]seed['\\\"]\"      # remove entirely\n\n# ตัวแปรสภาพแวดล้อมที่เลิกใช้แล้ว (ต้องทำความสะอาด)\nrg \"AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION\"\nrg \"AZURE_OPENAI_CLIENT_ID\"  # ควรเป็น AZURE_CLIENT_ID\n\n# จุดเชื่อมต่อโมเดล GitHub (ต้องลบ — API ตอบกลับไม่ได้รับการสนับสนุน)\nrg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"\n\n# รูปแบบเก่าของเฟรมเวิร์กระดับสูง (ต้องอัปเดต)\nrg \"OpenAIChatCompletionClient\"  # MAF 1.0.0+: เปลี่ยนเป็น OpenAIChatClient\nrg \"ChatOpenAI\\(\" | grep -v \"use_responses_api\"  # LangChain: ต้องใช้ use_responses_api=True\n\n# โครงสร้างพื้นฐานการทดสอบ (ต้องอัปเดต)\nrg \"ChatCompletionChunk|AsyncCompletions\\.create\" tests\u002F\nrg \"_azure_ad_token_provider\" tests\u002F\nrg \"prompt_filter_results|content_filter_results\" tests\u002F\nrg \"choices\\[0\\]\" tests\u002F\n\n# การเข้าถึงข้อมูลข้อผิดพลาดตัวกรองเนื้อหา (ต้องอัปเดต — โครงสร้างเปลี่ยนแปลง)\nrg 'innererror.*content_filter_result|error\\.body\\[\"innererror\"\\]'\nrg \"content_filter_result\\[\" # รูปแบบเอกพจน์เก่า — ตอนนี้เป็น content_filter_results (พหูพจน์) ภายในอาร์เรย์ content_filters\n\n# การเรียก HTTP ดิบไปยังจุดสิ้นสุด Chat Completions (ต้องอัปเดต URL)\nrg \"\u002Fopenai\u002Fdeployments\u002F.*\u002Fchat\u002Fcompletions\"\nrg \"api-version=\"\n```\n\n### การประมาณ (ตรวจจับและเขียนใหม่)\n\n- **ไคลเอนต์ Chat Completions**: `client.chat.completions.create` → `client.responses.create(...)`.\n\n- **ตัวสร้างลูกค้า Azure**: `AzureOpenAI(...)` → `OpenAI(base_url=..., api_key=...)`.\n- **เครื่องมือ**: แปลงคำจำกัดความเครื่องมือเรียกฟังก์ชันจากรูปแบบซ้อนกัน (`{\"type\": \"function\", \"function\": {\"name\": ...}}`) เป็นรูปแบบแบนของ Responses (`{\"type\": \"function\", \"name\": ...}`); ใช้ `tool_choice`; ส่งคืนผลลัพธ์ของเครื่องมือเป็นรายการ `{\"type\": \"function_call_output\", \"call_id\": ..., \"output\": ...}` (ไม่ใช่ `{\"role\": \"tool\", ...}`).\n- **รอบเครื่องมือ**: เมื่อโมเดลส่งคืนการเรียกฟังก์ชัน ให้แนบรายการ `response.output` ลงในการสนทนา (ไม่ใช่ dict แบบแมนนวล `{\"role\": \"assistant\", \"tool_calls\": [...]}`) จากนั้นแนบรายการ `function_call_output` สำหรับแต่ละผลลัพธ์.\n- **ตัวอย่างเครื่องมือแบบ few-shot**: หากการสนทนารวมตัวอย่างการเรียกเครื่องมือแบบกำหนดไว้ล่วงหน้า ให้แปลงเป็นรายการ `{\"type\": \"function_call\", \"id\": \"fc_...\", \"call_id\": \"fc_...\", ...}` + `{\"type\": \"function_call_output\", ...}` ต้องให้ ID เริ่มต้นด้วย `fc_`.\n- **`pydantic_function_tool()`**: ตัวช่วยนี้ยังคงสร้างรูปแบบซ้อนแบบเก่าและ **ไม่เข้ากันได้** กับ `responses.create()` ให้แทนที่ด้วยคำจำกัดความเครื่องมือแบบแมนนวลหรือใช้ตัวห่อแปลงรูปแบบแบน.\n- **หลายรอบ**: รักษาประวัติการสนทนาในแอป; ส่งผ่านรอบก่อนหน้าผ่านรายการ `input`.\n- **การจัดรูปแบบ**: แทนที่ `response_format` บนระดับบนสุดของ Chat ด้วย `text.format` ใน Responses รูปแบบมาตรฐาน: `text={\"format\": {\"type\": \"json_schema\", \"name\": \"Output\", \"strict\": True, \"schema\": {...}}}`.\n- **รายการเนื้อหา**: แทนที่ Chat `content[].type: \"text\"` ด้วย Responses `content[].type: \"input_text\"` สำหรับรอบของผู้ใช้\u002Fระบบ.\n- **รายการเนื้อหารูปภาพ**: แทนที่ Chat `content[].type: \"image_url\"` ด้วย Responses `content[].type: \"input_image\"` ฟิลด์ `image_url` เปลี่ยนจากออบเจ็กต์ซ้อน `{\"url\": \"...\"}` เป็นสตริงแบน ดูตารางสรุปสำหรับตัวอย่างก่อน\u002Fหลัง.\n- **ความพยายามในการให้เหตุผล**: **ย้ายเฉพาะ `reasoning` หากมีอยู่แล้วในโค้ดเดิม**.\n- **การจัดการข้อผิดพลาดตัวกรองเนื้อหา**: โครงสร้าง body ของข้อผิดพลาดเปลี่ยนจากเดิม Chat Completions ใช้ `error.body[\"innererror\"][\"content_filter_result\"]` (เอกพจน์); Responses API ใช้ `error.body[\"content_filters\"][0][\"content_filter_results\"]` (พหูพจน์ อยู่ในอาเรย์) โค้ดที่เข้าถึง `innererror` จะเกิด `KeyError` ให้เขียนใหม่ใช้เส้นทางใหม่.\n- **การเรียก HTTP แบบดิบ**: หากแอปเรียก REST API ของ Azure OpenAI โดยตรง (ผ่าน `requests`, `httpx` ฯลฯ) ใช้ `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions?api-version=...` ให้เขียนใหม่เป็น `\u002Fopenai\u002Fv1\u002Fresponses` ร่างคำขอเปลี่ยน: `messages` → `input` เพิ่ม `max_output_tokens` และ `store: false` ลบพารามิเตอร์ query `api-version` ร่างการตอบกลับเปลี่ยน: `choices[0].message.content` → `output[0].content[0].text` (หมายเหตุ: `output_text` เป็นคุณสมบัติสะดวกของ SDK ซึ่งไม่มีใน REST JSON ต้นฉบับ).\n\n---\n\n## ขั้นตอนที่ 2: ใช้การย้ายข้อมูล\n\n### หมายเหตุการย้ายข้อมูล (Chat Completions → Responses)\n\n- **ทำไมต้องย้าย**: Responses คือ API รวมสำหรับข้อความ, เครื่องมือ, และการสตรีม; Chat Completions เป็นของเดิม กับ GPT-5 จำเป็นต้องใช้ Responses เพื่อประสิทธิภาพดีที่สุด.\n- **HTTP**: จุดสิ้นสุด Azure เปลี่ยนจาก `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions` เป็น `\u002Fopenai\u002Fv1\u002Fresponses`.\n- **ฟิลด์**: `messages` → `input`, `max_tokens` → `max_output_tokens` อุณหภูมิยังคงเหมือนเดิม.\n- **การจัดรูปแบบ**: `response_format` → `text.format` โดยใช้วัตถุที่ถูกต้อง.\n- **รายการเนื้อหา**: แทนที่ Chat `content[].type: \"text\"` ด้วย Responses `content[].type: \"input_text\"` สำหรับรอบระบบ\u002Fผู้ใช้.\n- **รายการเนื้อหารูปภาพ**: แทนที่ Chat `content[].type: \"image_url\"` ด้วย Responses `content[].type: \"input_image\"` แบนฟิลด์ `image_url` จาก `{\"image_url\": {\"url\": \"...\"}}` เป็น `{\"image_url\": \"...\"}` (เป็นสตริงธรรมดา — อาจเป็น URL HTTPS หรือ data URI ประเภท `data:image\u002F...;base64,...`).\n\n### แผนที่พารามิเตอร์อ้างอิง\n\n| Chat Completions | Responses API |\n|-----------------|---------------|\n| `prompt` | `input` |\n| `messages` | `input` (อาเรย์ของรายการ) |\n| `max_tokens` | `max_output_tokens` |\n| `response_format` | `text.format` (วัตถุ) |\n| `temperature` | `temperature` (ไม่เปลี่ยนแปลง) |\n| `stop` | `stop` (ไม่เปลี่ยนแปลง) |\n| `frequency_penalty` | `frequency_penalty` (ไม่เปลี่ยนแปลง) |\n| `presence_penalty` | `presence_penalty` (ไม่เปลี่ยนแปลง) |\n| `tools` \u002F function-calling | `tools` (ไม่เปลี่ยนแปลง) |\n| `seed` | **ลบ** (ไม่รองรับ) |\n| `store` | `store` (ตั้งเป็น `false`) |\n| `content[].type: \"text\"` | `content[].type: \"input_text\"` |\n| `content[].type: \"image_url\"` | `content[].type: \"input_image\"` |\n| `\"image_url\": {\"url\": \"...\"}` | `\"image_url\": \"...\"` (สตริงแบน) |\n\nสำหรับตัวอย่างโค้ดก่อน\u002Fหลังแบบสมบูรณ์ ดูที่ [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\nสำหรับการย้ายโครงสร้างทดสอบ (mocks, snapshots, assertions) ดูที่ [test-migration.md](.\u002Freferences\u002Ftest-migration.md).\n\nสำหรับการแก้ไขปัญหาข้อผิดพลาดและปัญหาต่าง ๆ ดูที่ [troubleshooting.md](.\u002Freferences\u002Ftroubleshooting.md).\n\n---\n\n## การเก็บรักษาข้อมูล & สถานะ\n\n- ตั้งค่า `store: false` ในคำขอ Responses ทั้งหมด.\n- อย่าพึ่งพา ID ข้อความก่อนหน้าหรือบริบทที่เก็บไว้ในเซิร์ฟเวอร์; เก็บสถานะแบบจัดการโดยไคลเอนต์และลดเมตาดาต้าให้น้อยที่สุด.\n\n---\n\n## เกณฑ์การยอมรับ\n\n### ด่านระดับโค้ด (ต้องผ่านทั้งหมด)\n\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"chat\\.completions\\.create|ChatCompletion\\.create|Completion\\.create\"` ในไฟล์ที่ย้ายแล้ว.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"AzureOpenAI\\(|AsyncAzureOpenAI\\(\"` — ตัวสร้างทั้งหมดใช้ `OpenAI`\u002F`AsyncOpenAI` กับจุดสิ้นสุด v1.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"` — ลบเส้นทางโค้ด GitHub Models.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"OpenAIChatCompletionClient\"` — โค้ด MAF 1.0.0+ ใช้ `OpenAIChatClient` (ซึ่งใช้ Responses API) ในเวอร์ชันก่อน 1.0.0 ให้ปรับเป็น `agent-framework-openai>=1.0.0`.\n- [ ] ทุกการเรียก `ChatOpenAI(...)` รวม `use_responses_api=True`.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"choices\\[0\\]\"` — ทุกการเข้าถึงผลลัพธ์ใช้ `resp.output_text` หรือสคีม่าเอาต์พุต Responses.\n- [ ] ไม่มี `response_format` บนระดับบนสุด; ทุกผลลัพธ์มีโครงสร้างใช้ `text={\"format\": {...}}`.\n- [ ] ใน `requirements.txt` หรือ `pyproject.toml` มี `openai>=1.108.1` และ `azure-identity`; ติดตั้ง dependencies ใหม่แล้ว.\n- [ ] ตั้งค่า `store=False` ในทุกการเรียก `responses.create`.\n- [ ] ไม่มี `api_version` ในการสร้างไคลเอนต์; ลบ `AZURE_OPENAI_API_VERSION` ออกจากไฟล์ env และโครงสร้างพื้นฐาน.\n\n### ด่านโครงสร้างทดสอบ (ต้องผ่านทั้งหมด)\n\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"ChatCompletionChunk|AsyncCompletions\\.create|chat\\.completions\" tests\u002F`.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"_azure_ad_token_provider\" tests\u002F` — ปรับปรุง assertions ให้ตรวจสอบ `isinstance(client, AsyncOpenAI)` หรือ `base_url`.\n- [ ] ไม่มีการจับคู่สำหรับ `rg \"prompt_filter_results|content_filter_results\" tests\u002F` — ลบ mocks ตัวกรองเฉพาะ Azure.\n- [ ] ใช้ fixture mocks `kwargs.get(\"input\")` แทน `kwargs.get(\"messages\")`.\n- [ ] ปรับปรุงไฟล์ snapshot \u002F golden เป็นรูปแบบสตรีมของ Responses (ไม่มี `choices[0]`, `function_call`, `logprobs` ฯลฯ).\n- [ ] `pytest` ผ่านโดยไม่มีข้อผิดพลาดหลังจากแก้ไขการทดสอบทั้งหมด.\n\n### ด่านพฤติกรรม (ตรวจสอบด้วยตนเองหรือผ่านชุดทดสอบ)\n\n- [ ] **การคอมพลีตพื้นฐาน**: `responses.create` แบบไม่สตรีมส่งคืน `output_text` ที่ไม่ว่าง.\n- [ ] **ความเท่าเทียมแบบสตรีม**: หากโค้ดเดิมใช้การสตรีม โค้ดที่ย้ายจะสตรีมและให้เหตุการณ์ `response.output_text.delta` ที่มีเดลต้าไม่ว่าง.\n- [ ] **เอาต์พุตโครงสร้าง**: หากใช้ `text.format` กับ `json_schema` `json.loads(resp.output_text)` ผ่านและตรงกับสคีม่า.\n- [ ] **ลูปเรียกเครื่องมือ**: หากใช้เครื่องมือ โมเดลจะส่งคำสั่งเรียกเครื่องมือ, แอปจะประมวลผล, และคำขอต่อไปจะส่งคืน `output_text` สุดท้าย (ไม่มีลูปไม่สิ้นสุด).\n- [ ] **ความเท่าเทียมแบบ Async**: หากใช้ `AsyncAzureOpenAI`, การใช้ `AsyncOpenAI` แบบเทียบเท่าทำงานด้วย `await`.\n- [ ] **อัตราข้อผิดพลาด**: ไม่มีข้อผิดพลาด 400\u002F401\u002F404 ใหม่เมื่อเทียบกับเส้นฐานก่อนย้าย.\n\n### ผลงานที่ส่งมอบ\n\n- สรุปรายการไฟล์ที่แก้ไข, จำนวนจุดเรียกใช้เดิมและใหม่, และขั้นตอนถัดไป.\n- การเปลี่ยนแปลงเป็นการแก้ไขใน working-tree เท่านั้น (ไม่มี commit).\n\n---\n\n## เวอร์ชันที่ต้องใช้ของ SDK\n\n| แพ็กเกจ | เวอร์ชันขั้นต่ำ |\n|---------|----------------|\n| `openai` | `>=1.108.1` |\n| `azure-identity` | ล่าสุด (สำหรับการรับรองความถูกต้อง EntraID) |\n\n---\n\n## แหล่งอ้างอิง\n\n- [ใบสรุปการโกง — ตัวอย่างโค้ดทั้งหมด](.\u002Freferences\u002Fcheat-sheet.md)\n- [การย้ายทดสอบ — mocks, snapshots, assertions](.\u002Freferences\u002Ftest-migration.md)\n- [แก้ไขปัญหา — ข้อผิดพลาด, ตารางความเสี่ยง, ปัญหาที่พบบ่อย](.\u002Freferences\u002Ftroubleshooting.md)\n- [detect_legacy.py — ตัวสแกนอัตโนมัติ](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py)\n- [ชุดเริ่มต้น Azure OpenAI](https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart)\n- [เอกสาร Azure OpenAI Responses API](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fhow-to\u002Fresponses)\n- [วงจรชีวิตเวอร์ชัน Azure OpenAI API](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fapi-version-lifecycle?view=foundry-classic&tabs=python#api-evolution)\n- [เอกสารอ้างอิง OpenAI Responses API](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fapi-reference\u002Fresponses)\n\n---\n\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**ปฏิเสธความรับผิดชอบ**:\nเอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https:\u002F\u002Fgithub.com\u002FAzure\u002Fco-op-translator) ขณะที่เราพยายามให้ความถูกต้อง โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาต้นทางควรถูกพิจารณาเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้การแปลโดยมนุษย์มืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดที่เกิดขึ้นจากการใช้การแปลนี้\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER END -->",{"name":5,"license":14},"main","f09e94ffe170f8af6d3db7c42987bbe4db227723","translations\u002Fth\u002F.agents\u002Fskills\u002Fazure-openai-to-responses",26019,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners","https:\u002F\u002Faka.ms\u002Fai-agents-beginners","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-07 12:51:12",{"source":7,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add microsoft\u002Fai-agents-for-beginners --skill azure-openai-to-responses",{"tool":40,"command":41},"bunx","bunx skills add microsoft\u002Fai-agents-for-beginners --skill azure-openai-to-responses",{"tool":43,"command":44},"pnpm","pnpm dlx skills add microsoft\u002Fai-agents-for-beginners --skill azure-openai-to-responses","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fth\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002FSKILL.md",true,[48,54,58],{"path":49,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":52,"sourceHtmlUrl":53},"references\u002Fcheat-sheet.md","REFERENCE","参考文档",39159,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fth\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Freferences\u002Fcheat-sheet.md",{"path":55,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":56,"sourceHtmlUrl":57},"references\u002Ftest-migration.md",9869,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fth\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Freferences\u002Ftest-migration.md",{"path":59,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":60,"sourceHtmlUrl":61},"references\u002Ftroubleshooting.md",25575,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fth\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Freferences\u002Ftroubleshooting.md",[63,81,92,100,108,115],{"skillNo":64,"name":65,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":78,"publishedAt":19},"01M69A206TRZ8KK0CW0HYJF5V5","testing-course-samples","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fzh-TW\u002F.agents\u002Fskills\u002Ftesting-course-samples\u002FSKILL.md",[68,73],{"categoryNo":69,"categoryName":70,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":74,"categoryName":75,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000039","教师与教育","PROFESSION","适用职业",[79,80],"testing","testing course samples",{"skillNo":82,"name":83,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":89,"publishedAt":19},"01M69A1XRB2SFHYRMEH0K08EKZ","microsoft-docs","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fzh-TW\u002F.agents\u002Fskills\u002Fmicrosoft-docs\u002FSKILL.md",[86],{"categoryNo":87,"categoryName":88,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000023","Skill与智能体开发",[90,8,91],"docs","microsoft docs",{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":19},"01M69A1VPZFJQ1HNGTZQ5P3WSC","local-ai-agents","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fzh-TW\u002F.agents\u002Fskills\u002Flocal-ai-agents\u002FSKILL.md",[],[98,99],"ai agents","local ai agents",{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":104,"categories":105,"keywords":106,"publishedAt":19},"01M69A1S947N7MM6V9JF85S2E7","jupyter-notebook","當使用者要求建立、搭建或編輯 Jupyter 筆記本（`.ipynb`）用於實驗、探索或教學時使用；優先使用隨附範本並執行輔助腳本 `new_notebook.py` 來產生一個乾淨的起始筆記本。","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fzh-TW\u002F.agents\u002Fskills\u002Fjupyter-notebook\u002FSKILL.md",[],[107],"jupyter notebook",{"skillNo":109,"name":110,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":19},"01M69A1Q8EXPWKZSQK69V6WF22","deploying-scalable-agents","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fzh-TW\u002F.agents\u002Fskills\u002Fdeploying-scalable-agents\u002FSKILL.md",[],[114],"deploying scalable agents",{"skillNo":116,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":19},"01M69A1MHZTH3RH9N8VYSYG74X","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fzh-TW\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002FSKILL.md",[],[18]]