Para un proyecto nuevo, Responses API suele ser la mejor base. Para un servicio estable que solo genera texto con Chat Completions, no hay necesidad de una reescritura urgente. La guía actual de OpenAI recomienda Responses para proyectos nuevos y confirma que Chat Completions sigue soportada.
La diferencia no es un nombre nuevo para el mismo JSON. Chat Completions organiza la llamada alrededor de mensajes y opciones de respuesta. Responses representa mensajes, razonamiento, llamadas a funciones y resultados como Items tipados. Ese cambio alcanza al parser, el estado de conversación, las herramientas, el streaming y la observabilidad.
Una llamada mínima oculta el cambio de modelo
Para texto de un solo turno, ambas rutas parecen casi iguales:
pythoncompletion = client.chat.completions.create( model="gpt-5.6", messages=[{"role": "user", "content": "Clasifica este ticket"}], ) chat_text = completion.choices[0].message.content response = client.responses.create( model="gpt-5.6", input="Clasifica este ticket", ) response_text = response.output_text
output_text es una utilidad del SDK para reunir el texto final. Si la aplicación necesita tool calls, citas, reasoning summaries o el estado de cada elemento, debe recorrer response.output.
| Contrato de la aplicación | Chat Completions | Responses API |
|---|---|---|
| endpoint | /v1/chat/completions | /v1/responses |
| entrada | messages | input y instructions opcionales |
| salida | choices[].message | Items tipados en output[] |
| varios candidatos | n devuelve varias choices | una generación por response |
| continuidad | reenviar historial | previous_response_id, Conversations o replay manual |
| salida estructurada | response_format | text.format |
| streaming | chunks con choices[].delta | eventos semánticos tipados |
Un array sencillo de role/content puede reutilizarse como input de Responses. Eso facilita una prueba inicial; no convierte los cuerpos de respuesta ni las herramientas en compatibles.
El estado de conversación se elige explícitamente
Con Chat Completions, la aplicación suele guardar el historial relevante y volver a enviarlo en messages. Responses permite encadenar un turno mediante previous_response_id:
pythonfirst = client.responses.create( model="gpt-5.6", instructions="Responde como analista de incidentes y sé conciso.", input="Agrupa estas alertas por causa probable.", ) next_turn = client.responses.create( model="gpt-5.6", previous_response_id=first.id, instructions="Responde como analista de incidentes y sé conciso.", input="Deja solo el grupo que requiere escalado inmediato.", )
La repetición de instructions es deliberada. La referencia de Responses indica que las instrucciones anteriores no se heredan automáticamente al usar previous_response_id. La política permanente sigue siendo responsabilidad de la aplicación.
Continuidad y retención de datos tampoco son sinónimos. Los controles de datos de OpenAI separan Responses, store, Zero Data Retention, background mode, caché y hosted tools. El documento actual indica al menos 30 días para application state almacenado de Responses, con configuración de organización y excepciones. Para requisitos de privacidad hay que revisar todas las superficies reales, no solo un booleano.
Las herramientas cambian de sobre y de identificador

Chat Completions incluye tool calls dentro del assistant message. El resultado vuelve como un mensaje role: "tool" vinculado por tool_call_id. Responses entrega un Item function_call y recibe un Item function_call_output enlazado mediante call_id.
pythonoutputs = [] for item in response.output: if item.type == "function_call": outputs.append({ "type": "function_call_output", "call_id": item.call_id, "output": run_tool(item.name, item.arguments), })
El loop debe procesar todas las llamadas, incluidas las paralelas. Las pruebas necesitan casos sin llamadas, con una, con varias, con argumentos inválidos, timeout, error y una segunda herramienta después del primer resultado. La guía oficial de function calling contiene los sobres actuales de ambos protocolos.
Responses también integra hosted tools como web search, file search, code interpreter y remote MCP. Es una ventaja clara para flujos agentic, pero cada herramienta sigue dependiendo de las capacidades del modelo elegido.
Streaming necesita un dispatcher, no solo concatenar texto
En Chat Completions suele concatenarse choices[0].delta.content. Responses emite eventos distintos para deltas de texto, argumentos de función, final de Item y final del response. La guía de streaming documenta ambos formatos.
El cliente debe distinguir completed, failed, incomplete, cancelación y corte de red. Un HTTP 200 o el primer fragmento de texto no prueban que la generación haya terminado. Conviene registrar response ID, estado final, tipos de Item, usage y motivo de error o incompletitud.
Structured Outputs también cambia de response_format a text.format. La guía de salida estructurada ayuda a separar dos necesidades: dar una respuesta con schema al usuario o invocar una función de la aplicación. Además del schema, hay que validar soporte del modelo, refusal y fallo de parsing.
La decisión depende del trabajo, no de una fecha límite falsa

Responses encaja mejor en nuevos desarrollos con continuidad de razonamiento, hosted tools, varias funciones, entrada multimodal o tareas largas. Mantener Chat Completions puede ser correcto para un servicio maduro de texto de un turno cuando la migración no aporta un beneficio material. El calendario de retirada de Assistants API no es una fecha límite de Chat Completions.
Para migrar, introduce primero un adapter interno y elimina la dependencia directa de choices[0] en el código de negocio. Ejecuta peticiones representativas por ambas rutas y compara resultados estructurados, refusal, truncado, intención de herramienta y usage, no frases idénticas. Después migra, por separado, estado, ciclo completo de herramientas, streaming y controles de datos.
La etiqueta “OpenAI-compatible” de un proveedor tercero suele referirse a Chat Completions y no demuestra compatibilidad con Responses. Comprueba endpoint, Items, eventos, tool envelopes, continuidad y errores en su documentación. La migración termina cuando la conversación puede recuperarse, ninguna llamada se pierde, el schema se parsea, el stream se cierra y un fallo deja evidencia suficiente para diagnosticarlo.



