Skip to content
This page has been auto-translated and may contain errors.View in English

Chat Completions y Responses ​

Abre el playground de la lección y encontrarás dos botones, uno para cada una de las dos formas de API de OpenAI: Chat Completions y Responses. Volverás a encontrar ambos nombres en el código de otras personas y en la documentación del proveedor, generalmente sin explicación de por qué existen dos.

Hacen lo mismo. Ambas envían instrucciones y un mensaje del usuario a un modelo y reciben una respuesta. Lo que difiere es dónde pones cada parte de la solicitud, y dónde aparece el texto de la respuesta después, y esa segunda diferencia es la que te causa problemas cuando copias un fragmento de código de algún lado.

Esos botones del playground llaman rutas en el servidor Express, el pequeño programa Node que el proyecto del curso ejecuta junto a la página, para que las solicitudes al modelo ocurran fuera del código del navegador y tu clave API nunca quede expuesta. En Scrimba, la salida de esas rutas del servidor aparece en la pestaña Runner en lugar de la pestaña Console.

Ambos ejemplos a continuación usan un cliente construido de la misma manera, con los valores que guardaste en Configuración del proveedor:

js
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AI_KEY,
  baseURL: process.env.AI_URL,
});

Chat Completions ​

Chat Completions fue la primera API estable y ampliamente adoptada para modelos de lenguaje, y otros proveedores implementaron la misma forma, por eso aparece en tantas muestras de código. Coloca el prompt del sistema y la entrada del usuario juntos en messages:

js
const response = await client.chat.completions.create({
  model: process.env.AI_MODEL,
  messages: [
    { role: "system", content: "Eres un asistente útil." },
    {
      role: "user",
      content: "Dame una explicación breve de por qué las herramientas de código abierto son importantes.",
    },
  ],
});

El texto de la respuesta está anidado bajo la primera opción:

js
response.choices[0].message.content
JunoChat Completions Todo va en una lista messages: primero el prompt del sistema, luego tu pregunta. La respuesta regresa en response.choices[0].message.content.

Ese camino se ve complicado las primeras veces que lo escribes. Léelo lentamente una vez, porque lo verás en casi todas las muestras de código en línea.

JunoChat Completions Un array contiene toda la solicitud, con role definiendo para qué sirve cada entrada. La respuesta está bajo choices[0] porque la API puede devolver varias alternativas de completado en una sola llamada, y casi siempre quieres la primera.

Reconocer ese camino es útil en sí mismo: te dice de un vistazo que un fragmento que encontraste es Chat Completions y no Responses.

JunoChat Completionschoices es un plural que casi siempre es uno. Existe por el parámetro n, que pide varios completados independientes de la misma solicitud, y la forma se mantiene incluso aunque la mayoría del código deje n en 1.

Eso explica la ergonomía que estás a punto de cambiar. Cada lectura cuesta un índice de array que no lleva información, y cada turno que agregues a una conversación vuelve a la misma lista plana manualmente.

Responses ​

Responses le da al prompt del sistema su propio campo instructions. Para una solicitud simple, input puede ser una cadena directa:

js
const response = await client.responses.create({
  model: process.env.AI_MODEL,
  instructions: "Eres un asistente útil.",
  input: "Dame una explicación breve de por qué las herramientas de código abierto son importantes.",
});

La misma cadena directa puede moverse a un objeto de mensaje role/content cuando necesitas la forma de mensaje:

js
input: [
  {
    role: "user",
    content: "Dame una explicación breve de por qué las herramientas de código abierto son importantes.",
  },
],

Responses expone el texto de la respuesta directamente:

js
response.output_text

También mantiene la estructura completa de la respuesta en response.output. Una respuesta de texto básica generalmente contiene un elemento de mensaje cuyo content incluye el mismo texto de salida.

JunoResponses El prompt del sistema obtiene su propio campo instructions en lugar de compartir la lista, e input puede ser una cadena simple cuando solo haces una pregunta.

La respuesta está en response.output_text, un paso de distancia en lugar de tres. Si el botón Responses imprime una respuesta en la pestaña Runner, tu proveedor y modelo manejan esta API.

