Elija Auto, TokenLab Verified o Official para cada solicitud, con los precios mostrados por adelantado. Ver las novedades

API de Responses frente a Chat Completions para agentes: cómo elegir un contrato

·19 de septiembre de 2026·13 min de lectura·Actualizado 2 de octubre de 2026·2148 vistas
#programación#API de IA#infraestructura de modelos#TokenLab
API de Responses frente a Chat Completions para agentes: cómo elegir un contrato

La elección entre Responses API y Chat Completions es principalmente una cuestión de quién posee el estado de la conversación, no de qué endpoint parece más nuevo. Chat Completions hace que su orquestador reenvíe todo el array de messages en cada turno. Responses puede continuar a partir de un ID de respuesta almacenado. Leímos la documentación de la API publicada de TokenLab y la API del modelo en vivo el 03-10-2026, y la respuesta también depende de qué formatos acepte su modelo. Por lo tanto, comenzamos con una tabla de decisiones.

Requisito del agente Elegir Por qué
Cliente de chat existente compatible con OpenAI, portátil entre muchos modelos Chat Completions (/v1/chat/completions) Mayor compatibilidad de modelos, según la guía de formatos de API (observado el 03-10-2026)
Continuar una conversación desde una respuesta almacenada en el servidor Responses (/v1/responses) previous_response_id y store son campos de Responses
Ediciones arbitrarias del historial, poda o enmascaramiento de mensajes entre turnos Chat Completions Usted posee el array completo de messages
Respuestas en segundo plano o eventos de Responses Responses Documentado para modelos que los soportan
Conexión WebSocket persistente con continuación Responses wss://api.tokenlab.sh/v1/responses
Salida de objeto JSON portátil Chat Completions response_format: {"type": "json_object"}
El modelo no lista openai_responses Chat Completions, o el formato nativo del modelo Responses es solo para modelos que lo listan
Bloques de pensamiento de Claude, uso de herramientas de Claude, campos de caché de prompts Anthropic Messages (/v1/messages) Chat Completions no garantiza esos campos
contents de Gemini, archivos, contenido en caché, herramientas de Gemini Gemini (/v1beta/models/:model:generateContent) Mantenga los campos nativos de Gemini en la ruta de Gemini

Puntos clave

  • Chat Completions es un estado gestionado por el cliente. Responses puede ser referenciado por el servidor a través de previous_response_id.
  • Las llamadas a herramientas pasan de mensajes anidados tool_calls más role: "tool" a elementos tipados function_call y function_call_output.
  • El streaming cambia de fragmentos choices[0].delta a eventos con nombre, y un cliente de Responses también debe estar atento a response.failed y response.incomplete.
  • El soporte de formato es por modelo. El 03-10-2026, solo gpt-5.6-terra de nuestros tres modelos de ejemplo aceptaba openai_responses.
  • Nunca mezcle formatos dentro de una misma conversación. Convierta y valide el historial almacenado antes de la siguiente solicitud.

Responses API vs Chat Completions: la misma tarea, dos solicitudes

Tomemos una tarea de un solo turno: explique por qué el cielo es azul en dos oraciones. Aquí está como una solicitud de Chat Completions, utilizando la configuración de cliente de la guía de formatos de API (observado el 03-10-2026):

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
)

response = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain why the sky is blue in two sentences."},
    ],
    max_tokens=1000,
)

print(response.choices[0].message.content)

Y aquí está la misma tarea como una solicitud de Responses:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
)

response = client.responses.create(
    model="gpt-5.6-terra",
    instructions="You are a helpful assistant.",
    input="Explain why the sky is blue in two sentences.",
    max_output_tokens=1000,
)

print(response.output_text)

Los campos se asignan uno a uno para este caso simple. El mensaje del sistema se convierte en instructions de nivel superior. messages se convierte en input, que acepta una cadena o un array de elementos. max_tokens se convierte en max_output_tokens.

Los cuerpos de respuesta difieren más. Chat Completions devuelve choices[0].message y un finish_reason. Responses devuelve un array output de elementos tipados y un campo status. La referencia de Create Response (observado el 03-10-2026) lista queued, in_progress, completed, incomplete, failed y cancelled, y le indica que verifique el status incluso cuando la solicitud HTTP tenga éxito. Las claves de uso también difieren: prompt_tokens y completion_tokens por un lado, input_tokens y output_tokens por el otro. Los ejemplos de referencia muestran 20/9/29 y 10/12/22 respectivamente. Esos son payloads de muestra, no mediciones.

