[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699VBT0AR1E02QS6K0B5WH9":3,"skill-same:01M699VBT0AR1E02QS6K0B5WH9":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},"01M699VBT0AR1E02QS6K0B5WH9","azure-openai-to-responses",null,"microsoft\u002Fai-agents-for-beginners","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M6998ZK2275KMJE6Y5SEA2X2",79567,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fsr\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 endpoint-ом\n- Поправи упозорења о кварању због `AzureOpenAI` конструкторе или `api_version`\n\n---\n\n## ⚠️ Компатибилност модела — ПРОВЕРИТЕ ПРВО\n\n> **Пре миграције, проверите да ли ваша 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> **Напомена**: `max_output_tokens` има **минимум 16** на Azure OpenAI. Вредности испод 16 враћају грешку 400. За брзе тестове користите 50+.\n\nАко ово врати 404, модел на имплементацији још не подржава 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`**: Неподржан на многим моделима без rasuđivanja. Мигрирајте `reasoning` само ако је већ био присутан у оригиналном коду.\n> - **параметар `seed`**: Уопште није подржан у Responses API — уклоните из свих захтева.\n> - **Структурирани излаз преко `text.format`**: Старији модели можда не примењују поуздано `strict: true` JSON шеме.\n> - **Оркестрација алата**: GPT-5+ оркестрира позиве алата као део интерног расуђивања. Старији модели на Responses раде али без ове дубоке интеграције.\n> - **Ограничења температуре**: При миграцији на `gpt-5`, температура мора бити изостављена или постављена на `1`. Старији модели немају овакво ограничење.\n\n### O-серија модела за расуђивање (o1, o3-mini, o3, o4-mini)\n\nO-серија модели имају јединствена ограничења параметара. При миграцији апликација које циљају o-серију:\n\n- **`temperature`**: Мора бити `1` (или изостављен). O-серија модели не прихватају друге вредности.\n- **`max_completion_tokens` → `max_output_tokens`**: Апликације које користе Azure-специфични `max_completion_tokens` морају прелазити на `max_output_tokens`. Подесите високе вредности (4096+) јер tokeni за rasuđivanje улазe у лимит.\n- **`reasoning_effort`**: Ако апликација користи `reasoning_effort` (low\u002Fmedium\u002Fhigh), задржите га — Responses API подржава овај параметар за o-серију модела.\n- **Понашање стримовања**: O-серија модели можда кеширају излаз док се rasuđivanje не заврши пре емитовања текстуалних delta догађаја. Стримовање и даље ради, али први `response.output_text.delta` може стићи са дужим закашњењем него код GPT модела.\n- **`top_p`**: Неподржан на o-серији — уклоните ако је присутан.\n- **Коришћење алата**: O-серија модели подржавају алате преко Responses API исто као GPT модели, али квалитет оркестрације позива алата варира по моделу.\n\n**Акција — проактивни савет о моделу**: Током фазе скенирања провјерите који модел апликација користи (називи имплементација, окружене променљиве, конфигурација). Ако је модел старији од `gpt-4.1` (не gpt-4.1+), проактивно обавестите корисника:\n- Миграција ће радити за основни текст, ћаскање, стримовање и алате са њиховим тренутним моделом.\n- Новији модели (`gpt-5.1`, `gpt-5.2`) нуде бољу оркестрацију алата, примену структурираног излаза, расуђивање и доступност преко региона.\n- Требало би да размотре надоградњу имплементације кад буду спремни — то не блокира миграцију.\n\nНе блокирајте и не одбијајте миграцију због верзије модела. Савет је информативан.\n\n### GitHub модели НЕ подржавају Responses API\n\n> **GitHub модели (`models.github.ai`, `models.inference.ai.azure.com`) не подржавају Responses API.**\n\nАко кодна база има кодни пут за GitHub моделе (потражите `base_url` који указује на `models.github.ai` или `models.inference.ai.azure.com`), **уклоните га у потпуности** током миграције. Responses API захтева Azure OpenAI, OpenAI или компатибилан локални endpoint (нпр. Ollama са Responses подршком).\n\nАкција током скенирања:\n- Обележите све кодне путеве GitHub модела за уклањање.\n\n---\n\n## Миграција оквира (framework-a)\n\nМноге апликације користе вишем нивоу оквире изнад OpenAI. При миграцији ових, мења се сопствени API оквира — не само основни OpenAI позиви.\n\n### Microsoft Agent Framework (MAF)\n\n**Прво проверите вашу верзију MAF-а** — миграција зависи од тога да ли сте на MAF 1.0.0+ или пре-1.0.0 бета\u002Frc верзијама.\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У пре-1.0.0 MAF, `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За комплетне примере кода пре\u002Fпосле гледајте [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\n---\n\n## Упутства за миграцију фронтенда\n\n> **Responses API је ствар серверске стране.** Мигрирајте Python backend; HTTP ugovor фронтенда треба остати непромењен осим ако ваш backend није само танак пролаз — у том случају размотрите прилагођавање облика Responses захтева да елиминишете слој превођења. Ако фронтенд директно позива OpenAI са клијентским кључем, прво преместите те позиве на backend.\n\n### `@microsoft\u002Fai-chat-protocol` депрецатион\n\nnpm пакет `@microsoft\u002Fai-chat-protocol` је депрецатион и треба га заменити са [`ndjson-readablestream`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fndjson-readablestream). Ако га пронађете у фронтенду:\n\n1. Замените CDN script tag:\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 стриминг endpoint.\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 или Legacy Completions са Azure OpenAI.\n- Предложити план миграције и редослед за Python код.\n- Примени безбедне, минималне измене за прелазак на Responses API.\n- Ажурирати позиваче за коришћење Responses output шеме; без штићених замотача.\n- Покренути тестове\u002Fлінтове; поправити тривијалне грешке настале миграцијом.\n- Припремити мале, прегледне скупове промена и пружити коначни резиме са дифовима (не комитујте).\n\n---\n\n## Ограничења (Guardrails)\n\n- Мењати само фајлове унутар git workspace-а. Никада не писати изван.\n- Не чувати шиме за назадну компатибилност; мигрирајте код на нови облик API.\n- Не остављати коментаре за транзицију или бекуп фајлове.\n- Очувати семантику стримовања ако је раније коришћена; иначе користити нестреминг.\n- Тражити одобрење пре покретања команди или мрежних позива у режиму одобрења.\n- Не покретати `git add`\u002F`git commit`\u002F`git push`; радити само измене у радном простору.\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` endpoint користи стандардни `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\u002Finfra фајлова.\n- Преименовати `AZURE_OPENAI_CLIENT_ID` у `AZURE_CLIENT_ID` у `.env`, подешавањима апликације, Bicep\u002Finfra и тест фиxtures (стандардна Azure Identity SDK конвенција).\n- Осигурати `openai>=1.108.1` у `requirements.txt` или `pyproject.toml`.\n\n### Миграција окружења\n\n| Стари env var | Акција | Напомене |\n|-------------|--------|----------|\n| `AZURE_OPENAI_VERSION` | **Уклони** | Није потребно са v1 endpoint-ом |\n| `AZURE_OPENAI_API_VERSION` | **Уклони** | Исто као горе |\n| `AZURE_OPENAI_CLIENT_ID` | **Преимenuј** → `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 кључ, мултитенант), видети [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 Models крајње тачке (морају се уклонити — Responses 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` у разговор (не ручни речник `{\"role\": \"assistant\", \"tool_calls\": [...]}`), затим додај ставке `function_call_output` за сваки резултат.\n- **Примери за неколико позива алата**: ако разговор укључује примерима позива алата у коду, претвори их у `{\"type\": \"function_call\", \"id\": \"fc_...\", \"call_id\": \"fc_...\", ...}` + `{\"type\": \"function_call_output\", ...}` ставке. ИД-ови морају почети од `fc_`.\n- **`pydantic_function_tool()`**: овај помоћни алат још увек генерише стари уметнути формат и **није компатибилан** са `responses.create()`. Замени ручним дефиницијама алата или омотачем за раван формат.\n- **Више корака**: одржавај историју разговора у апликацији; претходне кораке прослеђуј кроз ставке `input`.\n- **Форматирање**: замени горњи `response_format` из Чата са `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- **Руковање грешкама филтера садржаја**: структура тела грешке се променила. Chat Completions је користио `error.body[\"innererror\"][\"content_filter_result\"]` (једнина); Responses API користи `error.body[\"content_filters\"][0][\"content_filter_results\"]` (множеина, унутар низа). Код који приступа `innererror` ће изазвати `KeyError`. Препиши да користи нови пут.\n- **Сирови HTTP позиви**: ако апликација директно позива Azure OpenAI REST API (путем `requests`, `httpx`, итд.) користећи `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions?api-version=...`, препиши на `\u002Fopenai\u002Fv1\u002Fresponses`. Тело захтева се мења: `messages` → `input`, додај `max_output_tokens` и `store: false`, уклони `api-version` query параметар. Тело одговора се мења: `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`. `temperature` остаје иста.\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\": \"...\"}` (обичан низ — или HTTPS URL или `data:image\u002F...;base64,...` data URI).\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За миграцију тест инфраструктуре (мокови, снимци, асертиције), види [test-migration.md](.\u002Freferences\u002Ftest-migration.md).\n\nЗа решавање грешака и проблематика, види [troubleshooting.md](.\u002Freferences\u002Ftroubleshooting.md).\n\n---\n\n## Чување података и стање\n\n- Постави `store: false` на све захтеве Responses.\n- Не ослањај се на претходне ИД-ове порука или контекст чuvan на серверу; одржавај стање под управом клијента и минимизирај метаподатке.\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 output шему.\n- [ ] Нема `response_format` на горњем нивоу; сваки структуирани излаз користи `text={\"format\": {...}}`.\n- [ ] `openai>=1.108.1` и `azure-identity` у `requirements.txt` или `pyproject.toml`; зависности поново инсталиране.\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` — асертиције ажуриране да провере `isinstance(client, AsyncOpenAI)` или `base_url`.\n- [ ] Ниједно поклапање за `rg \"prompt_filter_results|content_filter_results\" tests\u002F` — уклоњени Azure-специфични филтер мокови.\n- [ ] Мок фикстуре користе `kwargs.get(\"input\")` а не `kwargs.get(\"messages\")`.\n- [ ] Снимци\u002Fголд файлови ажурирани на 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- Резиме укључује измењене фајлове, број позива Legacy пре\u002Fпосле и следеће кораке.\n- Промене су само радне копије (без комита).\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- [Миграција теста — мокови, снимци, асертиције](.\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Овај документ је преведен коришћењем услуге за аутоматски превод [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 endpoint-ом\n- Поправи упозорења о кварању због `AzureOpenAI` конструкторе или `api_version`\n\n---\n\n## ⚠️ Компатибилност модела — ПРОВЕРИТЕ ПРВО\n\n> **Пре миграције, проверите да ли ваша 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> **Напомена**: `max_output_tokens` има **минимум 16** на Azure OpenAI. Вредности испод 16 враћају грешку 400. За брзе тестове користите 50+.\n\nАко ово врати 404, модел на имплементацији још не подржава 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`**: Неподржан на многим моделима без rasuđivanja. Мигрирајте `reasoning` само ако је већ био присутан у оригиналном коду.\n> - **параметар `seed`**: Уопште није подржан у Responses API — уклоните из свих захтева.\n> - **Структурирани излаз преко `text.format`**: Старији модели можда не примењују поуздано `strict: true` JSON шеме.\n> - **Оркестрација алата**: GPT-5+ оркестрира позиве алата као део интерног расуђивања. Старији модели на Responses раде али без ове дубоке интеграције.\n> - **Ограничења температуре**: При миграцији на `gpt-5`, температура мора бити изостављена или постављена на `1`. Старији модели немају овакво ограничење.\n\n### O-серија модела за расуђивање (o1, o3-mini, o3, o4-mini)\n\nO-серија модели имају јединствена ограничења параметара. При миграцији апликација које циљају o-серију:\n\n- **`temperature`**: Мора бити `1` (или изостављен). O-серија модели не прихватају друге вредности.\n- **`max_completion_tokens` → `max_output_tokens`**: Апликације које користе Azure-специфични `max_completion_tokens` морају прелазити на `max_output_tokens`. Подесите високе вредности (4096+) јер tokeni за rasuđivanje улазe у лимит.\n- **`reasoning_effort`**: Ако апликација користи `reasoning_effort` (low\u002Fmedium\u002Fhigh), задржите га — Responses API подржава овај параметар за o-серију модела.\n- **Понашање стримовања**: O-серија модели можда кеширају излаз док се rasuđivanje не заврши пре емитовања текстуалних delta догађаја. Стримовање и даље ради, али први `response.output_text.delta` може стићи са дужим закашњењем него код GPT модела.\n- **`top_p`**: Неподржан на o-серији — уклоните ако је присутан.\n- **Коришћење алата**: O-серија модели подржавају алате преко Responses API исто као GPT модели, али квалитет оркестрације позива алата варира по моделу.\n\n**Акција — проактивни савет о моделу**: Током фазе скенирања провјерите који модел апликација користи (називи имплементација, окружене променљиве, конфигурација). Ако је модел старији од `gpt-4.1` (не gpt-4.1+), проактивно обавестите корисника:\n- Миграција ће радити за основни текст, ћаскање, стримовање и алате са њиховим тренутним моделом.\n- Новији модели (`gpt-5.1`, `gpt-5.2`) нуде бољу оркестрацију алата, примену структурираног излаза, расуђивање и доступност преко региона.\n- Требало би да размотре надоградњу имплементације кад буду спремни — то не блокира миграцију.\n\nНе блокирајте и не одбијајте миграцију због верзије модела. Савет је информативан.\n\n### GitHub модели НЕ подржавају Responses API\n\n> **GitHub модели (`models.github.ai`, `models.inference.ai.azure.com`) не подржавају Responses API.**\n\nАко кодна база има кодни пут за GitHub моделе (потражите `base_url` који указује на `models.github.ai` или `models.inference.ai.azure.com`), **уклоните га у потпуности** током миграције. Responses API захтева Azure OpenAI, OpenAI или компатибилан локални endpoint (нпр. Ollama са Responses подршком).\n\nАкција током скенирања:\n- Обележите све кодне путеве GitHub модела за уклањање.\n\n---\n\n## Миграција оквира (framework-a)\n\nМноге апликације користе вишем нивоу оквире изнад OpenAI. При миграцији ових, мења се сопствени API оквира — не само основни OpenAI позиви.\n\n### Microsoft Agent Framework (MAF)\n\n**Прво проверите вашу верзију MAF-а** — миграција зависи од тога да ли сте на MAF 1.0.0+ или пре-1.0.0 бета\u002Frc верзијама.\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У пре-1.0.0 MAF, `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За комплетне примере кода пре\u002Fпосле гледајте [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\n---\n\n## Упутства за миграцију фронтенда\n\n> **Responses API је ствар серверске стране.** Мигрирајте Python backend; HTTP ugovor фронтенда треба остати непромењен осим ако ваш backend није само танак пролаз — у том случају размотрите прилагођавање облика Responses захтева да елиминишете слој превођења. Ако фронтенд директно позива OpenAI са клијентским кључем, прво преместите те позиве на backend.\n\n### `@microsoft\u002Fai-chat-protocol` депрецатион\n\nnpm пакет `@microsoft\u002Fai-chat-protocol` је депрецатион и треба га заменити са [`ndjson-readablestream`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fndjson-readablestream). Ако га пронађете у фронтенду:\n\n1. Замените CDN script tag:\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 стриминг endpoint.\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 или Legacy Completions са Azure OpenAI.\n- Предложити план миграције и редослед за Python код.\n- Примени безбедне, минималне измене за прелазак на Responses API.\n- Ажурирати позиваче за коришћење Responses output шеме; без штићених замотача.\n- Покренути тестове\u002Fлінтове; поправити тривијалне грешке настале миграцијом.\n- Припремити мале, прегледне скупове промена и пружити коначни резиме са дифовима (не комитујте).\n\n---\n\n## Ограничења (Guardrails)\n\n- Мењати само фајлове унутар git workspace-а. Никада не писати изван.\n- Не чувати шиме за назадну компатибилност; мигрирајте код на нови облик API.\n- Не остављати коментаре за транзицију или бекуп фајлове.\n- Очувати семантику стримовања ако је раније коришћена; иначе користити нестреминг.\n- Тражити одобрење пре покретања команди или мрежних позива у режиму одобрења.\n- Не покретати `git add`\u002F`git commit`\u002F`git push`; радити само измене у радном простору.\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` endpoint користи стандардни `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\u002Finfra фајлова.\n- Преименовати `AZURE_OPENAI_CLIENT_ID` у `AZURE_CLIENT_ID` у `.env`, подешавањима апликације, Bicep\u002Finfra и тест фиxtures (стандардна Azure Identity SDK конвенција).\n- Осигурати `openai>=1.108.1` у `requirements.txt` или `pyproject.toml`.\n\n### Миграција окружења\n\n| Стари env var | Акција | Напомене |\n|-------------|--------|----------|\n| `AZURE_OPENAI_VERSION` | **Уклони** | Није потребно са v1 endpoint-ом |\n| `AZURE_OPENAI_API_VERSION` | **Уклони** | Исто као горе |\n| `AZURE_OPENAI_CLIENT_ID` | **Преимenuј** → `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 кључ, мултитенант), видети [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 Models крајње тачке (морају се уклонити — Responses 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` у разговор (не ручни речник `{\"role\": \"assistant\", \"tool_calls\": [...]}`), затим додај ставке `function_call_output` за сваки резултат.\n- **Примери за неколико позива алата**: ако разговор укључује примерима позива алата у коду, претвори их у `{\"type\": \"function_call\", \"id\": \"fc_...\", \"call_id\": \"fc_...\", ...}` + `{\"type\": \"function_call_output\", ...}` ставке. ИД-ови морају почети од `fc_`.\n- **`pydantic_function_tool()`**: овај помоћни алат још увек генерише стари уметнути формат и **није компатибилан** са `responses.create()`. Замени ручним дефиницијама алата или омотачем за раван формат.\n- **Више корака**: одржавај историју разговора у апликацији; претходне кораке прослеђуј кроз ставке `input`.\n- **Форматирање**: замени горњи `response_format` из Чата са `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- **Руковање грешкама филтера садржаја**: структура тела грешке се променила. Chat Completions је користио `error.body[\"innererror\"][\"content_filter_result\"]` (једнина); Responses API користи `error.body[\"content_filters\"][0][\"content_filter_results\"]` (множеина, унутар низа). Код који приступа `innererror` ће изазвати `KeyError`. Препиши да користи нови пут.\n- **Сирови HTTP позиви**: ако апликација директно позива Azure OpenAI REST API (путем `requests`, `httpx`, итд.) користећи `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions?api-version=...`, препиши на `\u002Fopenai\u002Fv1\u002Fresponses`. Тело захтева се мења: `messages` → `input`, додај `max_output_tokens` и `store: false`, уклони `api-version` query параметар. Тело одговора се мења: `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`. `temperature` остаје иста.\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\": \"...\"}` (обичан низ — или HTTPS URL или `data:image\u002F...;base64,...` data URI).\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За миграцију тест инфраструктуре (мокови, снимци, асертиције), види [test-migration.md](.\u002Freferences\u002Ftest-migration.md).\n\nЗа решавање грешака и проблематика, види [troubleshooting.md](.\u002Freferences\u002Ftroubleshooting.md).\n\n---\n\n## Чување података и стање\n\n- Постави `store: false` на све захтеве Responses.\n- Не ослањај се на претходне ИД-ове порука или контекст чuvan на серверу; одржавај стање под управом клијента и минимизирај метаподатке.\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 output шему.\n- [ ] Нема `response_format` на горњем нивоу; сваки структуирани излаз користи `text={\"format\": {...}}`.\n- [ ] `openai>=1.108.1` и `azure-identity` у `requirements.txt` или `pyproject.toml`; зависности поново инсталиране.\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` — асертиције ажуриране да провере `isinstance(client, AsyncOpenAI)` или `base_url`.\n- [ ] Ниједно поклапање за `rg \"prompt_filter_results|content_filter_results\" tests\u002F` — уклоњени Azure-специфични филтер мокови.\n- [ ] Мок фикстуре користе `kwargs.get(\"input\")` а не `kwargs.get(\"messages\")`.\n- [ ] Снимци\u002Fголд файлови ажурирани на 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- Резиме укључује измењене фајлове, број позива Legacy пре\u002Fпосле и следеће кораке.\n- Промене су само радне копије (без комита).\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- [Миграција теста — мокови, снимци, асертиције](.\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Овај документ је преведен коришћењем услуге за аутоматски превод [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\u002Fsr\u002F.agents\u002Fskills\u002Fazure-openai-to-responses",26057,"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\u002Fsr\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","参考文档",34446,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fsr\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",8949,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fsr\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Freferences\u002Ftest-migration.md",{"path":59,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":60,"sourceHtmlUrl":61},"references\u002Ftroubleshooting.md",21410,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fsr\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]]