Crie uma camada de compatibilidade de API de respostas em um gateway de API de IA
Um gateway da API Responses não é apenas um proxy de conclusões de bate-papo com uma nova rota. Preserve itens de resposta, estado, chamadas de ferramentas, fluxos, continuidade de raciocínio, atribuição de uso e comportamento de downgrade com uma camada de compatibilidade de primeira classe.
Não implemente /v1/responses traduzindo cada solicitação em /v1/chat/completions e esperando que a forma esteja próxima o suficiente. Esse adaptador pode retornar texto, mas pode perder silenciosamente as partes com as quais os desenvolvedores se preocupam: itens de resposta, estado do lado do servidor, chamadas de ferramentas, continuidade de raciocínio, eventos de ciclo de vida de fluxo, semântica de cancelamento e atribuição de uso em nível de item.
O objetivo prático é uma camada de compatibilidade que trate as Respostas API como um protocolo mais rico. Mantenha o suporte de conclusões de bate-papo para clientes existentes, mas crie respostas como sua própria superfície de gateway com seu próprio modelo de estado, normalizador de fluxo, registro de chamadas de ferramenta, matriz de recursos e regras de fallback.
O que é factual, o que é política e o que é previsão?
Fatos: OpenAI descreve as respostas API como recursos unificadores que antes eram divididos entre conclusões de bate-papo e assistentes, incluindo suporte para ferramentas como pesquisa na Web, pesquisa de arquivos e uso de computador. O API expõe campos como previous_response_id, streaming, seleção de ferramentas e ferramentas integradas. SDK a documentação mostra que previous_response_id pode fornecer continuidade de conversação, enquanto as instruções anteriores não são transportadas automaticamente e devem ser reenviadas quando ainda forem aplicáveis. A referência de streaming de OpenAI inclui ciclo de vida de resposta e eventos de saída distintos, em vez de apenas deltas de token.
Recomendações: Um gateway deve preservar essas semânticas em vez de nivelá-las por padrão. Ele deve rejeitar ou fazer downgrade explicitamente de solicitações quando um provedor de destino não puder oferecer suporte ao comportamento exigido.
Previsão: Mais cargas de trabalho do agente dependerão da estrutura do item de resposta, dos rastreamentos de execução da ferramenta e do contexto de raciocínio com estado. Os gateways que modelam esses conceitos agora serão mais fáceis de estender do que os gateways que tratam as respostas como um ponto final cosmético.
Definir um contrato de compatibilidade separado para respostas
O primeiro erro de implementação é assumir que OpenAI-compatível significa um esquema universal de solicitação e resposta. Na prática, /v1/chat/completions e /v1/responses devem ser contratos de compatibilidade separados.
Mantenha uma camada compartilhada de autenticação, cobrança, cota e roteamento, mas separe a camada de protocolo:
- Superfície de conclusões de bate-papo: mensagens, escolhas, deltas, chamadas de ferramentas em formato de bate-papo, comportamento legado do cliente.
- Superfície de respostas: itens de entrada, itens de saída, IDs de resposta, referências de respostas anteriores, eventos de ferramentas mais avançados, eventos de fluxo de ciclo de vida, campos relacionados ao raciocínio e estado de resposta final.
Essa divisão é importante para testes de conformidade. Um adaptador de provedor que passa nos testes de bate-papo ainda pode falhar nos testes de respostas porque não pode preservar previous_response_id, ordem de itens, estrutura de recusa, metadados de ferramentas hospedadas ou nomes de eventos de streaming.
Um contrato de compatibilidade mínima deve responder:
- Quais campos de solicitação são aceitos, rejeitados, transformados ou ignorados?
- Quais tipos de itens de resposta são preservados?
- Quais tipos de ferramentas são compatíveis com cada provedor e modelo?
- O provedor pode manter o estado de conversação ou o gateway deve mantê-lo?
- O que acontece quando
store=falseé solicitado? - Quais eventos de transmissão são garantidos?
- Como são registrados o cancelamento, o tempo limite e o uso parcial?
Se você já possui um AI API gateway, trate o suporte do Responses como uma expansão de protocolo, não como um alias de rota.
Use um modelo de item de resposta canônico
As Respostas API retornam mais de uma mensagem do assistente. Ele pode representar diferentes itens e eventos de saída. Seu gateway precisa de um modelo canônico interno antes de ser mapeado para qualquer provedor.
Um esquema de item interno prático pode começar assim:
{
"gateway_response_id": "gw_resp_...",
"provider_response_id": "resp_...",
"tenant_id": "ten_123",
"key_id": "key_456",
"model_alias": "agent-default",
"provider": "openai",
"items": [
{
"item_id": "item_1",
"type": "text",
"role": "assistant",
"content": [{ "type": "output_text", "text": "..." }],
"status": "completed"
},
{
"item_id": "item_2",
"type": "function_call",
"call_id": "call_abc",
"name": "lookup_order",
"arguments_json": "{\"order_id\":\"123\"}",
"status": "completed"
}
],
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"reasoning_tokens": null,
"tool_units": []
},
"status": "completed"
}
Inclua tipos de itens antes mesmo que cada fornecedor possa produzi-los. As categorias úteis incluem:
- Saída de texto
- Recusas
- Chamadas de função
- Saídas de função enviadas pelo aplicativo
- Resumos de raciocínio ou metadados relacionados ao raciocínio, quando disponíveis
- Referências de arquivo
- Pesquisa na Web, pesquisa de arquivos, uso do computador ou outros eventos de ferramentas hospedadas
- Metadados finais de uso e faturamento
O objetivo não é expor um esquema proprietário aos usuários. O objetivo é evitar que o gateway jogue fora informações antes de poder auditar, cobrar, transmitir, reproduzir ou transformá-las.
Crie um livro-razão estadual de propriedade do gateway
previous_response_id é o campo que mais expõe a diferença entre proxy de bate-papo sem estado e compatibilidade de respostas. Se um cliente fizer referência a uma resposta anterior, o gateway deverá saber o que esse ID significa, se o locatário tem permissão para usá-lo e se o provedor pode continuar a partir dele.
Crie um razão de estado codificado por inquilino e ID de resposta:
{
"gateway_response_id": "gw_resp_789",
"provider_response_id": "resp_provider_789",
"previous_gateway_response_id": "gw_resp_456",
"tenant_id": "ten_123",
"user_id": "user_999",
"key_id": "key_456",
"model": "gpt-...",
"provider": "openai",
"store_mode": "provider|gateway|none",
"retention_policy": "standard|zero_retention|custom_30d",
"instructions_hash": "sha256:...",
"tool_policy_id": "tools_readonly_v3",
"created_at": "...",
"expires_at": "...",
"deleted_at": null
}
Regra importante: não emule automaticamente previous_response_id reproduzindo o histórico completo do bate-papo, a menos que o locatário tenha permitido explicitamente esse comportamento de retenção e custo. A repetição pode aumentar o custo do token, alterar a postura de privacidade e alterar o comportamento do modelo. É mais seguro retornar um erro de capacidade claro do que enviar silenciosamente o conteúdo da conversa armazenada que o aplicativo não esperava que você retivesse ou reutilizasse.
Modos de tratamento de estado
- Estado do provedor: O provedor upstream armazena contexto suficiente e o gateway mapeia IDs de resposta do gateway para IDs de resposta do provedor.
- Estado do gateway: O gateway armazena os itens anteriores necessários e reconstrói o contexto quando permitido.
- Sem estado: A solicitação usa
store=falseou a política do locatário proíbe a retenção.previous_response_iddeve ser rejeitado, a menos que o provedor possa honrar a solicitação sem retenção do gateway e a política permita isso.
Lembre-se também de que as instruções anteriores podem precisar ser reenviadas pelo cliente quando continuarem a ser aplicadas. O gateway não deve inventar instruções ocultas para compensar, a menos que esse comportamento faça parte de uma política explícita do locatário.
Validar ferramentas antes do envio
As respostas tornam o uso da ferramenta mais centralizado. Uma camada de compatibilidade deve lidar com duas categorias amplas:
- Ferramentas de aplicação: Definições de funções fornecidas pelo cliente, executadas fora do provedor de modelo, com saídas enviadas de volta ao API.
- Ferramentas do provedor hospedado: pesquisa na Web, pesquisa de arquivos, uso do computador, execução de código, aterramento ou ferramentas semelhantes executadas pelo provedor ou infraestrutura controlada por gateway.
Na entrada, valide os esquemas da ferramenta antes do roteamento:
- Rejeitar JSON esquema inválido antecipadamente.
- Aplicar tamanho máximo de esquema e profundidade de aninhamento.
- Verifique os nomes das ferramentas para verificar a compatibilidade do provedor.
- Aplica escopos de locatário, chave, usuário e ambiente.
- Exigir portas de aprovação para ferramentas que gravam dados, gastam dinheiro, acessam sistemas confidenciais ou chamam conectores externos.
Para chamada de função de aplicativo, exija um ID de chamada estável. O modelo emite uma chamada de função com call_id; o aplicativo envia a saída da ferramenta referenciando esse ID; o gateway registra ambos no mesmo rastreamento. Sem essa chave de junção, os registros de auditoria e as novas tentativas tornam-se ambíguos.
Para ferramentas hospedadas, reserve o orçamento antes do envio e liquide os custos depois. Ferramentas hospedadas podem adicionar cobranças fora da contabilidade de token comum, portanto, conecte o registro de ferramentas à IA unificada API faturamento em vez de ocultar esses custos dentro de um total genérico de chamadas de modelo.
Normalize o streaming como eventos, não como texto de token
Um proxy de bate-papo muitas vezes consegue encaminhar deltas de token. Um gateway de respostas não pode. O fluxo tem significado de ciclo de vida: uma resposta pode começar, os itens de saída podem começar e ser concluídos, o texto pode chegar em deltas, as chamadas de ferramenta podem ser montadas de forma incremental, o uso pode chegar no final ou durante o fluxo e a resposta pode falhar ou ser cancelada.
Defina um esquema de evento de gateway e mapeie cada fluxo de provedor nele:
event: response_started
data: { "response_id": "gw_resp_123", "status": "in_progress" }
event: output_item_started
data: { "item_id": "item_1", "type": "text" }
event: text_delta
data: { "item_id": "item_1", "delta": "Hello" }
event: tool_call_delta
data: { "item_id": "item_2", "call_id": "call_abc", "arguments_delta": "{\"order" }
event: usage_delta
data: { "output_tokens": 12 }
event: completed
data: { "response_id": "gw_resp_123", "usage": { ... } }
Eventos normalizados recomendados:
response_startedoutput_item_startedoutput_item_completedtext_deltarefusal_deltatool_call_deltatool_result_receivedusage_deltacompletedcancelledfailed
Quando o cliente se desconecta, propague o cancelamento upstream se o provedor oferecer suporte. Registre o estado da resposta parcial de qualquer maneira. Se o provedor retornar posteriormente o uso final por meio de um retorno de chamada atrasado ou parte final, reconcilie o razão. A compatibilidade de streaming tem tanto a ver com contabilidade e ciclo de vida quanto com latência.
Crie uma matriz de capacidade do provedor
O roteamento multimodelo é útil somente quando o gateway entende o que pode ser roteado com segurança. Adicione recursos específicos de respostas ao seu catálogo de modelos:
{
"model_alias": "agent-default",
"routes": [
{
"provider": "openai",
"model": "...",
"supports_responses": true,
"supports_previous_response_id": true,
"supports_store_false": true,
"supports_builtin_web_search": true,
"supports_function_calling": true,
"supports_stream_lifecycle_events": true,
"supports_reasoning_context_continuity": true,
"max_tool_schema_bytes": 65536
},
{
"provider": "provider_b",
"model": "...",
"supports_responses": false,
"chat_adapter_available": true,
"loss_profile": ["no_previous_response_id", "no_hosted_tools", "flattened_stream"]
}
]
}
O substituto deve reconhecer perdas. Se a solicitação exigir pesquisa na Web integrada e o provedor substituto não puder realizá-la, não responda silenciosamente sem pesquisar. Se a solicitação depender do contexto de raciocínio preservado e a rota substituta não puder preservá-la, retorne um erro de capacidade ou uma resposta de downgrade que o cliente optou explicitamente.
Uma opção de solicitação útil é:
{
"model": "agent-default",
"input": "...",
"fallback_policy": {
"allow_lossy": false,
"allowed_losses": []
}
}
Para casos de uso menos confidenciais, os locatários podem permitir downgrades específicos com perdas:
{
"fallback_policy": {
"allow_lossy": true,
"allowed_losses": ["flattened_stream", "no_reasoning_summary"]
}
}
O gateway deve registrar a decisão de fallback de qualquer maneira. Isso torna possível a depuração posterior quando um agente se comporta de maneira diferente após uma interrupção do provedor ou um novo roteamento do modelo.
Uso de atributos em nível de resposta e item
As chamadas de resposta podem custar mais do que as conclusões de bate-papo equivalentes porque podem incluir execução de ferramenta, contexto mais longo, tokens de raciocínio, pesquisa de arquivos, pesquisa na Web ou instruções repetidas. Uma única contagem agregada de tokens não é suficiente para um AI API painel de análise de uso.
Registre o uso em dois níveis:
- Nível de resposta: locatário, chave, usuário, modelo, provedor, latência, status final, tokens de entrada, tokens de saída, tokens de raciocínio quando relatados, custo total e rota de fallback.
- Nível do item/ferramenta: nome da ferramenta, ID da chamada, unidades de ferramentas hospedadas, IDs de arquivos, contagem de consultas de pesquisa, se disponível, latência da ferramenta, custo da ferramenta e resultado da política de aprovação.
Isso permite que os desenvolvedores respondam a perguntas concretas:
- O custo aumentou devido a estado mais longo, esforço de raciocínio, chamadas de ferramenta ou substituto?
- Qual inquilino ou API chave está gerando cobranças de ferramentas hospedadas?
- Qual resposta falhou após uma chamada de ferramenta, mas antes do texto final?
- Quais streams cancelados ainda incorreram em uso de upstream?
Trate a retenção e exclusão zero como um comportamento de primeira classe
O estado do lado do servidor é útil, mas altera as obrigações de retenção do gateway. Crie políticas na camada de protocolo em vez de tratá-las como uma configuração de registro.
Para cada solicitação de respostas, resolva:
- Política de retenção de locatário
- Preferência em nível de solicitação
store - Compatibilidade de retenção do provedor
- Se a reprodução do gateway é permitida
- Se as entradas e saídas da ferramenta podem ser armazenadas
- Comportamento de expiração e exclusão do estado de resposta
Se a retenção estiver desativada, o gateway ainda poderá manter metadados operacionais mínimos: carimbos de data/hora, IDs, status, contagens de tokens, custos e decisões políticas. Evite armazenar prompts brutos, resultados completos de ferramentas ou histórico reconstruído, a menos que a política permita.
Acessórios de conformidade a serem adicionados antes do lançamento
Não confie em testes manuais de caminho feliz. Adicione equipamentos que verificam o comportamento do protocolo em OpenAI rotas diretas, rotas adaptadas pelo provedor e cenários de fallback.
Conjunto mínimo de testes
- Resposta básica: item de texto é retornado com ID de resposta e uso estáveis.
- Estado multiturno: referências de segunda solicitação
previous_response_id; o gateway valida a propriedade do locatário e o modo de estado. - Instruções repetidas: verifica se as instruções omitidas não foram inventadas silenciosamente pelo gateway.
- Ida e volta da chamada de função: o modelo emite o ID da chamada; o aplicativo envia a saída; a resposta final une os dois registros.
- Política de ferramenta hospedada: a ferramenta integrada não autorizada é bloqueada antes do envio.
- Ordem de streaming: início da resposta, início do item, deltas, conclusão do item, uso e conclusão são emitidos em ordem válida.
- Cancelamento de stream: a desconexão do cliente aciona o cancelamento de upstream onde há suporte e registra o uso parcial.
- Rejeição de substituto: provedor sem semântica de respostas obrigatórias retorna erro de capacidade.
- Ativação de fallback com perdas: a solicitação com perdas permitidas recebe um marcador de downgrade explícito.
- Modo de retenção zero: a reprodução de estado e a retenção de prompt do lado do gateway estão bloqueadas.
Sequência de implementação recomendada
- Exponha uma rota beta. Adicione
/v1/responsessem alterar o comportamento de bate-papo existente. - Implemente primeiro a passagem para provedores com suporte nativo a respostas. Preserva IDs, itens, fluxos, uso e erros.
- Adicione o razão do estado. Mapeie os IDs do gateway para os IDs do provedor e imponha a propriedade do locatário.
- Adicione itens canônicos. Armazene metadados de itens necessários para auditoria, faturamento e reconstrução de fluxo.
- Adicione governança de ferramentas. Valide esquemas, aplique escopos e registre junções de chamadas de ferramentas.
- Adicione normalização de streaming. Converta fluxos específicos do provedor em eventos do ciclo de vida do gateway.
- Adicione roteamento com reconhecimento de capacidade. Permita apenas substitutos seguros por padrão.
- Adicione análises e liquidação de faturamento. Atribua token, raciocínio e uso de ferramentas separadamente.
- Publique notas de compatibilidade. Informe aos desenvolvedores quais campos são nativos, emulados, sem suporte ou com perdas.
Conclusão acionável
Uma camada de compatibilidade de Respostas API deve preservar o significado do protocolo, não apenas retornar texto plausível. Construa-o em torno de cinco objetos duráveis: um modelo de item de resposta canônico, um livro-razão de estado de conversação, um livro-razão de chamadas de ferramenta, um normalizador de eventos de streaming e uma matriz de capacidade do provedor.
O padrão mais seguro é a compatibilidade estrita: se uma rota não puder preservar o estado, as ferramentas, o contexto de raciocínio, os eventos de fluxo ou o comportamento de retenção necessários, retorne um erro de capacidade claro. Adicione substituto com perdas de aceitação somente quando os desenvolvedores entenderem o que será descartado. Essa abordagem pode parecer menos conveniente do que o nivelamento automático, mas evita o pior modo de falha: um aplicativo que parece compatível enquanto perde silenciosamente a semântica que o fez usar as Respostas API em primeiro lugar.