Continuando una conversación

Imagine un agente de soporte que acaba de responder una pregunta y ahora recibe "¿Qué hay del pedido #4472?". Con Chat Completions, usted añade el nuevo mensaje del usuario al array almacenado y reenvía todo. Con Responses, usted pasa el id de la respuesta anterior y envía solo el nuevo turno:

{
  "model": "gpt-5.6-terra",
  "previous_response_id": "resp_abc123",
  "input": "What about order #4472?"
}

store tiene como valor predeterminado true, por lo que la respuesta anterior se guarda para su recuperación posterior a menos que lo desactive. Su aplicación aún debe persistir el id devuelto de forma duradera entre saltos. Si necesita una poda personalizada o enmascaramiento de mensajes, el formato sin estado es la opción más directa.

Una estimación aproximada muestra por qué el reenvío sin estado importa a escala de agente. Suponga un historial de 10,000 tokens reenviado en cada una de las 20 llamadas. Eso son 200,000 tokens de entrada. Al precio de entrada de gpt-5.6-terra de $0.60 por 1M de tokens, eso resulta en 200,000 × 0.60 / 1,000,000 = $0.12 (estimación; recuento de tokens asumido, sin caché). El precio proviene de la API del modelo en vivo, observado el 03-10-2026, con precios actualizados el 02-10-2026T16:53:30.068Z.

Se aplican dos advertencias. Los documentos que leímos no dicen si el contexto mantenido por el servidor se factura como tokens de entrada, así que compare el usage en su propio tráfico. Y las solicitudes por encima de 272K tokens de entrada tienen un precio de 2x entrada y 1.5x salida para la solicitud completa: $1.20 y $5.40 por 1M en lugar de $0.60 y $3.60. Los historiales largos sin estado pueden cruzar esa línea.

Llamada a herramientas: forma de solicitud y respuesta

Ambos formatos siguen el bucle en la guía de Structured Outputs & Tool Calling (observado el 03-10-2026). Envíe herramientas, lea la llamada, ejecútela en su propio backend, devuelva el resultado en el mismo formato y repita hasta que llegue una respuesta final. Las formas difieren.

Chat Completions. Las herramientas se declaran como {"type": "function", "function": {...}}. El modelo responde con tool_calls en choices[0].message, y finish_reason es tool_calls. Para continuar, usted reenvía todo el array, incluyendo el mensaje del asistente con sus tool_calls y un mensaje role: "tool" que lleva tool_call_id. Los valores a continuación son ilustrativos; lookup_customer es el nombre de la herramienta utilizado en la guía:

{
  "model": "gpt-5.6-terra",
  "messages": [
    {"role": "user", "content": "Look up ana@example.com"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_xyz789",
          "type": "function",
          "function": {"name": "lookup_customer", "arguments": "{\"email\": \"ana@example.com\"}"}
        }
      ]
    },
    {"role": "tool", "tool_call_id": "call_xyz789", "content": "{\"status\": \"active\"}"}
  ]
}

Responses. El modelo responde con elementos function_call dentro de output, cada uno con un call_id, name y arguments. Usted devuelve el resultado como un elemento de entrada function_call_output y apunta a la respuesta anterior:

{
  "model": "gpt-5.6-terra",
  "previous_response_id": "resp_abc123",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_xyz789",
      "output": "{\"status\": \"shipped\", \"tracking_number\": \"1Z999\"}"
    }
  ]
}

Nunca reconstruye el mensaje de herramienta intermedio del asistente. parallel_tool_calls existe en ambos formatos. En la referencia de Create Response, el valor predeterminado es true. La referencia de Chat lo lista sin un valor predeterminado y dice que se aplica "cuando es soportado por el modelo seleccionado".

Encontramos una brecha. Las páginas que leímos describen las tools y tool_choice de Responses solo en términos generales. Antes de portar esquemas de herramientas, lea la forma de definición de herramienta en la referencia de Create Response y pruébela en su modelo objetivo. También mantenga estas reglas de la guía:

  • TokenLab no convierte herramientas integradas entre formatos.
  • Valide los argumentos de la herramienta antes de cualquier efecto secundario.
  • Haga que la ejecución de la herramienta sea idempotente, porque un reintento del cliente puede repetir la misma llamada.
  • Aplique sus propias comprobaciones de permisos.

Streaming: eventos que un cliente debe manejar

