Thème
Langue
·5 min de lecture

Responses API vs Chat Completions : quelles différences et laquelle utiliser

Les différences pratiques entre /v1/responses et /v1/chat/completions sur une API compatible avec OpenAI : structure des requêtes, historique des conversations, outils, événements de streaming et choix de l’API à utiliser. Chaque exemple a été exécuté en direct sur GetVibe API.

Responses API vs Chat Completions : quelles différences et laquelle utiliser

Les API compatibles avec OpenAI proposent désormais deux principaux formats de requête : le format historique /v1/chat/completions et le nouveau format /v1/responses. GetVibe API accepte les deux avec une seule clé et une seule URL de base, https://getvibeapi.com/v1. Voici leurs différences en pratique, lequel choisir et le piège à éviter lorsque vous passez de l’un à l’autre.

La version courte

Chat CompletionsResponses
Point de terminaisonPOST /v1/chat/completionsPOST /v1/responses
Entréeun tableau messagesinput : une chaîne ou un tableau d’éléments
Prompt systèmeun message avec le rôle systemle champ instructions
Réponsechoices[0].messageun tableau output : raisonnement, message, appels de fonction
Limite de sortiemax_tokensmax_output_tokens
Utilisateursla plupart des SDK, frameworks et applications de chatCodex CLI et les SDK d’agents plus récents

Le format ne modifie ni le modèle, ni le prix, ni le nombre de tokens : dans les deux cas, vous êtes facturé pour les tokens d’entrée et de sortie du modèle.

La même requête dans les deux formats

Chat Completions :

curl https://getvibeapi.com/v1/chat/completions \
  -H "Authorization: Bearer $GETVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna",
    "messages": [
      {"role": "system", "content": "Répondez en une phrase."},
      {"role": "user", "content": "Que signifie HTTP 429 ?"}
    ],
    "max_tokens": 300
  }'

Responses :

curl https://getvibeapi.com/v1/responses \
  -H "Authorization: Bearer $GETVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna",
    "instructions": "Répondez en une phrase.",
    "input": "Que signifie HTTP 429 ?",
    "max_output_tokens": 300
  }'

Avec Chat Completions, le texte se trouve dans choices[0].message.content. Avec Responses, il se trouve dans output : pour les modèles de raisonnement, le premier élément est un élément reasoning et la réponse est l’élément de type message. Vous n’avez pas besoin de parcourir le tableau manuellement ; le SDK Python propose une propriété output_text.

import os
from openai import OpenAI

client = OpenAI(base_url="https://getvibeapi.com/v1", api_key=os.environ["GETVIBE_API_KEY"])

chat = client.chat.completions.create(
    model="gpt-6-luna",
    messages=[{"role": "system", "content": "Répondez en une phrase."},
              {"role": "user", "content": "Que signifie HTTP 429 ?"}],
)
print(chat.choices[0].message.content)

resp = client.responses.create(
    model="gpt-6-luna",
    instructions="Répondez en une phrase.",
    input="Que signifie HTTP 429 ?",
)
print(resp.output_text)

Responses ne se limite pas aux modèles OpenAI. Avant la publication, nous avons envoyé la même requête Responses à gpt-6-luna, claude-sonnet-5.5 et deepseek-v4.1-flash, et les trois ont répondu. DeepSeek a renvoyé un élément reasoning avant son élément message, exactement comme indiqué ci-dessus.

Historique des conversations : envoyez-le vous-même

C’est la seule chose à savoir avant de basculer. L’API Responses d’OpenAI peut conserver une conversation sur le serveur, de sorte que la requête suivante pointe vers la précédente avec previous_response_id. GetVibe API ne stocke pas vos conversations ; previous_response_id n’est donc pas pris en charge et store est ignoré. Lorsque nous l’avons essayé, la requête a été rejetée avec une erreur 400.

La méthode qui fonctionne est la même qu’avec Chat Completions : envoyez l’historique complet dans input.

history = [{"role": "user", "content": "Je m'appelle Ana. Souvenez-vous-en."}]
first = client.responses.create(model="gpt-6-luna", input=history)

history.append({"role": "assistant", "content": first.output_text})
history.append({"role": "user", "content": "Quel est mon nom ? Un seul mot."})
second = client.responses.create(model="gpt-6-luna", input=history)
print(second.output_text)  # Ana

Outils : une structure différente

Les appels de fonction fonctionnent dans les deux formats, mais la définition de l’outil se présente différemment. Avec Chat Completions, les champs de la fonction sont imbriqués dans un objet function ; avec Responses, ils se trouvent directement sur l’outil. L’appel arrive sous la forme d’un élément function_call distinct, et vous renvoyez le résultat sous la forme d’un élément function_call_output avec le même call_id.

import json

tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "Météo actuelle dans une ville",
    "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
        "additionalProperties": False,
    },
}]

items = [{"role": "user", "content": "Quel temps fait-il à Denver ?"}]
resp = client.responses.create(model="gpt-6-luna", input=items, tools=tools)

for item in resp.output:
    if item.type == "function_call":
        result = {"city": "Denver", "temp_f": 54, "sky": "overcast"}  # votre fonction
        items.append({"type": "function_call", "call_id": item.call_id,
                      "name": item.name, "arguments": item.arguments})
        items.append({"type": "function_call_output", "call_id": item.call_id,
                      "output": json.dumps(result)})

final = client.responses.create(model="gpt-6-luna", input=items, tools=tools)
print(final.output_text)

Lors de notre test, le modèle a appelé get_weather avec {"city":"Denver"}, et la deuxième requête a répondu qu’il faisait 54 °F à Denver, avec un ciel couvert. La version Chat Completions de la même boucle se trouve dans notre guide des appels de fonction.

Diffusion en continu

Les deux formats prennent en charge "stream": true, mais les événements diffèrent. Chat Completions envoie des lignes data: uniformes, chaque nouveau fragment de texte se trouvant dans choices[0].delta.content. Responses envoie des événements nommés : response.created en premier, response.output_text.delta avec les fragments de texte, puis response.completed à la fin. Si vous analysez vous-même le flux au lieu de passer par un SDK, vous avez besoin d’un analyseur adapté au format concerné.

Lequel choisir

  • Chat Completions si vous disposez déjà de code basé dessus, ou si vous utilisez un framework, une application de chat ou une plateforme no-code. Presque tous les outils le prennent en charge, et rien ne justifie de réécrire du code fonctionnel uniquement pour changer de format.
  • Responses si un outil l’exige. L’exemple principal est Codex CLI, qui communique avec /v1/responses ; la configuration est décrite dans la documentation de Codex CLI et dans notre guide Codex CLI.

Dans les deux cas, la liste des modèles et les prix sont identiques. Consultez la référence de l’API pour connaître tous les champs, et la page des modèles pour voir les prix en temps réel.

Responses API vs Chat CompletionsOpenAI Responses API/v1/responsesAPI Chat Completionsprevious_response_idCodex CLI Responses API

Essayez GetVibe API gratuitement

GPT, Claude, Gemini et bien plus via une seule API compatible avec OpenAI. Payez en USD par carte ou en cryptomonnaie.

Articles associés

Responses API vs Chat Completions : quelles différences et laquelle utiliser | GetVibe API