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

Chat Completions e Responses ​

Abra o playground da aula e você vai encontrar dois botões, um para cada uma das duas formas de API do OpenAI: Chat Completions e Responses. Você vai ver esses dois nomes novamente no código de outras pessoas e na documentação do próprio provedor, geralmente sem explicação de por que existem dois.

Eles fazem o mesmo trabalho. Ambos enviam instruções e uma mensagem do usuário para um modelo e recebem uma resposta de volta. O que muda é onde você coloca cada parte da requisição, e onde o texto da resposta aparece depois, e essa segunda diferença é a que causa confusão quando você está copiando um trecho de código de algum lugar.

Esses botões do playground chamam rotas no servidor Express, o pequeno programa Node que o projeto do curso executa junto com a página, para que as requisições ao modelo aconteçam longe do código do navegador e sua chave de API nunca fique exposta. No Scrimba, a saída dessas rotas do servidor aparece na aba Runner em vez da aba Console.

Ambos os exemplos abaixo usam um cliente construído da mesma forma, a partir dos valores que você salvou em Configuração do provedor:

js
import OpenAI from "openai";

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

Chat Completions ​

Chat Completions foi a primeira API estável e amplamente adotada para modelos de linguagem, e outros provedores implementaram a mesma forma, e é por isso que aparece em tantas amostras de código. Ela coloca o prompt do sistema e a entrada do usuário juntos em messages:

js
const response = await client.chat.completions.create({
  model: process.env.AI_MODEL,
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    {
      role: "user",
      content: "Give me a short explanation of why open-source tools matter.",
    },
  ],
});

O texto da resposta está aninhado sob a primeira choice:

js
response.choices[0].message.content
JunoChat Completions Tudo vai para uma única lista de messages: o prompt do sistema primeiro, depois sua pergunta. A resposta volta em response.choices[0].message.content.

Esse caminho parece chato nas primeiras vezes que você digita. Leia com calma uma vez, porque você vai ver em quase toda amostra de código online.

JunoChat Completions Um único array carrega toda a requisição, com role decidindo para o que serve cada entrada. A resposta fica em choices[0] porque a API pode retornar várias completações alternativas em uma chamada, e você quase sempre quer a primeira.

Reconhecer esse caminho é útil por si só: isso te diz num relance que um trecho que você encontrou é Chat Completions em vez de Responses.

JunoChat Completionschoices é um plural que quase sempre é um. Ele existe por causa do parâmetro n, que pede várias completações independentes da mesma requisição, e a forma se mantém mesmo que a maioria do código deixe n em 1.

Isso explica a ergonomia que você está prestes a deixar de lado. Cada leitura custa um índice de array que não traz informação, e cada turno que você adiciona a uma conversa volta para a mesma lista plana manualmente.

Responses ​

Responses dá seu próprio campo instructions ao prompt do sistema. Para uma requisição simples, input pode ser uma string direta:

js
const response = await client.responses.create({
  model: process.env.AI_MODEL,
  instructions: "You are a helpful assistant.",
  input: "Give me a short explanation of why open-source tools matter.",
});

A mesma string direta pode ser movida para um objeto message com role/content quando você precisa da forma de message:

js
input: [
  {
    role: "user",
    content: "Give me a short explanation of why open-source tools matter.",
  },
],

Responses expõe o texto da resposta diretamente:

js
response.output_text

Também mantém a estrutura completa da resposta em response.output. Uma resposta de texto básica geralmente contém um item de message cujo content inclui o mesmo texto de saída.

JunoResponses O prompt do sistema ganha seu próprio campo instructions em vez de compartilhar a lista, e input pode ser uma string simples quando você está perguntando apenas uma coisa.

A resposta fica em response.output_text, a um passo de distância em vez de três. Se o botão Responses imprime uma resposta na aba Runner, seu provedor e modelo suportam essa API.