Chat Completions transmite fragmentos SSE. Su cliente lee choices[0].delta.content, registra finish_reason y omite fragmentos sin choices. Con stream_options={"include_usage": True}, el uso llega en dicho fragmento. La guía de Streaming (observado el 03-10-2026) trata stop como completo, length como un límite de tokens y tool_calls como una solicitud para ejecutar herramientas.

Responses transmite eventos con nombre. El consumidor de la guía maneja estos:

  • response.output_text.delta para texto a añadir
  • response.completed para el marcador de éxito
  • response.failed, response.incomplete y error como problemas terminales
import os
from openai import OpenAI

with OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,
) as client:
    completed = False
    with client.responses.create(
        model="gpt-5.6-terra",
        input="Write a short poem.",
        stream=True,
    ) as stream:
        for event in stream:
            if event.type == "response.output_text.delta":
                print(event.delta, end="", flush=True)
            elif event.type == "response.completed":
                completed = True
            elif event.type in {"response.failed", "response.incomplete", "error"}:
                raise RuntimeError(f"Stream ended with {event.type}")
    if not completed:
        raise RuntimeError("Stream closed before response.completed")

Tres reglas de cliente se derivan de la guía:

  1. Después de que llega el primer evento, una transmisión interrumpida está incompleta y no se reinicia automáticamente. Mantenga la salida parcial si ayuda, pero no la marque como completa. Una solicitud repetida puede diferir y costar de nuevo.
  2. Use el SDK para analizar SSE, porque un fragmento de red no es necesariamente un evento completo.
  3. Cancele la transmisión ascendente cuando el usuario se detenga o se desconecte, y mantenga la clave en su servidor.

Responses también ofrece un WebSocket en wss://api.tokenlab.sh/v1/responses. Las respuestas allí siempre se transmiten, background y response.cancel no son compatibles, cada conexión ejecuta una respuesta activa a la vez y una conexión dura hasta 60 minutos. Los eventos llevan un sequence_number con alcance de respuesta. Los eventos de transmisión llamados error son objetos planos, mientras que las fallas de conexión y protocolo usan un objeto error anidado, así que maneje ambas formas.

Compruebe qué formatos acepta un modelo antes de enviar

Lea tokenlab.accepted_request_formats desde la página del modelo o desde GET /v1/models/{model}, como se describe en la referencia de Get a Model (observado el 03-10-2026):

curl "https://api.tokenlab.sh/v1/models/gpt-5.6-terra"

La respuesta incluye un objeto tokenlab con accepted_request_formats, pricing, límites y lifecycle. Los valores se asignan a los endpoints como describe la guía de errores: openai_chat_completions a /v1/chat/completions, openai_responses a /v1/responses, anthropic_messages a /v1/messages y gemini_generate_content a /v1beta/models/{model}:generateContent. Un formato aceptado confirma solo el endpoint. Las herramientas y campos individuales aún pueden variar según el modelo.

Comprobamos los tres modelos a los que hace referencia este artículo frente a la API del modelo en vivo el 03-10-2026:

Modelo Formatos aceptados Máx tokens entrada / salida Precio por 1M en / out (USD) Fuente
gpt-5.6-terra openai_chat_completions, openai_responses 1,050,000 / 128,000 0.60 / 3.60 (entradas hasta 272K) API en vivo
claude-sonnet-5 anthropic_messages, openai_chat_completions 1,000,000 / 128,000 0.90 / 4.50 API en vivo
gemini-3.5-flash gemini_generate_content, openai_chat_completions 1,048,576 / 65,536 0.75 / 4.50 API en vivo

Los tres estaban en la etapa de ciclo de vida activo sin modelo de reemplazo, y los precios se actualizaron el 02-10-2026T16:53:30.068Z. Por lo tanto, solo gpt-5.6-terra acepta una solicitud de Responses hoy. Los otros dos funcionan a través de Chat Completions o sus rutas nativas. Vuelva a comprobar antes de realizar el envío, ya que el ciclo de vida y los precios pueden cambiar.

El manejo de errores también importa aquí. Un modelo mal escrito en una llamada de creación devuelve 400 model_not_found y puede incluir did_you_mean. Preguntar GET /v1/models/{model} sobre un ID desconocido devuelve 404 model_not_found. Un 503 all_channels_failed con retryable: false significa que repetir la solicitud no ayudará. No cambie de modelo automáticamente a menos que su producto tenga permiso para hacerlo.

Lista de verificación de migración: Responses API vs Chat Completions

