[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699T1WWFNKSE4FFSASTWKM4":3,"skill-same:01M699T1WWFNKSE4FFSASTWKM4":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},"01M699T1WWFNKSE4FFSASTWKM4","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\u002Fru\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> **Перед миграцией убедитесь, что ваше развертывание 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`**: Не поддерживается во многих моделях без рассуждений. Мигрируйте `reasoning` только если он уже был в исходном коде.\n> - **Параметр `seed`**: Не поддерживается в Responses API вообще — удалите из всех запросов.\n> - **Структурированный вывод через `text.format`**: Старые модели могут не надёжно применять JSON-схемы с `strict: true`.\n> - **Оркестрация инструментов**: GPT-5 и новее оркестрируют вызовы инструментов как часть внутренних рассуждений. Старые модели с Responses работают, но без глубокой интеграции.\n> - **Ограничения по температуре**: При миграции на `gpt-5` температуру нужно убирать или выставлять равной `1`. У старых моделей таких ограничений нет.\n\n### Модели серии O (o1, o3-mini, o3, o4-mini)\n\nМодели серии O имеют уникальные ограничения параметров. При миграции приложений, нацеленных на модели этой серии:\n\n- **`temperature`**: Должна быть `1` (или отсутствовать). Модели серии O не принимают другие значения.\n- **`max_completion_tokens` → `max_output_tokens`**: Приложения, использующие Azure-специфичный `max_completion_tokens`, должны перейти на `max_output_tokens`. Указывайте высокие значения (4096+), поскольку токены рассуждений учитываются в лимите.\n- **`reasoning_effort`**: Если приложение использует `reasoning_effort` (low\u002Fmedium\u002Fhigh), сохраняйте его — Responses API поддерживает этот параметр для моделей серии O.\n- **Поведение потоковой передачи**: Модели серии O могут буферизировать вывод до завершения рассуждений, прежде чем отправлять дельты текста. Потоковая передача всё ещё работает, но первый `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 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 — это серверная часть.** Мигрируйте ваш Python-бэкенд; HTTP-контракт фронтенда должен оставаться без изменений, если только ваш бэкенд не является легким прокси — в таком случае рассмотрите возможность использования формы запроса Responses для устранения слоя трансляции. Если фронтенд вызывает OpenAI напрямую с клиентским ключом, сначала перенесите эти вызовы на бэкенд.\n\n### Устаревание `@microsoft\u002Fai-chat-protocol`\n\nПакет `@microsoft\u002Fai-chat-protocol` для npm устарел и должен быть заменён на [`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()` к эндпоинту потоковой передачи на бэкенде.\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- Подготовить небольшие удобные для обзора наборы изменений и предоставить финальное резюме с диффами (не коммитить).\n\n---\n\n## Ограничения\n\n- Изменять только файлы внутри git-репозитория. Никогда не писать за его пределами.\n- Не сохранять шимы обратной совместимости; мигрировать код на новую структуру API.\n- Не оставлять комментарии переходного периода или резервные копии файлов.\n- Сохранять семантику потоковой передачи, если она использовалась ранее; иначе использовать непротоковый режим.\n- Запрашивать подтверждение перед выполнением команд или сетевых вызовов в режиме подтверждения.\n- Не выполнять `git add`, `git commit` или `git push`; генерировать только изменения в рабочем дереве.\n\n---\n\n## Шаг 0: Миграция клиента Azure OpenAI (предварительное условие)\n\nЕсли в кодовой базе используются конструкторы `AzureOpenAI` или `AsyncAzureOpenAI`, сначала мигрируйте их на стандартные конструкторы `OpenAI` \u002F `AsyncOpenAI`. Azure-специфические конструкторы устарели в `openai>=1.108.1`.\n\n### Почему путь API v1?\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-ключ, мультиарендность) смотрите [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` в разговор (а не ручной словарь `{\"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` в 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\": \"...\"}` на плоскую строку. Смотрите шпаргалку для примеров до и после.\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`. Тело ответа меняется: `choices[0].message.content` → `output[0].content[0].text` (примечание: `output_text` — удобное свойство SDK, отсутствует в сыром JSON REST).\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, либо 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 вызов функций | `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Для полных примеров кода до и после смотрите [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- Не полагайтесь на предыдущие 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.\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`; зависимости переустановлены.\n- [ ] В каждом вызове `responses.create` установлен `store=False`.\n- [ ] Нет `api_version` в конструкторе клиента; `AZURE_OPENAI_API_VERSION` удалён из файлов окружения и инфраструктуры.\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- В резюме указаны отредактированные файлы, количество устаревших вызовов до и после, а также следующие шаги.\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\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`**: Не поддерживается во многих моделях без рассуждений. Мигрируйте `reasoning` только если он уже был в исходном коде.\n> - **Параметр `seed`**: Не поддерживается в Responses API вообще — удалите из всех запросов.\n> - **Структурированный вывод через `text.format`**: Старые модели могут не надёжно применять JSON-схемы с `strict: true`.\n> - **Оркестрация инструментов**: GPT-5 и новее оркестрируют вызовы инструментов как часть внутренних рассуждений. Старые модели с Responses работают, но без глубокой интеграции.\n> - **Ограничения по температуре**: При миграции на `gpt-5` температуру нужно убирать или выставлять равной `1`. У старых моделей таких ограничений нет.\n\n### Модели серии O (o1, o3-mini, o3, o4-mini)\n\nМодели серии O имеют уникальные ограничения параметров. При миграции приложений, нацеленных на модели этой серии:\n\n- **`temperature`**: Должна быть `1` (или отсутствовать). Модели серии O не принимают другие значения.\n- **`max_completion_tokens` → `max_output_tokens`**: Приложения, использующие Azure-специфичный `max_completion_tokens`, должны перейти на `max_output_tokens`. Указывайте высокие значения (4096+), поскольку токены рассуждений учитываются в лимите.\n- **`reasoning_effort`**: Если приложение использует `reasoning_effort` (low\u002Fmedium\u002Fhigh), сохраняйте его — Responses API поддерживает этот параметр для моделей серии O.\n- **Поведение потоковой передачи**: Модели серии O могут буферизировать вывод до завершения рассуждений, прежде чем отправлять дельты текста. Потоковая передача всё ещё работает, но первый `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 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 — это серверная часть.** Мигрируйте ваш Python-бэкенд; HTTP-контракт фронтенда должен оставаться без изменений, если только ваш бэкенд не является легким прокси — в таком случае рассмотрите возможность использования формы запроса Responses для устранения слоя трансляции. Если фронтенд вызывает OpenAI напрямую с клиентским ключом, сначала перенесите эти вызовы на бэкенд.\n\n### Устаревание `@microsoft\u002Fai-chat-protocol`\n\nПакет `@microsoft\u002Fai-chat-protocol` для npm устарел и должен быть заменён на [`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()` к эндпоинту потоковой передачи на бэкенде.\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- Подготовить небольшие удобные для обзора наборы изменений и предоставить финальное резюме с диффами (не коммитить).\n\n---\n\n## Ограничения\n\n- Изменять только файлы внутри git-репозитория. Никогда не писать за его пределами.\n- Не сохранять шимы обратной совместимости; мигрировать код на новую структуру API.\n- Не оставлять комментарии переходного периода или резервные копии файлов.\n- Сохранять семантику потоковой передачи, если она использовалась ранее; иначе использовать непротоковый режим.\n- Запрашивать подтверждение перед выполнением команд или сетевых вызовов в режиме подтверждения.\n- Не выполнять `git add`, `git commit` или `git push`; генерировать только изменения в рабочем дереве.\n\n---\n\n## Шаг 0: Миграция клиента Azure OpenAI (предварительное условие)\n\nЕсли в кодовой базе используются конструкторы `AzureOpenAI` или `AsyncAzureOpenAI`, сначала мигрируйте их на стандартные конструкторы `OpenAI` \u002F `AsyncOpenAI`. Azure-специфические конструкторы устарели в `openai>=1.108.1`.\n\n### Почему путь API v1?\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-ключ, мультиарендность) смотрите [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` в разговор (а не ручной словарь `{\"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` в 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\": \"...\"}` на плоскую строку. Смотрите шпаргалку для примеров до и после.\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`. Тело ответа меняется: `choices[0].message.content` → `output[0].content[0].text` (примечание: `output_text` — удобное свойство SDK, отсутствует в сыром JSON REST).\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, либо 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 вызов функций | `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Для полных примеров кода до и после смотрите [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- Не полагайтесь на предыдущие 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.\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`; зависимости переустановлены.\n- [ ] В каждом вызове `responses.create` установлен `store=False`.\n- [ ] Нет `api_version` в конструкторе клиента; `AZURE_OPENAI_API_VERSION` удалён из файлов окружения и инфраструктуры.\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- В резюме указаны отредактированные файлы, количество устаревших вызовов до и после, а также следующие шаги.\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\u002Fru\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\u002Fru\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","参考文档",35993,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fru\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",9430,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fru\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Freferences\u002Ftest-migration.md",{"path":59,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":60,"sourceHtmlUrl":61},"references\u002Ftroubleshooting.md",23292,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fru\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]]