JunoResponsesinstructions mantém o prompt do sistema fora da conversa, então você não está reconstruindo um array a cada turno para mantê-lo na frente, e output_text te dá o texto diretamente.

input ainda aceita a forma de array de messages quando você precisa, o que é o que o histórico de conversa usa mais adiante no curso. A forma de string é um atalho para o caso simples, não uma API diferente.

JunoResponsesoutput_text é um auxiliar do SDK sobre output, que é o valor real retornado: uma lista de itens tipados em vez de uma única message. Um turno que chama ferramentas retorna itens tool-call nessa lista, e uma string de conteúdo único não teria lugar para colocá-los.

Então leia output_text para uma resposta final e output sempre que você precisar saber o que o modelo realmente fez.

Por que o curso usa Responses ​

Chat Completions ainda é uma API suportada, e a funcionalidade de agente neste curso poderia ser construída com ela.

O curso usa Responses por causa da diferença que você já pode ver nos dois blocos de código acima. Ler uma resposta é response.output_text em vez de response.choices[0].message.content, e o prompt do sistema tem um lugar nomeado em vez de ser o primeiro item em um array no qual você também adiciona turnos do usuário. Assim que chamadas de ferramentas e histórico de conversa começam a se acumular, essa forma significa menos código mantendo as peças juntas.

OpenRouter também suporta a API Responses, com uma diferença do OpenAI: ele não armazena estado de conversa em seus servidores. Isso não afeta o curso, que mantém seu próprio histórico de conversa em código.

Use a saída completa quando você precisar da estrutura

output_text é a forma conveniente de ler uma resposta de texto final. Use output quando você precisar inspecionar o conjunto completo de itens de resposta.

JunoPor que o curso usa Responses Ambas as APIs podem fazer tudo que este curso precisa. Responses é a que tem menos para digitar: a resposta fica a um passo de distância e o prompt do sistema tem um campo próprio.

Você não precisa memorizar as diferenças. Use Responses aqui, e reconheça Chat Completions quando encontrá-la em outro lugar.

JunoPor que o curso usa Responses A escolha é sobre quanto código de cola você escreve ao redor da chamada. Chat Completions ainda é suportada e bastante código em produção a usa, então se você herdar uma base de código construída com ela, nada aqui diz que precisa ser reescrito.

Se você está no OpenRouter, o estado do lado do servidor ausente é por que o curso armazena seu próprio histórico. Cada requisição carrega a conversa que precisa.

JunoPor que o curso usa Responses A diferença se agrava em vez de aparecer na primeira requisição. Em um loop de chamada de ferramentas você adiciona o turno do modelo, depois os resultados da ferramenta, depois chama novamente, e Chat Completions te faz reconstruir esse array plano cada vez enquanto mantém a mensagem do sistema fixada na frente.

Responses modela um turno como itens, que é a forma que o loop realmente tem. Os dois exemplos brinquedos acima não conseguem mostrar isso, é por isso que vale a pena saber antes de encontrá-lo.

Para onde isso vai a seguir ​

Rodando o código localmente explica como o navegador e o servidor Express se conectam depois que você baixa uma aula do Scrimba. Se você ainda não escolheu um modelo, Modelos recomendados cobre o que o trabalho com agentes requer.

JunoPara onde isso vai a seguir Se ambos os botões imprimem uma resposta na aba Runner, sua configuração funciona e você pode continuar com o curso. O guia local é apenas para quando você quer o mesmo projeto no seu próprio computador.
JunoPara onde isso vai a seguir A configuração botão-para-rota aqui é a mesma que você vai rodar localmente: a página envia uma requisição para /api, Vite a passa para Express, e a chamada do modelo acontece no servidor.
JunoPara onde isso vai a seguir Um modelo que falha na requisição Responses aqui não vai longe no curso, já que toda aula depois dessa se baseia nessa API. Se falhar, confira o modelo contra a lista recomendada antes de qualquer outra coisa.