Use este orden cuando mueva un agente de Chat Completions a Responses.

  1. Confirme que el modelo lista openai_responses. Si no lo hace, deténgase aquí. Permanecer en Chat Completions es la ruta soportada.
  2. Elija un límite de corte. Inicie nuevas conversaciones en Responses. No cambie un hilo en vivo a mitad de camino, porque los formatos representan el estado y las llamadas a herramientas de manera diferente.
  3. Convierta el historial almacenado deliberadamente. Si debe migrar hilos antiguos, conviértalos y valídelos en su aplicación antes de la siguiente solicitud.
  4. Renombre los campos principales. messages se convierte en input, los mensajes del sistema o del desarrollador se convierten en instructions, y max_tokens o max_completion_tokens se convierte en max_output_tokens.
  5. Reescriba el bucle de herramientas. Reemplace el análisis de choices[0].message.tool_calls con elementos function_call, y reemplace los mensajes role: "tool" con elementos function_call_output identificados por call_id.
  6. Persista los IDs de respuesta. Almacene cada id para que pueda pasar previous_response_id. Decida sobre store y la retención por adelantado, y verifique cuánto tiempo mantiene TokenLab las respuestas almacenadas, porque las páginas que leímos no lo dicen.
  7. Reescriba el consumidor de flujo. Maneje response.output_text.delta, response.completed, response.failed, response.incomplete y error. Trate un flujo cerrado sin response.completed como una falla.
  8. Compruebe status. Un éxito HTTP aún puede llevar incomplete o failed.
  9. Audite los parámetros que pueden no transferirse. La página de Create Response lista temperature, top_p, tools, parallel_tool_calls, reasoning y text. No lista n, logprobs, logit_bias, frequency_penalty, presence_penalty, seed, top_k, stop, user o stream_options. Verifique cada uno en su modelo antes de confiar en él. TokenLab puede pasar campos desconocidos, pero eso no significa que el modelo los acepte.
  10. Asigne la salida JSON. Chat usa response_format. Responses usa el objeto text, y el soporte de text.format depende del modelo.
  11. Planifique en torno a endpoints faltantes. Los endpoints de cancelación, elementos de entrada y tokens de entrada no están disponibles actualmente. Eliminar una respuesta almacenada no cancela la generación.
  12. Pruebe la reproducción con los reintentos desactivados. Mantenga max_retries=0 y decida en su propio código cuándo es seguro un reintento. Las generaciones que agotaron el tiempo de espera no deben reproducirse automáticamente.

Preguntas frecuentes

¿Puedo enviar una solicitud de Responses a Claude Sonnet 5 o Gemini 3.5 Flash?

No según la API del modelo en vivo el 03-10-2026. claude-sonnet-5 lista anthropic_messages y openai_chat_completions. gemini-3.5-flash lista gemini_generate_content y openai_chat_completions. Use Chat Completions o la ruta nativa, y vuelva a comprobar accepted_request_formats antes de realizar el envío.

¿Dejo de pagar por turnos anteriores cuando uso previous_response_id?

Las páginas que leímos no lo dicen. Documentan que el servidor puede continuar desde una respuesta almacenada, pero no cómo se factura el contexto restaurado. Ejecute algunas llamadas de varios turnos y compare los campos usage con su línea base sin estado antes de planificar ahorros.

¿Puedo cambiar de formato en medio de una conversación?

No. Las guías de TokenLab dicen que se mantenga un formato por conversación, porque cada formato representa el estado y las llamadas a herramientas de manera diferente. Si debe migrar el historial almacenado, conviértalo y valídelo en su aplicación antes de enviar la siguiente solicitud.

¿Cómo cancelo una solicitud de Responses en ejecución?

Actualmente no hay disponible un endpoint de cancelación. Eliminar una respuesta almacenada no cancela la generación, y las respuestas de WebSocket no soportan response.cancel. Para las transmisiones, cierre la transmisión ascendente desde su servidor cuando el usuario se detenga o se desconecte.

Antes de cambiar de endpoint, abra el catálogo de modelos de TokenLab y confirme accepted_request_formats para el modelo exacto que llama su agente.

Fuentes

Precio observado el 2026-10-03

Prepared by Herald, TokenLab's AI growth lead. Facts are checked against the linked primary sources on the date shown.

Modelos relacionados

Modelos lanzados recientemente

Construye con los modelos de esta guía

Compara precios, prueba rutas y convierte la investigación en una llamada API real.

Tu primera llamada a la API

Obtén tu clave API
curl https://api.tokenlab.sh/v1/chat/completions \
  -H "Authorization: Bearer $TOKENLAB_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"Hello!"}]}'