[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699RRRF9F9414WZ4CTN1EYT":3,"skill-same:01M699RRRF9F9414WZ4CTN1EYT":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},"01M699RRRF9F9414WZ4CTN1EYT","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\u002Fpt-BR\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# Migrar Aplicativos Python de Azure OpenAI Chat Completions para Responses API\n\n> **ORIENTAÇÃO AUTORITATIVA — SIGA EXATAMENTE**\n>\n> Esta habilidade migra bases de código Python que usam Azure OpenAI Chat Completions\n> para a Responses API unificada. Siga estas instruções com precisão.\n> Não improvise mapeamentos de parâmetros nem invente formatos de API.\n\n---\n\n## Gatilhos\n\nAtive esta habilidade quando o usuário quiser:\n- Migrar um app Python de Azure OpenAI Chat Completions para Responses API\n- Atualizar o uso do SDK Python OpenAI para o formato mais recente da API contra Azure OpenAI\n- Preparar código Python para modelos GPT-5 ou mais recentes que requerem Responses na Azure\n- Mudar de `AzureOpenAI`\u002F`AsyncAzureOpenAI` para o cliente padrão `OpenAI`\u002F`AsyncOpenAI` com o endpoint v1\n- Corrigir avisos de depreciação relacionados a construtores `AzureOpenAI` ou `api_version`\n\n---\n\n## ⚠️ Compatibilidade de Modelo — VERIFIQUE PRIMEIRO\n\n> **Antes de migrar, verifique se sua implantação Azure OpenAI suporta a Responses API.**\n\n### 1. Teste simples da implantação (mais rápido)\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> **Nota**: `max_output_tokens` tem um **mínimo de 16** na Azure OpenAI. Valores abaixo de 16 retornam erro 400. Use 50+ para testes simples.\n\nSe isto retornar 404, o modelo da implantação ainda não suporta Responses — consulte a referência abaixo ou reimplemente com um modelo suportado.\n\n### 2. Verifique os modelos disponíveis na sua região (recomendado)\n\nExecute a ferramenta embutida de compatibilidade de modelos para ver o que está disponível com suporte à Responses API em sua região específica:\n\n```bash\npython migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION\n```\n\nEsta consulta à Azure ARM ao vivo mostra uma matriz de compatibilidade — quais modelos suportam Responses, saída estruturada, ferramentas, etc. Use `--filter gpt-5.1,gpt-5.2` para filtrar resultados ou `--json` para script.\n\n### 3. Referência completa de suporte a modelos\n\n- **Consulta ao vivo**: `python migrate.py models` (veja acima — específico por região, sempre atualizado)\n- **Navegue disponibilidade**: [Tabela resumo de modelos e disponibilidade regional](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- **Início rápido e orientações**: **https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart**\n\n### ⚠️ Limitações de modelos antigos\n\n> **AVISO**: Modelos antigos (anteriores a `gpt-4.1`) podem não suportar totalmente todos os recursos da Responses API.\n>\n> Limitações conhecidas com modelos antigos:\n> - **Parâmetro `reasoning`**: Não suportado em muitos modelos sem raciocínio. Migrar `reasoning` só se já estiver presente no código original.\n> - **Parâmetro `seed`**: Não suportado na Responses API — remova de todas as requisições.\n> - **Saída estruturada via `text.format`**: Modelos antigos podem não aplicar esquemas JSON `strict: true` de forma confiável.\n> - **Orquestração de ferramentas**: GPT-5+ orquestra chamadas de ferramentas como parte do raciocínio interno. Modelos antigos no Responses funcionam, mas sem essa integração profunda.\n> - **Restrições de temperatura**: Ao migrar para `gpt-5`, a temperatura deve ser omitida ou definida como `1`. Modelos antigos não têm essa restrição.\n\n### Modelos de raciocínio da série O (o1, o3-mini, o3, o4-mini)\n\nModelos da série O têm restrições exclusivas de parâmetros. Ao migrar apps que usam modelos da série O:\n\n- **`temperature`**: Deve ser `1` (ou omitido). Modelos da série O não aceitam outros valores.\n- **`max_completion_tokens` → `max_output_tokens`**: Apps usando o específico `max_completion_tokens` do Azure devem mudar para `max_output_tokens`. Defina valores altos (4096+) pois tokens de raciocínio contam no limite.\n- **`reasoning_effort`**: Se o app usa `reasoning_effort` (baixo\u002Fmédio\u002Falto), mantenha — a Responses API suporta esse parâmetro para modelos da série O.\n- **Comportamento de streaming**: Modelos da série O podem armazenar saída até o raciocínio finalizar antes de emitir eventos de delta de texto. Streaming ainda funciona, mas o primeiro `response.output_text.delta` pode chegar com delay maior que em modelos GPT.\n- **`top_p`**: Não suportado na série O — remova se presente.\n- **Uso de ferramentas**: Modelos da série O suportam ferramentas pela Responses API igual aos modelos GPT, mas a qualidade da orquestração varia com o modelo.\n\n**Ação — aviso proativo de modelo**: Durante a fase de análise, verifique qual modelo o app usa (nomes de implantação, variáveis de ambiente, config). Se o modelo for anterior a `gpt-4.1` (não gpt-4.1+), informe proativamente ao usuário:\n- A migração funcionará para texto básico, chat, streaming e ferramentas no modelo atual.\n- Modelos mais novos (`gpt-5.1`, `gpt-5.2`) oferecem melhor orquestração de ferramentas, aplicação de saída estruturada, raciocínio e disponibilidade cross-region.\n- Ele deve considerar atualizar a implantação quando quiser — não bloqueia a migração.\n\nNão bloqueie nem recuse a migração por versão do modelo. O aviso é informativo.\n\n### GitHub Models NÃO suporta a Responses API\n\n> **GitHub Models (`models.github.ai`, `models.inference.ai.azure.com`) não suporta a Responses API.**\n\nSe a base de código tiver um caminho de código GitHub Models (procure `base_url` apontando para `models.github.ai` ou `models.inference.ai.azure.com`), **remova completamente** durante a migração. A Responses API requer Azure OpenAI, OpenAI, ou endpoint local compatível (ex: Ollama com suporte a Responses).\n\nAção durante a análise:\n- Identifique qualquer caminho de código GitHub Models para remoção.\n\n---\n\n## Migração de Framework\n\nMuitos apps usam frameworks de nível superior sobre OpenAI. Ao migrar, alteram-se também as APIs do framework — não apenas as chamadas subjacentes OpenAI.\n\n### Microsoft Agent Framework (MAF)\n\n**Verifique sua versão do MAF primeiro** — a migração depende se você está no MAF 1.0.0+ ou numa beta\u002Frc pré-1.0.0.\n\n#### MAF 1.0.0+ (agent-framework-openai >= 1.0.0)\n\n`OpenAIChatClient` **já usa Responses API** — não precisa migrar. Se o código usa o legado `OpenAIChatCompletionClient` (que usa `chat.completions.create`), substitua por `OpenAIChatClient`.\n\n| Antes | Depois |\n|--------|-------|\n| `from agent_framework.openai import OpenAIChatCompletionClient` | `from agent_framework.openai import OpenAIChatClient` |\n| `OpenAIChatCompletionClient(...)` | `OpenAIChatClient(...)` |\n\nPara checar sua versão: `python -c \"import agent_framework_openai; print(agent_framework_openai.__version__)\"`\n\n#### MAF pré-1.0.0 (lançamentos beta\u002Frc)\n\nNo MAF pré-1.0.0, `OpenAIChatClient` usava Chat Completions. Atualize para `agent-framework-openai>=1.0.0` onde `OpenAIChatClient` usa Responses API por padrão.\n\nNenhuma outra mudança necessária — as APIs `Agent` e de ferramentas permanecem iguais.\n\n### LangChain (`langchain-openai`)\n\nAdicione `use_responses_api=True` a `ChatOpenAI()`. Também atualize o acesso à resposta de `.content` para `.text`.\n\n| Antes | Depois |\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\nPara exemplos completos de código antes\u002Fdepois, veja [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\n---\n\n## Orientação para Migração do Frontend\n\n> **A Responses API é uma preocupação do lado servidor.** Migre seu backend Python; o contrato HTTP do frontend deve permanecer inalterado, a menos que seu backend seja uma passagem fina — nesse caso, considere adotar o formato Requests Responses para eliminar uma camada de tradução. Se o frontend chama OpenAI diretamente com chave no cliente, mova essas chamadas para o backend primeiro.\n\n### Depreciação do `@microsoft\u002Fai-chat-protocol`\n\nO pacote npm `@microsoft\u002Fai-chat-protocol` está depreciado e deve ser substituído por [`ndjson-readablestream`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fndjson-readablestream). Se encontrá-lo em um frontend:\n\n1. Substitua a tag script 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. Remova a instanciação `AIChatProtocolClient` (`new ChatProtocol.AIChatProtocolClient(\"\u002Fchat\")`).\n3. Substitua `client.getStreamedCompletion(messages)` por uma chamada `fetch()` direta ao endpoint de streaming do backend.\n4. Substitua `for await (const response of result)` por `for await (const chunk of readNDJSONStream(response.body))`.\n5. Atualize o acesso a propriedades de `response.delta.content` \u002F `response.error` para `chunk.delta.content` \u002F `chunk.error`.\n\n---\n\n## Objetivos\n\n- Enumerar todos os pontos de chamadas Python que usam Chat Completions ou Completions legadas contra Azure OpenAI.\n- Propor um plano de migração e sequenciamento para a base de código Python.\n- Aplicar edições seguras e mínimas para mudar à Responses API.\n- Atualizar chamadores para consumir o esquema de saída do Responses; sem wrappers de retrocompatibilidade.\n- Rodar testes\u002Flints; corrigir quebras triviais causadas pela migração.\n- Preparar pequenos conjuntos de mudanças revisáveis e fornecer um resumo final com diffs (não commite).\n\n---\n\n## Limites de Segurança\n\n- Modifique apenas arquivos dentro da workspace git. Nunca escreva fora.\n- Não preserve shims de retrocompatibilidade; migre código para o novo formato da API.\n- Não deixe comentários de transição\u002Ftombstone ou arquivos de backup.\n- Preserve semântica de streaming se usada antes; senão use não streaming.\n- Peça aprovação antes de executar comandos ou chamadas de rede se estiver em modo de aprovação.\n- Não execute `git add`\u002F`git commit`\u002F`git push`; produza apenas edições na working tree.\n\n---\n\n## Passo 0: Migração do Cliente Azure OpenAI (Pré-requisito)\n\nSe a base de código usar construtores `AzureOpenAI` ou `AsyncAzureOpenAI`, migre primeiro para os construtores padrão `OpenAI` \u002F `AsyncOpenAI`. Os construtores específicos Azure estão depreciados em `openai>=1.108.1`.\n\n### Por que o caminho v1 da API?\n\nO novo endpoint `\u002Fopenai\u002Fv1` usa o cliente padrão `OpenAI()` em vez de `AzureOpenAI()`, não requer parâmetro `api_version`, e funciona exatamente igual em OpenAI e Azure OpenAI. O mesmo código cliente é à prova de futuro — não precisa gerenciar versões.\n\n### Mudanças principais\n\n| Antes | Depois |\n|--------|-------|\n| `AzureOpenAI` | `OpenAI` |\n| `AsyncAzureOpenAI` | `AsyncOpenAI` |\n| `azure_endpoint` | `base_url` |\n| `azure_ad_token_provider` | `api_key` |\n| `api_version=...` | Remova completamente |\n\n### Checklist de limpeza\n\n- Remova argumento `api_version` da construção do cliente.\n- Remova variáveis de ambiente `AZURE_OPENAI_VERSION` \u002F `AZURE_OPENAI_API_VERSION` de `.env`, configurações do app e arquivos Bicep\u002Finfra.\n- Renomeie `AZURE_OPENAI_CLIENT_ID` → `AZURE_CLIENT_ID` em `.env`, configurações do app, Bicep\u002Finfra, e fixtures de teste (convenção padrão SDK Azure Identity).\n- Garanta `openai>=1.108.1` em `requirements.txt` ou `pyproject.toml`.\n\n### Migração de variáveis de ambiente\n\n| Variável antiga | Ação | Notas |\n|-------------|--------|-------|\n| `AZURE_OPENAI_VERSION` | **Remover** | Não precisa de `api_version` com endpoint v1 |\n| `AZURE_OPENAI_API_VERSION` | **Remover** | Igual acima |\n| `AZURE_OPENAI_CLIENT_ID` | **Renomear** → `AZURE_CLIENT_ID` | Convenção padrão SDK Azure Identity para `ManagedIdentityCredential(client_id=...)` |\n| `AZURE_OPENAI_ENDPOINT` | **Manter** | Ainda necessário para construção de `base_url` |\n| `AZURE_OPENAI_CHAT_DEPLOYMENT` | **Manter** | Usado como parâmetro `model` em `responses.create` |\n| `AZURE_OPENAI_API_KEY` | **Manter** | Usado como `api_key` para autenticação por chave |\n\nPara exemplos de configuração de cliente (sync, async, EntraID, chave API, multi-tenant), veja [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\n---\n\n## Passo 1: Detectar Pontos de Chamadas Legadas\n\nExecute o script [detect_legacy.py](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py) para encontrar todos os pontos de chamada que precisam migrar:\n\n```bash\npython skills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py .\n```\n\nOu faça buscas manuais — cada correspondência é um alvo de migração:\n\n```bash\n# Chamadas de API legadas (precisa reescrever)\nrg \"chat\\.completions\\.create\"\nrg \"ChatCompletion\\.create\"\nrg \"Completion\\.create\"\n\n# Construtores de cliente Azure obsoletos (precisa substituir)\nrg \"AzureOpenAI\\(\"\nrg \"AsyncAzureOpenAI\\(\"\n\n# Padrões de acesso à forma da resposta (precisa atualizar)\nrg \"choices\\[0\\]\\.message\\.content\"\nrg \"choices\\[0\\]\\.delta\\.content\"\nrg \"choices\\[0\\]\\.message\\.function_call\"\nrg \"choices\\[0\\]\\.message\\.tool_calls\"\n\n# Definições de ferramentas em formato antigo aninhado (precisa achatar)\nrg '\"function\":\\s*{\\s*\"name\"'\nrg \"pydantic_function_tool\"\n\n# Resultados da ferramenta em formato antigo (precisa converter para function_call_output)\nrg '\"role\":\\s*\"tool\"'\nrg '\"tool_call_id\"'\n\n# Parâmetros obsoletos (precisa remover ou renomear)\nrg \"response_format\"\nrg \"max_tokens\\b\"        # renomear para max_output_tokens\nrg \"['\\\"]seed['\\\"]\"      # remove entirely\n\n# Variáveis de ambiente obsoletas (limpar)\nrg \"AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION\"\nrg \"AZURE_OPENAI_CLIENT_ID\"  # deveria ser AZURE_CLIENT_ID\n\n# Endpoints de Modelos do GitHub (precisa remover — API de Respostas não suportada)\nrg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"\n\n# Padrões legados no nível do framework (precisa atualizar)\nrg \"OpenAIChatCompletionClient\"  # MAF 1.0.0+: substituir por OpenAIChatClient\nrg \"ChatOpenAI\\(\" | grep -v \"use_responses_api\"  # LangChain: precisa de use_responses_api=True\n\n# Infraestrutura de teste (precisa atualizar)\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# Acesso ao corpo de erro do filtro de conteúdo (precisa atualizar — estrutura mudou)\nrg 'innererror.*content_filter_result|error\\.body\\[\"innererror\"\\]'\nrg \"content_filter_result\\[\" # forma singular antiga — agora content_filter_results (plural) dentro do array content_filters\n\n# Chamadas HTTP brutas para o endpoint de Chat Completions (precisa atualizar URL)\nrg \"\u002Fopenai\u002Fdeployments\u002F.*\u002Fchat\u002Fcompletions\"\nrg \"api-version=\"\n```\n\n### Heurísticas (detectar e reescrever)\n\n- **Cliente Chat Completions**: `client.chat.completions.create` → `client.responses.create(...)`.\n\n- **Construtores de cliente Azure**: `AzureOpenAI(...)` → `OpenAI(base_url=..., api_key=...)`.\n- **Ferramentas**: converta definições de ferramentas com chamada de função do formato aninhado (`{\"type\": \"function\", \"function\": {\"name\": ...}}`) para o formato plano do Responses (`{\"type\": \"function\", \"name\": ...}`); use `tool_choice`; retorne resultados das ferramentas como itens `{\"type\": \"function_call_output\", \"call_id\": ..., \"output\": ...}` (não `{\"role\": \"tool\", ...}`).\n- **Ciclo das ferramentas**: quando o modelo retornar chamadas de funções, anexe os itens `response.output` à conversa (não um dicionário manual `{\"role\": \"assistant\", \"tool_calls\": [...]}`), depois anexe os itens `function_call_output` para cada resultado.\n- **Exemplos de ferramentas few-shot**: se a conversa incluir exemplos embutidos de chamadas de ferramentas, converta-os em itens `{\"type\": \"function_call\", \"id\": \"fc_...\", \"call_id\": \"fc_...\", ...}` + `{\"type\": \"function_call_output\", ...}`. IDs devem começar com `fc_`.\n- **`pydantic_function_tool()`**: esse auxiliar ainda gera o formato aninhado antigo e **não é compatível** com `responses.create()`. Substitua por definições manuais de ferramentas ou um wrapper de achatamento.\n- **Multi-turn**: mantenha o histórico da conversa na aplicação; passe turnos anteriores via itens `input`.\n- **Formatação**: substitua o `response_format` do nível superior do Chat por `text.format` no Responses. Forma canônica: `text={\"format\": {\"type\": \"json_schema\", \"name\": \"Output\", \"strict\": True, \"schema\": {...}}}`.\n- **Itens de conteúdo**: substitua Chat `content[].type: \"text\"` por Responses `content[].type: \"input_text\"` para turnos de usuário\u002Fsistema.\n- **Itens de conteúdo de imagem**: substitua Chat `content[].type: \"image_url\"` por Responses `content[].type: \"input_image\"`. O campo `image_url` muda de um objeto aninhado `{\"url\": \"...\"}` para uma string simples. Veja a folha de dicas para exemplos antes\u002Fdepois.\n- **Esforço de raciocínio**: **migre `reasoning` somente se ele já existir no código original**.\n- **Tratamento de erro do filtro de conteúdo**: a estrutura do corpo do erro mudou. Chat Completions usava `error.body[\"innererror\"][\"content_filter_result\"]` (singular); a API Responses usa `error.body[\"content_filters\"][0][\"content_filter_results\"]` (plural, dentro de um array). Código que acessa `innererror` levantará `KeyError`. Reescreva para usar o novo caminho.\n- **Chamadas HTTP brutas**: se o app chama a API REST Azure OpenAI diretamente (via `requests`, `httpx`, etc.) usando `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions?api-version=...`, reescreva para `\u002Fopenai\u002Fv1\u002Fresponses`. O corpo da requisição muda: `messages` → `input`, adicione `max_output_tokens` e `store: false`, remova o parâmetro de query `api-version`. O corpo da resposta muda: `choices[0].message.content` → `output[0].content[0].text` (nota: `output_text` é uma propriedade de conveniência do SDK não presente no JSON REST cru).\n\n---\n\n## Etapa 2: Aplicar Migração\n\n### Notas de migração (Chat Completions → Responses)\n\n- **Por que migrar**: Responses é a API unificada para texto, ferramentas e streaming; Chat Completions é legado. Com GPT-5, Responses é obrigatório para melhor desempenho.\n- **HTTP**: o endpoint Azure muda de `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions` para `\u002Fopenai\u002Fv1\u002Fresponses`.\n- **Campos**: `messages` → `input`, `max_tokens` → `max_output_tokens`. `temperature` permanece.\n- **Formatação**: `response_format` → `text.format` com objeto adequado.\n- **Itens de conteúdo**: substitua Chat `content[].type: \"text\"` por Responses `content[].type: \"input_text\"` para turnos de sistema\u002Fusuário.\n- **Itens de conteúdo de imagem**: substitua Chat `content[].type: \"image_url\"` por Responses `content[].type: \"input_image\"`. Achate o campo `image_url` de `{\"image_url\": {\"url\": \"...\"}}` para `{\"image_url\": \"...\"}` (uma string simples — URL HTTPS ou URI de dados `data:image\u002F...;base64,...`).\n\n### Referência de mapeamento de parâmetros\n\n| Chat Completions | Responses API |\n|-----------------|---------------|\n| `prompt` | `input` |\n| `messages` | `input` (array de itens) |\n| `max_tokens` | `max_output_tokens` |\n| `response_format` | `text.format` (objeto) |\n| `temperature` | `temperature` (sem mudanças) |\n| `stop` | `stop` (sem mudanças) |\n| `frequency_penalty` | `frequency_penalty` (sem mudanças) |\n| `presence_penalty` | `presence_penalty` (sem mudanças) |\n| `tools` \u002F chamada de função | `tools` (sem mudanças) |\n| `seed` | **Remover** (não suportado) |\n| `store` | `store` (definido como `false`) |\n| `content[].type: \"text\"` | `content[].type: \"input_text\"` |\n| `content[].type: \"image_url\"` | `content[].type: \"input_image\"` |\n| `\"image_url\": {\"url\": \"...\"}` | `\"image_url\": \"...\"` (string simples) |\n\nPara exemplos completos antes\u002Fdepois de código, veja [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\nPara migração de infraestrutura de teste (mocks, snapshots, assertions), veja [test-migration.md](.\u002Freferences\u002Ftest-migration.md).\n\nPara solução de problemas e armadilhas, veja [troubleshooting.md](.\u002Freferences\u002Ftroubleshooting.md).\n\n---\n\n## Retenção de Dados & Estado\n\n- Defina `store: false` em todas as requisições Responses.\n- Não confie em IDs de mensagens anteriores ou contexto armazenado no servidor; mantenha o estado gerenciado pelo cliente e minimize metadados.\n\n---\n\n## Critérios de Aceitação\n\n### Barreiras de nível de código (todas devem passar)\n\n- [ ] Zero correspondências para `rg \"chat\\.completions\\.create|ChatCompletion\\.create|Completion\\.create\"` nos arquivos migrados.\n- [ ] Zero correspondências para `rg \"AzureOpenAI\\(|AsyncAzureOpenAI\\(\"` — todos os construtores usam `OpenAI`\u002F`AsyncOpenAI` com o endpoint v1.\n- [ ] Zero correspondências para `rg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"` — caminhos de código dos modelos do GitHub removidos.\n- [ ] Zero correspondências para `rg \"OpenAIChatCompletionClient\"` — código MAF 1.0.0+ usa `OpenAIChatClient` (que usa Responses API). Em versões pré-1.0.0, atualize para `agent-framework-openai>=1.0.0`.\n- [ ] Todas chamadas `ChatOpenAI(...)` incluem `use_responses_api=True`.\n- [ ] Zero correspondências para `rg \"choices\\[0\\]\"` — todo acesso a respostas usa `resp.output_text` ou o esquema de saída Responses.\n- [ ] Nenhum `response_format` no nível superior; toda saída estruturada usa `text={\"format\": {...}}`.\n- [ ] `openai>=1.108.1` e `azure-identity` em `requirements.txt` ou `pyproject.toml`; dependências reinstaladas.\n- [ ] `store=False` definido em toda chamada `responses.create`.\n- [ ] Nenhum `api_version` na construção do cliente; `AZURE_OPENAI_API_VERSION` removido de arquivos e infraestrutura de ambiente.\n\n### Barreiras da infraestrutura de teste (todas devem passar)\n\n- [ ] Zero correspondências para `rg \"ChatCompletionChunk|AsyncCompletions\\.create|chat\\.completions\" tests\u002F`.\n- [ ] Zero correspondências para `rg \"_azure_ad_token_provider\" tests\u002F` — asserções atualizadas para verificar `isinstance(client, AsyncOpenAI)` ou `base_url`.\n- [ ] Zero correspondências para `rg \"prompt_filter_results|content_filter_results\" tests\u002F` — mocks do filtro específicos do Azure removidos.\n- [ ] Mocks usam `kwargs.get(\"input\")` e não `kwargs.get(\"messages\")`.\n- [ ] Arquivos snapshot \u002F golden atualizados para a forma de streaming Responses (sem `choices[0]`, `function_call`, `logprobs`, etc.).\n- [ ] `pytest` passa sem falhas após todas as atualizações de testes.\n\n### Barreiras comportamentais (verificar manualmente ou via suíte de testes)\n\n- [ ] **Completion básica**: `responses.create` não-streaming retorna `output_text` não vazio.\n- [ ] **Paridade de streaming**: se o código original usava streaming, o código migrado também faz streaming e emite eventos `response.output_text.delta` com deltas não vazios.\n- [ ] **Saída estruturada**: se usa `text.format` com `json_schema`, `json.loads(resp.output_text)` funciona e corresponde ao esquema.\n- [ ] **Loop de chamada de ferramentas**: se ferramentas são usadas, o modelo emite chamadas, o app executa, e a requisição subsequente retorna um `output_text` final (sem loop infinito).\n- [ ] **Paridade assíncrona**: se usava `AsyncAzureOpenAI`, o equivalente `AsyncOpenAI` funciona com `await`.\n- [ ] **Taxa de erro**: não há novos erros 400\u002F401\u002F404 comparados ao baseline pré-migração.\n\n### Entregáveis\n\n- O resumo inclui arquivos editados, contagens antes\u002Fdepois dos pontos de chamadas legadas e próximos passos.\n- As mudanças são edições na árvore de trabalho apenas (sem commits).\n\n---\n\n## Requisitos de Versão do SDK\n\n| Pacote | Versão Mínima |\n|---------|----------------|\n| `openai` | `>=1.108.1` |\n| `azure-identity` | Última (para autenticação EntraID) |\n\n---\n\n## Referências\n\n- [Folha de Dicas — todos os trechos de código](.\u002Freferences\u002Fcheat-sheet.md)\n- [Migração de Testes — mocks, snapshots, assertions](.\u002Freferences\u002Ftest-migration.md)\n- [Resolução de Problemas — erros, tabela de riscos, armadilhas](.\u002Freferences\u002Ftroubleshooting.md)\n- [detect_legacy.py — scanner automatizado](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py)\n- [Kit Inicial Azure OpenAI](https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart)\n- [Documentação Azure OpenAI Responses API](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fhow-to\u002Fresponses)\n- [Ciclo de vida da versão da API Azure OpenAI](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fapi-version-lifecycle?view=foundry-classic&tabs=python#api-evolution)\n- [Referência da API OpenAI Responses](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fapi-reference\u002Fresponses)\n\n---\n\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Aviso Legal**:\nEste documento foi traduzido usando o serviço de tradução por IA [Co-op Translator](https:\u002F\u002Fgithub.com\u002FAzure\u002Fco-op-translator). Embora nos esforcemos pela precisão, por favor, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autorizada. Para informações críticas, recomenda-se tradução profissional humana. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução.\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER END -->","# Migrar Aplicativos Python de Azure OpenAI Chat Completions para Responses API\n\n> **ORIENTAÇÃO AUTORITATIVA — SIGA EXATAMENTE**\n>\n> Esta habilidade migra bases de código Python que usam Azure OpenAI Chat Completions\n> para a Responses API unificada. Siga estas instruções com precisão.\n> Não improvise mapeamentos de parâmetros nem invente formatos de API.\n\n---\n\n## Gatilhos\n\nAtive esta habilidade quando o usuário quiser:\n- Migrar um app Python de Azure OpenAI Chat Completions para Responses API\n- Atualizar o uso do SDK Python OpenAI para o formato mais recente da API contra Azure OpenAI\n- Preparar código Python para modelos GPT-5 ou mais recentes que requerem Responses na Azure\n- Mudar de `AzureOpenAI`\u002F`AsyncAzureOpenAI` para o cliente padrão `OpenAI`\u002F`AsyncOpenAI` com o endpoint v1\n- Corrigir avisos de depreciação relacionados a construtores `AzureOpenAI` ou `api_version`\n\n---\n\n## ⚠️ Compatibilidade de Modelo — VERIFIQUE PRIMEIRO\n\n> **Antes de migrar, verifique se sua implantação Azure OpenAI suporta a Responses API.**\n\n### 1. Teste simples da implantação (mais rápido)\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> **Nota**: `max_output_tokens` tem um **mínimo de 16** na Azure OpenAI. Valores abaixo de 16 retornam erro 400. Use 50+ para testes simples.\n\nSe isto retornar 404, o modelo da implantação ainda não suporta Responses — consulte a referência abaixo ou reimplemente com um modelo suportado.\n\n### 2. Verifique os modelos disponíveis na sua região (recomendado)\n\nExecute a ferramenta embutida de compatibilidade de modelos para ver o que está disponível com suporte à Responses API em sua região específica:\n\n```bash\npython migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION\n```\n\nEsta consulta à Azure ARM ao vivo mostra uma matriz de compatibilidade — quais modelos suportam Responses, saída estruturada, ferramentas, etc. Use `--filter gpt-5.1,gpt-5.2` para filtrar resultados ou `--json` para script.\n\n### 3. Referência completa de suporte a modelos\n\n- **Consulta ao vivo**: `python migrate.py models` (veja acima — específico por região, sempre atualizado)\n- **Navegue disponibilidade**: [Tabela resumo de modelos e disponibilidade regional](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- **Início rápido e orientações**: **https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart**\n\n### ⚠️ Limitações de modelos antigos\n\n> **AVISO**: Modelos antigos (anteriores a `gpt-4.1`) podem não suportar totalmente todos os recursos da Responses API.\n>\n> Limitações conhecidas com modelos antigos:\n> - **Parâmetro `reasoning`**: Não suportado em muitos modelos sem raciocínio. Migrar `reasoning` só se já estiver presente no código original.\n> - **Parâmetro `seed`**: Não suportado na Responses API — remova de todas as requisições.\n> - **Saída estruturada via `text.format`**: Modelos antigos podem não aplicar esquemas JSON `strict: true` de forma confiável.\n> - **Orquestração de ferramentas**: GPT-5+ orquestra chamadas de ferramentas como parte do raciocínio interno. Modelos antigos no Responses funcionam, mas sem essa integração profunda.\n> - **Restrições de temperatura**: Ao migrar para `gpt-5`, a temperatura deve ser omitida ou definida como `1`. Modelos antigos não têm essa restrição.\n\n### Modelos de raciocínio da série O (o1, o3-mini, o3, o4-mini)\n\nModelos da série O têm restrições exclusivas de parâmetros. Ao migrar apps que usam modelos da série O:\n\n- **`temperature`**: Deve ser `1` (ou omitido). Modelos da série O não aceitam outros valores.\n- **`max_completion_tokens` → `max_output_tokens`**: Apps usando o específico `max_completion_tokens` do Azure devem mudar para `max_output_tokens`. Defina valores altos (4096+) pois tokens de raciocínio contam no limite.\n- **`reasoning_effort`**: Se o app usa `reasoning_effort` (baixo\u002Fmédio\u002Falto), mantenha — a Responses API suporta esse parâmetro para modelos da série O.\n- **Comportamento de streaming**: Modelos da série O podem armazenar saída até o raciocínio finalizar antes de emitir eventos de delta de texto. Streaming ainda funciona, mas o primeiro `response.output_text.delta` pode chegar com delay maior que em modelos GPT.\n- **`top_p`**: Não suportado na série O — remova se presente.\n- **Uso de ferramentas**: Modelos da série O suportam ferramentas pela Responses API igual aos modelos GPT, mas a qualidade da orquestração varia com o modelo.\n\n**Ação — aviso proativo de modelo**: Durante a fase de análise, verifique qual modelo o app usa (nomes de implantação, variáveis de ambiente, config). Se o modelo for anterior a `gpt-4.1` (não gpt-4.1+), informe proativamente ao usuário:\n- A migração funcionará para texto básico, chat, streaming e ferramentas no modelo atual.\n- Modelos mais novos (`gpt-5.1`, `gpt-5.2`) oferecem melhor orquestração de ferramentas, aplicação de saída estruturada, raciocínio e disponibilidade cross-region.\n- Ele deve considerar atualizar a implantação quando quiser — não bloqueia a migração.\n\nNão bloqueie nem recuse a migração por versão do modelo. O aviso é informativo.\n\n### GitHub Models NÃO suporta a Responses API\n\n> **GitHub Models (`models.github.ai`, `models.inference.ai.azure.com`) não suporta a Responses API.**\n\nSe a base de código tiver um caminho de código GitHub Models (procure `base_url` apontando para `models.github.ai` ou `models.inference.ai.azure.com`), **remova completamente** durante a migração. A Responses API requer Azure OpenAI, OpenAI, ou endpoint local compatível (ex: Ollama com suporte a Responses).\n\nAção durante a análise:\n- Identifique qualquer caminho de código GitHub Models para remoção.\n\n---\n\n## Migração de Framework\n\nMuitos apps usam frameworks de nível superior sobre OpenAI. Ao migrar, alteram-se também as APIs do framework — não apenas as chamadas subjacentes OpenAI.\n\n### Microsoft Agent Framework (MAF)\n\n**Verifique sua versão do MAF primeiro** — a migração depende se você está no MAF 1.0.0+ ou numa beta\u002Frc pré-1.0.0.\n\n#### MAF 1.0.0+ (agent-framework-openai >= 1.0.0)\n\n`OpenAIChatClient` **já usa Responses API** — não precisa migrar. Se o código usa o legado `OpenAIChatCompletionClient` (que usa `chat.completions.create`), substitua por `OpenAIChatClient`.\n\n| Antes | Depois |\n|--------|-------|\n| `from agent_framework.openai import OpenAIChatCompletionClient` | `from agent_framework.openai import OpenAIChatClient` |\n| `OpenAIChatCompletionClient(...)` | `OpenAIChatClient(...)` |\n\nPara checar sua versão: `python -c \"import agent_framework_openai; print(agent_framework_openai.__version__)\"`\n\n#### MAF pré-1.0.0 (lançamentos beta\u002Frc)\n\nNo MAF pré-1.0.0, `OpenAIChatClient` usava Chat Completions. Atualize para `agent-framework-openai>=1.0.0` onde `OpenAIChatClient` usa Responses API por padrão.\n\nNenhuma outra mudança necessária — as APIs `Agent` e de ferramentas permanecem iguais.\n\n### LangChain (`langchain-openai`)\n\nAdicione `use_responses_api=True` a `ChatOpenAI()`. Também atualize o acesso à resposta de `.content` para `.text`.\n\n| Antes | Depois |\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\nPara exemplos completos de código antes\u002Fdepois, veja [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\n---\n\n## Orientação para Migração do Frontend\n\n> **A Responses API é uma preocupação do lado servidor.** Migre seu backend Python; o contrato HTTP do frontend deve permanecer inalterado, a menos que seu backend seja uma passagem fina — nesse caso, considere adotar o formato Requests Responses para eliminar uma camada de tradução. Se o frontend chama OpenAI diretamente com chave no cliente, mova essas chamadas para o backend primeiro.\n\n### Depreciação do `@microsoft\u002Fai-chat-protocol`\n\nO pacote npm `@microsoft\u002Fai-chat-protocol` está depreciado e deve ser substituído por [`ndjson-readablestream`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fndjson-readablestream). Se encontrá-lo em um frontend:\n\n1. Substitua a tag script 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. Remova a instanciação `AIChatProtocolClient` (`new ChatProtocol.AIChatProtocolClient(\"\u002Fchat\")`).\n3. Substitua `client.getStreamedCompletion(messages)` por uma chamada `fetch()` direta ao endpoint de streaming do backend.\n4. Substitua `for await (const response of result)` por `for await (const chunk of readNDJSONStream(response.body))`.\n5. Atualize o acesso a propriedades de `response.delta.content` \u002F `response.error` para `chunk.delta.content` \u002F `chunk.error`.\n\n---\n\n## Objetivos\n\n- Enumerar todos os pontos de chamadas Python que usam Chat Completions ou Completions legadas contra Azure OpenAI.\n- Propor um plano de migração e sequenciamento para a base de código Python.\n- Aplicar edições seguras e mínimas para mudar à Responses API.\n- Atualizar chamadores para consumir o esquema de saída do Responses; sem wrappers de retrocompatibilidade.\n- Rodar testes\u002Flints; corrigir quebras triviais causadas pela migração.\n- Preparar pequenos conjuntos de mudanças revisáveis e fornecer um resumo final com diffs (não commite).\n\n---\n\n## Limites de Segurança\n\n- Modifique apenas arquivos dentro da workspace git. Nunca escreva fora.\n- Não preserve shims de retrocompatibilidade; migre código para o novo formato da API.\n- Não deixe comentários de transição\u002Ftombstone ou arquivos de backup.\n- Preserve semântica de streaming se usada antes; senão use não streaming.\n- Peça aprovação antes de executar comandos ou chamadas de rede se estiver em modo de aprovação.\n- Não execute `git add`\u002F`git commit`\u002F`git push`; produza apenas edições na working tree.\n\n---\n\n## Passo 0: Migração do Cliente Azure OpenAI (Pré-requisito)\n\nSe a base de código usar construtores `AzureOpenAI` ou `AsyncAzureOpenAI`, migre primeiro para os construtores padrão `OpenAI` \u002F `AsyncOpenAI`. Os construtores específicos Azure estão depreciados em `openai>=1.108.1`.\n\n### Por que o caminho v1 da API?\n\nO novo endpoint `\u002Fopenai\u002Fv1` usa o cliente padrão `OpenAI()` em vez de `AzureOpenAI()`, não requer parâmetro `api_version`, e funciona exatamente igual em OpenAI e Azure OpenAI. O mesmo código cliente é à prova de futuro — não precisa gerenciar versões.\n\n### Mudanças principais\n\n| Antes | Depois |\n|--------|-------|\n| `AzureOpenAI` | `OpenAI` |\n| `AsyncAzureOpenAI` | `AsyncOpenAI` |\n| `azure_endpoint` | `base_url` |\n| `azure_ad_token_provider` | `api_key` |\n| `api_version=...` | Remova completamente |\n\n### Checklist de limpeza\n\n- Remova argumento `api_version` da construção do cliente.\n- Remova variáveis de ambiente `AZURE_OPENAI_VERSION` \u002F `AZURE_OPENAI_API_VERSION` de `.env`, configurações do app e arquivos Bicep\u002Finfra.\n- Renomeie `AZURE_OPENAI_CLIENT_ID` → `AZURE_CLIENT_ID` em `.env`, configurações do app, Bicep\u002Finfra, e fixtures de teste (convenção padrão SDK Azure Identity).\n- Garanta `openai>=1.108.1` em `requirements.txt` ou `pyproject.toml`.\n\n### Migração de variáveis de ambiente\n\n| Variável antiga | Ação | Notas |\n|-------------|--------|-------|\n| `AZURE_OPENAI_VERSION` | **Remover** | Não precisa de `api_version` com endpoint v1 |\n| `AZURE_OPENAI_API_VERSION` | **Remover** | Igual acima |\n| `AZURE_OPENAI_CLIENT_ID` | **Renomear** → `AZURE_CLIENT_ID` | Convenção padrão SDK Azure Identity para `ManagedIdentityCredential(client_id=...)` |\n| `AZURE_OPENAI_ENDPOINT` | **Manter** | Ainda necessário para construção de `base_url` |\n| `AZURE_OPENAI_CHAT_DEPLOYMENT` | **Manter** | Usado como parâmetro `model` em `responses.create` |\n| `AZURE_OPENAI_API_KEY` | **Manter** | Usado como `api_key` para autenticação por chave |\n\nPara exemplos de configuração de cliente (sync, async, EntraID, chave API, multi-tenant), veja [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\n---\n\n## Passo 1: Detectar Pontos de Chamadas Legadas\n\nExecute o script [detect_legacy.py](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py) para encontrar todos os pontos de chamada que precisam migrar:\n\n```bash\npython skills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py .\n```\n\nOu faça buscas manuais — cada correspondência é um alvo de migração:\n\n```bash\n# Chamadas de API legadas (precisa reescrever)\nrg \"chat\\.completions\\.create\"\nrg \"ChatCompletion\\.create\"\nrg \"Completion\\.create\"\n\n# Construtores de cliente Azure obsoletos (precisa substituir)\nrg \"AzureOpenAI\\(\"\nrg \"AsyncAzureOpenAI\\(\"\n\n# Padrões de acesso à forma da resposta (precisa atualizar)\nrg \"choices\\[0\\]\\.message\\.content\"\nrg \"choices\\[0\\]\\.delta\\.content\"\nrg \"choices\\[0\\]\\.message\\.function_call\"\nrg \"choices\\[0\\]\\.message\\.tool_calls\"\n\n# Definições de ferramentas em formato antigo aninhado (precisa achatar)\nrg '\"function\":\\s*{\\s*\"name\"'\nrg \"pydantic_function_tool\"\n\n# Resultados da ferramenta em formato antigo (precisa converter para function_call_output)\nrg '\"role\":\\s*\"tool\"'\nrg '\"tool_call_id\"'\n\n# Parâmetros obsoletos (precisa remover ou renomear)\nrg \"response_format\"\nrg \"max_tokens\\b\"        # renomear para max_output_tokens\nrg \"['\\\"]seed['\\\"]\"      # remove entirely\n\n# Variáveis de ambiente obsoletas (limpar)\nrg \"AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION\"\nrg \"AZURE_OPENAI_CLIENT_ID\"  # deveria ser AZURE_CLIENT_ID\n\n# Endpoints de Modelos do GitHub (precisa remover — API de Respostas não suportada)\nrg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"\n\n# Padrões legados no nível do framework (precisa atualizar)\nrg \"OpenAIChatCompletionClient\"  # MAF 1.0.0+: substituir por OpenAIChatClient\nrg \"ChatOpenAI\\(\" | grep -v \"use_responses_api\"  # LangChain: precisa de use_responses_api=True\n\n# Infraestrutura de teste (precisa atualizar)\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# Acesso ao corpo de erro do filtro de conteúdo (precisa atualizar — estrutura mudou)\nrg 'innererror.*content_filter_result|error\\.body\\[\"innererror\"\\]'\nrg \"content_filter_result\\[\" # forma singular antiga — agora content_filter_results (plural) dentro do array content_filters\n\n# Chamadas HTTP brutas para o endpoint de Chat Completions (precisa atualizar URL)\nrg \"\u002Fopenai\u002Fdeployments\u002F.*\u002Fchat\u002Fcompletions\"\nrg \"api-version=\"\n```\n\n### Heurísticas (detectar e reescrever)\n\n- **Cliente Chat Completions**: `client.chat.completions.create` → `client.responses.create(...)`.\n\n- **Construtores de cliente Azure**: `AzureOpenAI(...)` → `OpenAI(base_url=..., api_key=...)`.\n- **Ferramentas**: converta definições de ferramentas com chamada de função do formato aninhado (`{\"type\": \"function\", \"function\": {\"name\": ...}}`) para o formato plano do Responses (`{\"type\": \"function\", \"name\": ...}`); use `tool_choice`; retorne resultados das ferramentas como itens `{\"type\": \"function_call_output\", \"call_id\": ..., \"output\": ...}` (não `{\"role\": \"tool\", ...}`).\n- **Ciclo das ferramentas**: quando o modelo retornar chamadas de funções, anexe os itens `response.output` à conversa (não um dicionário manual `{\"role\": \"assistant\", \"tool_calls\": [...]}`), depois anexe os itens `function_call_output` para cada resultado.\n- **Exemplos de ferramentas few-shot**: se a conversa incluir exemplos embutidos de chamadas de ferramentas, converta-os em itens `{\"type\": \"function_call\", \"id\": \"fc_...\", \"call_id\": \"fc_...\", ...}` + `{\"type\": \"function_call_output\", ...}`. IDs devem começar com `fc_`.\n- **`pydantic_function_tool()`**: esse auxiliar ainda gera o formato aninhado antigo e **não é compatível** com `responses.create()`. Substitua por definições manuais de ferramentas ou um wrapper de achatamento.\n- **Multi-turn**: mantenha o histórico da conversa na aplicação; passe turnos anteriores via itens `input`.\n- **Formatação**: substitua o `response_format` do nível superior do Chat por `text.format` no Responses. Forma canônica: `text={\"format\": {\"type\": \"json_schema\", \"name\": \"Output\", \"strict\": True, \"schema\": {...}}}`.\n- **Itens de conteúdo**: substitua Chat `content[].type: \"text\"` por Responses `content[].type: \"input_text\"` para turnos de usuário\u002Fsistema.\n- **Itens de conteúdo de imagem**: substitua Chat `content[].type: \"image_url\"` por Responses `content[].type: \"input_image\"`. O campo `image_url` muda de um objeto aninhado `{\"url\": \"...\"}` para uma string simples. Veja a folha de dicas para exemplos antes\u002Fdepois.\n- **Esforço de raciocínio**: **migre `reasoning` somente se ele já existir no código original**.\n- **Tratamento de erro do filtro de conteúdo**: a estrutura do corpo do erro mudou. Chat Completions usava `error.body[\"innererror\"][\"content_filter_result\"]` (singular); a API Responses usa `error.body[\"content_filters\"][0][\"content_filter_results\"]` (plural, dentro de um array). Código que acessa `innererror` levantará `KeyError`. Reescreva para usar o novo caminho.\n- **Chamadas HTTP brutas**: se o app chama a API REST Azure OpenAI diretamente (via `requests`, `httpx`, etc.) usando `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions?api-version=...`, reescreva para `\u002Fopenai\u002Fv1\u002Fresponses`. O corpo da requisição muda: `messages` → `input`, adicione `max_output_tokens` e `store: false`, remova o parâmetro de query `api-version`. O corpo da resposta muda: `choices[0].message.content` → `output[0].content[0].text` (nota: `output_text` é uma propriedade de conveniência do SDK não presente no JSON REST cru).\n\n---\n\n## Etapa 2: Aplicar Migração\n\n### Notas de migração (Chat Completions → Responses)\n\n- **Por que migrar**: Responses é a API unificada para texto, ferramentas e streaming; Chat Completions é legado. Com GPT-5, Responses é obrigatório para melhor desempenho.\n- **HTTP**: o endpoint Azure muda de `\u002Fopenai\u002Fdeployments\u002F{name}\u002Fchat\u002Fcompletions` para `\u002Fopenai\u002Fv1\u002Fresponses`.\n- **Campos**: `messages` → `input`, `max_tokens` → `max_output_tokens`. `temperature` permanece.\n- **Formatação**: `response_format` → `text.format` com objeto adequado.\n- **Itens de conteúdo**: substitua Chat `content[].type: \"text\"` por Responses `content[].type: \"input_text\"` para turnos de sistema\u002Fusuário.\n- **Itens de conteúdo de imagem**: substitua Chat `content[].type: \"image_url\"` por Responses `content[].type: \"input_image\"`. Achate o campo `image_url` de `{\"image_url\": {\"url\": \"...\"}}` para `{\"image_url\": \"...\"}` (uma string simples — URL HTTPS ou URI de dados `data:image\u002F...;base64,...`).\n\n### Referência de mapeamento de parâmetros\n\n| Chat Completions | Responses API |\n|-----------------|---------------|\n| `prompt` | `input` |\n| `messages` | `input` (array de itens) |\n| `max_tokens` | `max_output_tokens` |\n| `response_format` | `text.format` (objeto) |\n| `temperature` | `temperature` (sem mudanças) |\n| `stop` | `stop` (sem mudanças) |\n| `frequency_penalty` | `frequency_penalty` (sem mudanças) |\n| `presence_penalty` | `presence_penalty` (sem mudanças) |\n| `tools` \u002F chamada de função | `tools` (sem mudanças) |\n| `seed` | **Remover** (não suportado) |\n| `store` | `store` (definido como `false`) |\n| `content[].type: \"text\"` | `content[].type: \"input_text\"` |\n| `content[].type: \"image_url\"` | `content[].type: \"input_image\"` |\n| `\"image_url\": {\"url\": \"...\"}` | `\"image_url\": \"...\"` (string simples) |\n\nPara exemplos completos antes\u002Fdepois de código, veja [cheat-sheet.md](.\u002Freferences\u002Fcheat-sheet.md).\n\nPara migração de infraestrutura de teste (mocks, snapshots, assertions), veja [test-migration.md](.\u002Freferences\u002Ftest-migration.md).\n\nPara solução de problemas e armadilhas, veja [troubleshooting.md](.\u002Freferences\u002Ftroubleshooting.md).\n\n---\n\n## Retenção de Dados & Estado\n\n- Defina `store: false` em todas as requisições Responses.\n- Não confie em IDs de mensagens anteriores ou contexto armazenado no servidor; mantenha o estado gerenciado pelo cliente e minimize metadados.\n\n---\n\n## Critérios de Aceitação\n\n### Barreiras de nível de código (todas devem passar)\n\n- [ ] Zero correspondências para `rg \"chat\\.completions\\.create|ChatCompletion\\.create|Completion\\.create\"` nos arquivos migrados.\n- [ ] Zero correspondências para `rg \"AzureOpenAI\\(|AsyncAzureOpenAI\\(\"` — todos os construtores usam `OpenAI`\u002F`AsyncOpenAI` com o endpoint v1.\n- [ ] Zero correspondências para `rg \"models\\.github\\.ai|models\\.inference\\.ai\\.azure\"` — caminhos de código dos modelos do GitHub removidos.\n- [ ] Zero correspondências para `rg \"OpenAIChatCompletionClient\"` — código MAF 1.0.0+ usa `OpenAIChatClient` (que usa Responses API). Em versões pré-1.0.0, atualize para `agent-framework-openai>=1.0.0`.\n- [ ] Todas chamadas `ChatOpenAI(...)` incluem `use_responses_api=True`.\n- [ ] Zero correspondências para `rg \"choices\\[0\\]\"` — todo acesso a respostas usa `resp.output_text` ou o esquema de saída Responses.\n- [ ] Nenhum `response_format` no nível superior; toda saída estruturada usa `text={\"format\": {...}}`.\n- [ ] `openai>=1.108.1` e `azure-identity` em `requirements.txt` ou `pyproject.toml`; dependências reinstaladas.\n- [ ] `store=False` definido em toda chamada `responses.create`.\n- [ ] Nenhum `api_version` na construção do cliente; `AZURE_OPENAI_API_VERSION` removido de arquivos e infraestrutura de ambiente.\n\n### Barreiras da infraestrutura de teste (todas devem passar)\n\n- [ ] Zero correspondências para `rg \"ChatCompletionChunk|AsyncCompletions\\.create|chat\\.completions\" tests\u002F`.\n- [ ] Zero correspondências para `rg \"_azure_ad_token_provider\" tests\u002F` — asserções atualizadas para verificar `isinstance(client, AsyncOpenAI)` ou `base_url`.\n- [ ] Zero correspondências para `rg \"prompt_filter_results|content_filter_results\" tests\u002F` — mocks do filtro específicos do Azure removidos.\n- [ ] Mocks usam `kwargs.get(\"input\")` e não `kwargs.get(\"messages\")`.\n- [ ] Arquivos snapshot \u002F golden atualizados para a forma de streaming Responses (sem `choices[0]`, `function_call`, `logprobs`, etc.).\n- [ ] `pytest` passa sem falhas após todas as atualizações de testes.\n\n### Barreiras comportamentais (verificar manualmente ou via suíte de testes)\n\n- [ ] **Completion básica**: `responses.create` não-streaming retorna `output_text` não vazio.\n- [ ] **Paridade de streaming**: se o código original usava streaming, o código migrado também faz streaming e emite eventos `response.output_text.delta` com deltas não vazios.\n- [ ] **Saída estruturada**: se usa `text.format` com `json_schema`, `json.loads(resp.output_text)` funciona e corresponde ao esquema.\n- [ ] **Loop de chamada de ferramentas**: se ferramentas são usadas, o modelo emite chamadas, o app executa, e a requisição subsequente retorna um `output_text` final (sem loop infinito).\n- [ ] **Paridade assíncrona**: se usava `AsyncAzureOpenAI`, o equivalente `AsyncOpenAI` funciona com `await`.\n- [ ] **Taxa de erro**: não há novos erros 400\u002F401\u002F404 comparados ao baseline pré-migração.\n\n### Entregáveis\n\n- O resumo inclui arquivos editados, contagens antes\u002Fdepois dos pontos de chamadas legadas e próximos passos.\n- As mudanças são edições na árvore de trabalho apenas (sem commits).\n\n---\n\n## Requisitos de Versão do SDK\n\n| Pacote | Versão Mínima |\n|---------|----------------|\n| `openai` | `>=1.108.1` |\n| `azure-identity` | Última (para autenticação EntraID) |\n\n---\n\n## Referências\n\n- [Folha de Dicas — todos os trechos de código](.\u002Freferences\u002Fcheat-sheet.md)\n- [Migração de Testes — mocks, snapshots, assertions](.\u002Freferences\u002Ftest-migration.md)\n- [Resolução de Problemas — erros, tabela de riscos, armadilhas](.\u002Freferences\u002Ftroubleshooting.md)\n- [detect_legacy.py — scanner automatizado](..\u002F..\u002F..\u002F..\u002F..\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Fscripts\u002Fdetect_legacy.py)\n- [Kit Inicial Azure OpenAI](https:\u002F\u002Faka.ms\u002Fopenai\u002Fstart)\n- [Documentação Azure OpenAI Responses API](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fhow-to\u002Fresponses)\n- [Ciclo de vida da versão da API Azure OpenAI](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fai-foundry\u002Fopenai\u002Fapi-version-lifecycle?view=foundry-classic&tabs=python#api-evolution)\n- [Referência da API OpenAI Responses](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fapi-reference\u002Fresponses)\n\n---\n\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Aviso Legal**:\nEste documento foi traduzido usando o serviço de tradução por IA [Co-op Translator](https:\u002F\u002Fgithub.com\u002FAzure\u002Fco-op-translator). Embora nos esforcemos pela precisão, por favor, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autorizada. Para informações críticas, recomenda-se tradução profissional humana. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução.\n\u003C!-- CO-OP TRANSLATOR DISCLAIMER END -->",{"name":5,"license":14},"main","f09e94ffe170f8af6d3db7c42987bbe4db227723","translations\u002Fpt-BR\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\u002Fpt-BR\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","参考文档",29416,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fpt-BR\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",7515,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fpt-BR\u002F.agents\u002Fskills\u002Fazure-openai-to-responses\u002Freferences\u002Ftest-migration.md",{"path":59,"resourceType":50,"resourceTypeDesc":51,"sizeBytes":60,"sourceHtmlUrl":61},"references\u002Ftroubleshooting.md",16027,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fai-agents-for-beginners\u002Fblob\u002Fmain\u002Ftranslations\u002Fpt-BR\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]]