Migrar Apps Python de Azure OpenAI Chat Completions para Responses API
ORIENTAÇÃO AUTORITATIVA — SIGA EXATAMENTE
Esta funcionalidade migra bases de código Python a usar Azure OpenAI Chat Completions para a API unificada Responses. Siga estas instruções de forma precisa. Não improvise mapeamentos de parâmetros nem invente formatos de API.
Gatilhos
Ative esta funcionalidade quando o utilizador quiser:
- Migrar uma app Python de Azure OpenAI Chat Completions para Responses API
- Atualizar utilização do SDK OpenAI em Python para o formato mais recente da API com Azure OpenAI
- Preparar código Python para modelos GPT-5 ou superiores que requerem Responses na Azure
- Trocar
AzureOpenAI/AsyncAzureOpenAIpelo cliente padrãoOpenAI/AsyncOpenAIcom o endpoint v1 - Corrigir avisos de descontinuação relacionados com construtores
AzureOpenAIouapi_version
⚠️ Compatibilidade de Modelo — VERIFIQUE PRIMEIRO
Antes de migrar, verifique se o seu deployment Azure OpenAI suporta a Responses API.
1. Teste rápido do deployment (mais rápido)
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AZURE_OPENAI_API_KEY"],
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
)
try:
resp = client.responses.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
input="ping",
max_output_tokens=50,
store=False,
)
print(f"✅ Deployment supports Responses API: {resp.output_text}")
except Exception as e:
print(f"❌ Deployment does NOT support Responses API: {e}")
Nota:
max_output_tokenstem um mínimo de 16 na Azure OpenAI. Valores abaixo de 16 causam erro 400. Use 50+ para testes rápidos.
Se isto devolver 404, o modelo do deployment não suporta Responses ainda — verifique a referência abaixo ou redeploy com um modelo suportado.
2. Verifique modelos disponíveis na sua região (recomendado)
Execute a ferramenta incorporada de compatibilidade de modelos para ver o que está disponível com suporte Responses API na sua região:
python migrate.py models --subscription YOUR_SUB_ID --location YOUR_REGION
Esta consulta ao vivo Azure ARM mostra uma matriz de compatibilidades — quais modelos suportam Responses, output estruturado, ferramentas, etc. Use --filter gpt-5.1,gpt-5.2 para filtrar resultados ou --json para scripting.
3. Referência completa de suporte a modelos
- Consulta ao vivo:
python migrate.py models(veja acima — específico de região, sempre atualizado) - Navegar disponibilidades: Tabela resumo de modelos e disponibilidade por região
- Arranque rápido & orientação: https://aka.ms/openai/start
⚠️ Limitações de modelos antigos
AVISO: Modelos mais antigos (anteriores a
gpt-4.1) podem não suportar totalmente todas as funcionalidades da Responses API.Limitações conhecidas com modelos antigos:
- Parâmetro
reasoning: Não suportado em muitos modelos sem capacidade de raciocínio. Apenas migrereasoningse já existia no código original.- Parâmetro
seed: Não suportado na Responses API — remova de todos os pedidos.- Output estruturado via
text.format: Modelos antigos podem não impor esquemas JSONstrict: truede forma fiável.- Orquestração de ferramentas: GPT-5+ orquestra chamadas a ferramentas como parte do raciocínio interno. Modelos antigos em Responses ainda funcionam mas sem esta integração profunda.
- Restrições de temperatura: Ao migrar para
gpt-5, a temperatura deve ser omitida ou definida para1. Modelos antigos não têm esta restrição.
Modelos de raciocínio da série O (o1, o3-mini, o3, o4-mini)
Modelos da série O têm restrições específicas de parâmetros. Ao migrar apps para modelos da série O:
temperature: Deve ser1(ou omitido). Modelos série O não aceitam outros valores.max_completion_tokens→max_output_tokens: Apps que usammax_completion_tokensespecífico Azure devem mudar paramax_output_tokens. Use valores altos (4096+) pois tokens de raciocínio contam para o limite.reasoning_effort: Se usarreasoning_effort(baixo/médio/alto), mantenha — Responses API suporta este parâmetro para modelos da série O.- Comportamento streaming: Modelos da série O podem armazenar output internamente até o raciocínio concluir antes de emitir eventos delta de texto. Streaming funciona, mas o primeiro
response.output_text.deltapode demorar mais que em modelos GPT. top_p: Não suportado na série O — remova se presente.- Uso de ferramentas: Modelos da série O suportam ferramentas via Responses API como GPT, mas a qualidade da orquestração varia por modelo.
Ação — aviso proativo ao modelo: Durante a fase de análise, verifique qual modelo a app usa (nomes de deployment, variáveis de ambiente, configuração). Se o modelo for anterior a gpt-4.1 (não gpt-4.1+), informe proativamente o utilizador:
- A migração funcionará para texto básico, chat, streaming, e ferramentas no modelo atual.
- Modelos mais recentes (
gpt-5.1,gpt-5.2) oferecem melhor orquestração de ferramentas, aplicação de output estruturado, raciocínio, e disponibilidade cross-region. - Devem considerar atualizar o deployment quando prontos — não bloqueia a migração.
Não bloqueie nem recuse a migração por versão do modelo. O aviso é informativo.
GitHub Models NÃO suporta a Responses API
GitHub Models (
models.github.ai,models.inference.ai.azure.com) não suporta a Responses API.
Se a base de código tiver um caminho para GitHub Models (procure por base_url a apontar para models.github.ai ou models.inference.ai.azure.com), remova-o completamente na migração. A Responses API requer Azure OpenAI, OpenAI ou endpoint local compatível (ex.: Ollama com suporte a Responses).
Ação durante a análise:
- Identifique e marque todos os caminhos de código GitHub Models para remoção.
Migração de Frameworks
Muitas apps usam frameworks de nível superior sobre OpenAI. Ao migrar estes, mudam as APIs do próprio framework — não só as chamadas OpenAI subjacentes.
Microsoft Agent Framework (MAF)
Verifique primeiro a sua versão MAF — a migração depende se está na versão 1.0.0+ ou numa beta/rc pré-1.0.0.
MAF 1.0.0+ (agent-framework-openai >= 1.0.0)
OpenAIChatClient já usa a Responses API — não há migração necessária. Se o código usar o legado OpenAIChatCompletionClient (usando chat.completions.create), troque-o por OpenAIChatClient.
| Antes | Depois |
|---|---|
from agent_framework.openai import OpenAIChatCompletionClient |
from agent_framework.openai import OpenAIChatClient |
OpenAIChatCompletionClient(...) |
OpenAIChatClient(...) |
Para verificar a versão: python -c "import agent_framework_openai; print(agent_framework_openai.__version__)"
MAF pré-1.0.0 (beta/rc)
No MAF pré-1.0.0, OpenAIChatClient usava Chat Completions. Atualize para agent-framework-openai>=1.0.0 onde OpenAIChatClient usa a Responses API por padrão.
Não são necessárias outras mudanças — as APIs do Agent e das ferramentas mantêm-se.
LangChain (langchain-openai)
Adicione use_responses_api=True ao ChatOpenAI(). Também atualize o acesso à resposta de .content para .text.
| Antes | Depois |
|---|---|
ChatOpenAI(model=..., base_url=..., api_key=...) |
ChatOpenAI(model=..., base_url=..., api_key=..., use_responses_api=True) |
result['messages'][-1].content |
result['messages'][-1].text |
Para exemplos completos de código antes/depois, veja cheat-sheet.md.
Orientações para Migração Frontend
A Responses API é uma preocupação do servidor. Migre o backend Python; o contrato HTTP no frontend deve manter-se inalterado, a menos que o backend seja um simples passthrough — nesse caso, considere adotar o formato de pedido 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.
Descontinuação do @microsoft/ai-chat-protocol
O pacote npm @microsoft/ai-chat-protocol está descontinuado e deve ser substituído por ndjson-readablestream. Se o encontrar num frontend:
- Substitua a tag script CDN:
<!-- Before --> <script src="https://cdn.jsdelivr.net/npm/@microsoft/ai-chat-protocol@.../dist/iife/index.js"></script> <!-- After --> <script src="https://cdn.jsdelivr.net/npm/ndjson-readablestream@1.0.7/dist/ndjson-readablestream.umd.js"></script> - Remova a criação de
AIChatProtocolClient(new ChatProtocol.AIChatProtocolClient("/chat")). - Substitua
client.getStreamedCompletion(messages)por uma chamadafetch()direta ao endpoint backend de streaming. - Substitua
for await (const response of result)porfor await (const chunk of readNDJSONStream(response.body)). - Atualize acessos a propriedades: de
response.delta.content/response.errorparachunk.delta.content/chunk.error.
Objetivos
- Enumerar todos os locais de chamadas Python usando Chat Completions ou Completions legados contra Azure OpenAI.
- Propor um plano de migração e sequência para a base de código Python.
- Aplicar edições seguras e mínimas para mudar para Responses API.
- Atualizar os callers para consumirem o esquema de output Responses; sem wrappers de retrocompatibilidade.
- Executar testes/lints; corrigir rupturas triviais introduzidas pela migração.
- Preparar conjuntos de mudanças pequenos e revisáveis e providenciar um sumário final com diffs (não commitar).
Regras
- Modificar apenas ficheiros dentro da workspace git. Nunca escrever fora.
- Não preservar shims de retrocompatibilidade; migre para o novo formato de API.
- Não deixar comentários de transição ou ficheiros de backup.
- Preservar semântica streaming se usada anteriormente; senão usar sem streaming.
- Pedir aprovação antes de executar comandos ou chamadas de rede se em modo aprovação.
- Não executar
git add/git commit/git push; apenas edite working-tree.
Passo 0: Migração do Cliente Azure OpenAI (Pré-requisito)
Se a base de código usar os construtores AzureOpenAI ou AsyncAzureOpenAI, migre para os construtores padrão OpenAI / AsyncOpenAI primeiro. Os construtores específicos Azure estão descontinuados em openai>=1.108.1.
Porquê o endpoint API v1?
O novo endpoint /openai/v1 usa o cliente padrão OpenAI() em vez de AzureOpenAI(), não requer parâmetro api_version, e funciona igual em OpenAI e Azure OpenAI. O mesmo código cliente é à prova de futuro — sem necessidade de gerir versões.
Principais mudanças
| Antes | Depois |
|---|---|
AzureOpenAI |
OpenAI |
AsyncAzureOpenAI |
AsyncOpenAI |
azure_endpoint |
base_url |
azure_ad_token_provider |
api_key |
api_version=... |
Remover completamente |
Lista de limpeza
- Remover argumento
api_versionda construção do cliente. - Remover variáveis ambiente
AZURE_OPENAI_VERSION/AZURE_OPENAI_API_VERSIONde.env, definições da app, e ficheiros Bicep/infra. - Renomear
AZURE_OPENAI_CLIENT_ID→AZURE_CLIENT_IDem.env, definições da app, Bicep/infra, e fixtures de teste (convenção SDK Azure Identity padrão). - Garantir
openai>=1.108.1norequirements.txtoupyproject.toml.
Migração de variáveis de ambiente
| Variável antiga | Ação | Notas |
|---|---|---|
AZURE_OPENAI_VERSION |
Remover | Não é necessário api_version com endpoint v1 |
AZURE_OPENAI_API_VERSION |
Remover | Igual acima |
AZURE_OPENAI_CLIENT_ID |
Renomear → AZURE_CLIENT_ID |
Convenção padrão SDK Azure Identity para ManagedIdentityCredential(client_id=...) |
AZURE_OPENAI_ENDPOINT |
Manter | Ainda necessário para construir base_url |
AZURE_OPENAI_CHAT_DEPLOYMENT |
Manter | Usado como model no responses.create |
AZURE_OPENAI_API_KEY |
Manter | Usado como api_key para autenticação por chave |
Para exemplos de configuração cliente (sync, async, EntraID, chave API, multi-tenant), veja cheat-sheet.md.
Passo 1: Detectar Locais de Chamadas Legadas
Execute o script detect_legacy.py para localizar todos os locais de chamadas que precisam de migração:
python skills/azure-openai-to-responses/scripts/detect_legacy.py .
Ou execute estas pesquisas manualmente — cada correspondência é alvo de migração:
# Chamadas API legadas (deve reescrever)
rg "chat\.completions\.create"
rg "ChatCompletion\.create"
rg "Completion\.create"
# Construtores do cliente Azure obsoletos (deve substituir)
rg "AzureOpenAI\("
rg "AsyncAzureOpenAI\("
# Padrões de acesso à estrutura de resposta (deve atualizar)
rg "choices\[0\]\.message\.content"
rg "choices\[0\]\.delta\.content"
rg "choices\[0\]\.message\.function_call"
rg "choices\[0\]\.message\.tool_calls"
# Definições de ferramentas em formato antigo aninhado (deve achatar)
rg '"function":\s*{\s*"name"'
rg "pydantic_function_tool"
# Resultados da ferramenta em formato antigo (deve converter para function_call_output)
rg '"role":\s*"tool"'
rg '"tool_call_id"'
# Parâmetros obsoletos (deve remover ou renomear)
rg "response_format"
rg "max_tokens\b" # renomear para max_output_tokens
rg "['\"]seed['\"]" # remove entirely
# Variáveis de ambiente obsoletas (limpar)
rg "AZURE_OPENAI_API_VERSION|AZURE_OPENAI_VERSION"
rg "AZURE_OPENAI_CLIENT_ID" # deveria ser AZURE_CLIENT_ID
# Endpoints dos Modelos GitHub (deve remover — API de Respostas não suportada)
rg "models\.github\.ai|models\.inference\.ai\.azure"
# Padrões legados ao nível do framework (deve atualizar)
rg "OpenAIChatCompletionClient" # MAF 1.0.0+: substituir por OpenAIChatClient
rg "ChatOpenAI\(" | grep -v "use_responses_api" # LangChain: necessita de use_responses_api=True
# Infraestrutura de testes (deve atualizar)
rg "ChatCompletionChunk|AsyncCompletions\.create" tests/
rg "_azure_ad_token_provider" tests/
rg "prompt_filter_results|content_filter_results" tests/
rg "choices\[0\]" tests/
# Acesso ao corpo de erro do filtro de conteúdo (deve atualizar — estrutura alterada)
rg 'innererror.*content_filter_result|error\.body\["innererror"\]'
rg "content_filter_result\[" # Forma singular antiga — agora content_filter_results (plural) dentro do array content_filters
# Chamadas HTTP brutas ao endpoint Chat Completions (deve atualizar URL)
rg "/openai/deployments/.*/chat/completions"
rg "api-version="
Heurísticas (detetar e reescrever)
Cliente Chat Completions:
client.chat.completions.create→client.responses.create(...).Construtores de cliente Azure:
AzureOpenAI(...)→OpenAI(base_url=..., api_key=...).Ferramentas: converta definições de ferramentas para chamada de função do formato aninhado (
{"type": "function", "function": {"name": ...}}) para o formato plano Responses ({"type": "function", "name": ...}); utilizetool_choice; retorne resultados de ferramentas como itens{"type": "function_call_output", "call_id": ..., "output": ...}(não{"role": "tool", ...}).Ciclos de ferramentas: quando o modelo retornar chamadas de função, anexe os itens
response.outputà conversa (não um dicionário manual{"role": "assistant", "tool_calls": [...]}), depois anexe itensfunction_call_outputpara cada resultado.Exemplos de ferramentas few-shot: se a conversa incluir exemplos fixos de chamadas de ferramentas, converta-os em itens
{"type": "function_call", "id": "fc_...", "call_id": "fc_...", ...}+{"type": "function_call_output", ...}. IDs devem começar comfc_.pydantic_function_tool(): este auxiliar ainda gera o formato aninhado antigo e não é compatível comresponses.create(). Substitua por definições manuais de ferramentas ou um wrapper de achatamento.Multi-turn: mantenha o histórico da conversa na aplicação; passe os turnos anteriores via itens
input.Formatos: substitua
response_formatde nível superior do Chat portext.formatnas Responses. Forma canónica:text={"format": {"type": "json_schema", "name": "Output", "strict": True, "schema": {...}}}.Itens de conteúdo: substitua Chat
content[].type: "text"por Responsescontent[].type: "input_text"para os turnos do utilizador/sistema.Itens de conteúdo de imagem: substitua Chat
content[].type: "image_url"por Responsescontent[].type: "input_image". O campoimage_urlmuda de um objeto aninhado{"url": "..."}para uma string simples. Veja o cheat sheet para exemplos antes/depois.Esforço de raciocínio: migre apenas
reasoningse já existir no código original.Tratamento de erros do filtro de conteúdo: a estrutura do corpo do erro mudou. Chat Completions usava
error.body["innererror"]["content_filter_result"](singular); Responses API usaerror.body["content_filters"][0]["content_filter_results"](plural, dentro de um array). Código que acede ainnererrorlançará umKeyError. Reescreva para usar o novo caminho.Chamadas HTTP brutas: se a aplicação usar diretamente a REST API Azure OpenAI (via
requests,httpx, etc.) com/openai/deployments/{name}/chat/completions?api-version=..., reescreva para/openai/v1/responses. O corpo do pedido muda:messages→input, adicionarmax_output_tokensestore: false, remover o parâmetro de consultaapi-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 bruto).
Passo 2: Aplicar Migração
Notas de Migração (Chat Completions → Responses)
- Porquê migrar: Responses é a API unificada para texto, ferramentas e streaming; Chat Completions é legado. Com o GPT-5, Responses é obrigatório para melhor desempenho.
- HTTP: o endpoint Azure muda de
/openai/deployments/{name}/chat/completionspara/openai/v1/responses. - Campos:
messages→input,max_tokens→max_output_tokens.temperaturemantém-se. - Formatos:
response_format→text.formatcom um objeto apropriado. - Itens de conteúdo: substitua Chat
content[].type: "text"por Responsescontent[].type: "input_text"para os turnos do sistema/utilizador. - Itens de conteúdo de imagem: substitua Chat
content[].type: "image_url"por Responsescontent[].type: "input_image". Achate o campoimage_urlde{"image_url": {"url": "..."}}para{"image_url": "..."}(uma string simples – pode ser um URL HTTPS ou um URI de dadosdata:image/...;base64,...).
Referência de mapeamento de parâmetros
| Chat Completions | Responses API |
|---|---|
prompt |
input |
messages |
input (array de itens) |
max_tokens |
max_output_tokens |
response_format |
text.format (objeto) |
temperature |
temperature (inalterado) |
stop |
stop (inalterado) |
frequency_penalty |
frequency_penalty (inalterado) |
presence_penalty |
presence_penalty (inalterado) |
tools / chamada de função |
tools (inalterado) |
seed |
Remover (não suportado) |
store |
store (definido para false) |
content[].type: "text" |
content[].type: "input_text" |
content[].type: "image_url" |
content[].type: "input_image" |
"image_url": {"url": "..."} |
"image_url": "..." (string simples) |
Para exemplos completos de código antes/depois, veja cheat-sheet.md.
Para migração de infraestruturas de teste (mocks, snapshots, assertions), veja test-migration.md.
Para resolução de problemas e armadilhas, veja troubleshooting.md.
Retenção de Dados e Estado
- Defina
store: falseem todos os pedidos Responses. - Não confie em IDs de mensagens anteriores ou contexto armazenado no servidor; mantenha estado gerido pelo cliente e minimize metadados.
Critérios de Aceitação
Portões a nível de código (todos devem passar)
- Nenhuma correspondência para
rg "chat\.completions\.create|ChatCompletion\.create|Completion\.create"nos ficheiros migrados. - Nenhuma correspondência para
rg "AzureOpenAI\(|AsyncAzureOpenAI\("— todos os construtores usamOpenAI/AsyncOpenAIcom o endpoint v1. - Nenhuma correspondência para
rg "models\.github\.ai|models\.inference\.ai\.azure"— caminhos de código de GitHub Models removidos. - Nenhuma correspondência para
rg "OpenAIChatCompletionClient"— código MAF 1.0.0+ usaOpenAIChatClient(que usa Responses API). Em versões anteriores a 1.0.0, atualize paraagent-framework-openai>=1.0.0. - Todas as chamadas
ChatOpenAI(...)incluemuse_responses_api=True. - Nenhuma correspondência para
rg "choices\[0\]"— todo o acesso a respostas usaresp.output_textou o esquema de saída Responses. - Sem
response_formatao nível superior; toda saída estruturada usatext={"format": {...}}. -
openai>=1.108.1eazure-identityemrequirements.txtoupyproject.toml; dependências reinstaladas. -
store=Falsedefinido em cada chamadaresponses.create. - Sem
api_versionna construção do cliente;AZURE_OPENAI_API_VERSIONremovido de ficheiros env e infra.
Portões da infraestrutura de teste (todos devem passar)
- Nenhuma correspondência para
rg "ChatCompletionChunk|AsyncCompletions\.create|chat\.completions" tests/. - Nenhuma correspondência para
rg "_azure_ad_token_provider" tests/— as asserts foram atualizadas para verificarisinstance(client, AsyncOpenAI)oubase_url. - Nenhuma correspondência para
rg "prompt_filter_results|content_filter_results" tests/— mocks de filtros específicos Azure removidos. - Fixtures de mocks usam
kwargs.get("input")e nãokwargs.get("messages"). - Ficheiros snapshot / golden atualizados para a forma de streaming Responses (sem
choices[0],function_call,logprobs, etc.). -
pytestpassa sem falhas após todas as atualizações de teste.
Portões comportamentais (verificação manual ou via harness de teste)
- Completação básica:
responses.createnão-streaming retornaoutput_textnão vazio. - Paridade no streaming: se o código original usava streaming, o código migrado transmite streaming e produz eventos
response.output_text.deltacom deltas não vazios. - Saída estruturada: se usar
text.formatcomjson_schema,json.loads(resp.output_text)faz parse com sucesso e corresponde ao esquema. - Loop de chamada de ferramentas: se for usadas ferramentas, o modelo emite chamadas a ferramentas, a aplicação executa e o pedido de seguimento retorna um
output_textfinal (sem ciclo infinito). - Paridade assíncrona: se foi usado
AsyncAzureOpenAI, o equivalenteAsyncOpenAIfunciona comawait. - Taxa de erro: sem novos erros 400/401/404 comparados à linha base pré-migração.
Entregáveis
- O sumário inclui ficheiros editados, contagens antes/depois dos locais de chamada legado, e próximos passos.
- As alterações são apenas edições da árvore de trabalho (sem commits).
Requisitos de Versão do SDK
| Pacote | Versão Mínima |
|---|---|
openai |
>=1.108.1 |
azure-identity |
Mais recente (para autenticação EntraID) |
Referências
- Cheat Sheet — todos os excertos de código
- Test Migration — mocks, snapshots, assertions
- Troubleshooting — erros, tabela de riscos, armadilhas
- detect_legacy.py — scanner automatizado
- Azure OpenAI Starter Kit
- Documentação da API Azure OpenAI Responses
- Ciclo de vida das versões da API Azure OpenAI
- Referência da API OpenAI Responses
Aviso Legal: Este documento foi traduzido utilizando o serviço de tradução automática Co-op Translator. Embora nos esforcemos pela precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa 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 resultantes da utilização desta tradução.
Source: microsoft/ai-agents-for-beginners → translations/pt-PT/.agents/skills/azure-openai-to-responses/SKILL.md