JunoResponsesinstructions mantiene el prompt del sistema fuera de la conversación, así que no estás reconstruyendo un array cada turno para mantenerlo al frente, e output_text te da el texto directamente.

input sigue tomando la forma de array-de-mensajes cuando la necesitas, que es lo que usa el historial de conversación más adelante en el curso. La forma de cadena es un atajo para el caso simple, no una API diferente.

JunoResponsesoutput_text es un ayudante del SDK sobre output, que es el valor de retorno real: una lista de elementos tipados en lugar de un único mensaje. Un turno que llama herramientas devuelve elementos de llamada de herramienta en esa lista, y una única cadena de contenido no tendría lugar para ponerlos.

Entonces lee output_text para una respuesta final y output cada vez que necesites saber qué hizo realmente el modelo.

Por qué el curso usa Responses ​

Chat Completions sigue siendo una API compatible, y la funcionalidad de agentes en este curso podría construirse con ella.

El curso usa Responses por la diferencia que ya puedes ver en los dos bloques de código anteriores. Leer una respuesta es response.output_text en lugar de response.choices[0].message.content, y el prompt del sistema tiene un hogar con nombre en lugar de ser el primer elemento en un array al que también agregas turnos del usuario. Una vez que las llamadas de herramientas y el historial de conversación empiezan a acumularse, esa forma significa menos código sosteniendo las piezas.

OpenRouter también soporta la API de Responses, con una diferencia respecto a OpenAI: no almacena el estado de la conversación en sus servidores. Eso no afecta el curso, que mantiene su propio historial de conversación en código.

Usa la salida completa cuando necesites la estructura

output_text es la manera conveniente de leer una respuesta de texto final. Usa output cuando necesites inspeccionar el conjunto completo de elementos de respuesta.

JunoPor qué el curso usa Responses Ambas APIs pueden hacer todo lo que este curso necesita. Responses es la que tiene menos que escribir: la respuesta está un paso de distancia y el prompt del sistema tiene su propio campo.

No necesitas memorizar las diferencias. Usa Responses aquí, y reconoce Chat Completions cuando lo encuentres en otro lado.

JunoPor qué el curso usa Responses La elección es sobre cuánto código adhesivo escribes alrededor de la llamada. Chat Completions sigue siendo compatible y bastante código en producción la usa, así que si heredas una base de código construida con ella, nada aquí dice que necesite reescribirse.

Si estás en OpenRouter, la falta de estado del lado del servidor es por qué el curso almacena su propio historial. Cada solicitud lleva la conversación que necesita.

JunoPor qué el curso usa Responses La diferencia se compone en lugar de aparecer en la primera solicitud. En un bucle de llamada de herramientas agregas el turno del modelo, luego los resultados de la herramienta, luego llamas de nuevo, y Chat Completions te tiene reconstruyendo ese array plano cada vez mientras mantienes el mensaje del sistema fijado al frente.

Responses modela un turno como elementos, que es la forma que el bucle realmente tiene. Los dos ejemplos de juguete anteriores no pueden mostrar eso, por eso vale la pena saberlo antes de que lo encuentres.

Hacia dónde va esto ​

Ejecutar el código localmente explica cómo se conectan el navegador y el servidor Express después de que descargas una lección de Scrimba. Si aún no has elegido un modelo, Modelos recomendados cubre lo que requiere el trabajo de agentes.

JunoHacia dónde va esto Si ambos botones imprimen una respuesta en la pestaña Runner, tu configuración funciona y puedes continuar con el curso. La guía local es solo para cuando quieres el mismo proyecto en tu propio computador.
JunoHacia dónde va esto La configuración de botón-a-ruta aquí es la misma que ejecutarás localmente: la página envía una solicitud a /api, Vite la pasa a Express, y la llamada al modelo ocurre en el servidor.
JunoHacia dónde va esto Un modelo que falla la solicitud de Responses aquí no llegará lejos en el curso, ya que cada lección después de esta se construye sobre esa API. Si falla, verifica el modelo contra la lista recomendada antes que nada.