Utiliser les modèles GPT-3.5-Turbo et GPT-4

Les modèles GPT-3.5-Turbo et GPT-4 sont des modèles de langage optimisés pour les interfaces conversationnelles (chats). Les modèles se comportent différemment des anciens modèles GPT-3. Les modèles précédents étaient de type entrée de texte et sortie de texte, ce qui signifie qu’ils acceptaient une chaîne de prompt, et retournaient une complétion à ajouter au prompt. Les modèles GPT-3.5-Turbo et GPT-4 sont de type « conversation-in/message-out ». Les modèles attendent une entrée mise en forme dans un format de transcription spécifique de type conversation. Ils retournent une complétion qui représente un message écrit par le modèle dans la conversation. Ce format a été conçu spécifiquement pour les invites multitours, mais il peut également bien fonctionner dans le cadre d’autres scénarios que celui des conversations.

Cet article vous guide tout au long de la prise en main des modèles GPT-3.5-Turbo et GPT-4. Pour obtenir les meilleurs résultats possible, utilisez les techniques décrites ici. N’essayez pas d’interagir avec les modèles de la même façon qu’avec les anciennes séries de modèles, car les modèles font souvent preuve de verbosité, et fournissent des réponses moins utiles.

Utiliser les modèles GPT-3.5-Turbo et GPT-4

L’extrait de code suivant montre la façon la plus simple d’utiliser les modèles GPT-3.5-Turbo et GPT-4 avec l’API Complétion de conversation. Si vous utilisez ces modèles par programmation pour la première fois, nous vous recommandons de commencer par le Guide de démarrage rapide de GPT-3.5-Turbo et GPT-4.

Remarque

Dans la documentation d’Azure OpenAI, nous faisons référence à GPT-3.5-Turbo et GPT-35-Turbo de manière interchangeable. Le nom officiel du modèle sur OpenAI est gpt-3.5-turbo. Pour Azure OpenAI, en raison de contraintes liées aux caractères et spécifiques à Azure, le nom du modèle sous-jacent est gpt-35-turbo.

import os
from openai import AzureOpenAI

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
)

response = client.chat.completions.create(
    model="gpt-35-turbo", # model = "deployment_name".
    messages=[
        {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
        {"role": "user", "content": "Who were the founders of Microsoft?"}
    ]
)

#print(response)
print(response.model_dump_json(indent=2))
print(response.choices[0].message.content)
{
  "id": "chatcmpl-8GHoQAJ3zN2DJYqOFiVysrMQJfe1P",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.",
        "role": "assistant",
        "function_call": null
      },
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ],
  "created": 1698892410,
  "model": "gpt-35-turbo",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 73,
    "prompt_tokens": 29,
    "total_tokens": 102
  },
  "prompt_filter_results": [
    {
      "prompt_index": 0,
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ]
}
Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.

Remarque

Les paramètres suivants ne sont pas disponibles avec les nouveaux modèles GPT-35-Turbo et GPT-4 : logprobs, best_of et echo. Si vous définissez l’un de ces paramètres, une erreur se produit.

Chaque réponse inclut finish_reason. Les valeurs possibles pour finish_reason sont les suivantes :

  • stop : l’API a retourné la sortie complète du modèle.
  • length : sortie de modèle incomplète en raison du paramètre max_tokens ou de la limite relative aux jetons.
  • content_filter : contenu omis en raison d’un indicateur dans nos filtres de contenu.
  • null : réponse de l’API toujours en cours ou incomplète.

Pensez à affecter à max_tokens une valeur légèrement supérieure à la normale, par exemple 300 ou 500. Une valeur plus élevée permet de garantir que le modèle ne s’arrête pas de générer du texte avant d’avoir atteint la fin du message.

Gestion des versions des modèles

Remarque

La version gpt-35-turbo équivaut au modèle gpt-3.5-turbo d’OpenAI.

Contrairement aux modèles GPT-3 et GPT-3.5 précédents, le modèle gpt-35-turbo ainsi que les modèles gpt-4 et gpt-4-32k continuent d’être mis à jour. Quand vous créez un déploiement de ces modèles, vous devez également spécifier une version du modèle.

Vous trouverez les dates de mise hors service de ces modèles dans la page modèles.

Utiliser l’API de complétion de conversation

OpenAI a entraîné les modèles GPT-35-Turbo et GPT-4 pour qu’ils acceptent les entrées de conversation. Le paramètre messages prend un tableau d’objets de message avec une conversation organisée par rôle. Quand vous utilisez l’API Python, une liste de dictionnaires est utilisée.

Le format d’une complétion de conversation de base est le suivant :

{"role": "system", "content": "Provide some context and/or instructions to the model"},
{"role": "user", "content": "The users messages goes here"}

Une conversation avec un exemple de réponse suivie d’une question ressemblerait à ceci :

{"role": "system", "content": "Provide some context and/or instructions to the model."},
{"role": "user", "content": "Example question goes here."},
{"role": "assistant", "content": "Example answer goes here."},
{"role": "user", "content": "First question/message for the model to actually respond to."}

Rôle du système

Le rôle système, également appelé message système, est inclus au début du tableau. Ce message fournit les instructions initiales au modèle. Vous pouvez fournir diverses informations dans le rôle système, par exemple :

  • Une brève description de l’assistant.
  • Les traits de personnalité de l’assistant.
  • Les instructions ou règles à suivre par l’assistant.
  • Les données ou informations nécessaires au modèle, par exemple des questions pertinentes provenant d’un FAQ.

Vous pouvez personnaliser le rôle système en fonction de votre cas d’usage ou inclure des instructions de base. Le rôle/message système est facultatif, mais nous vous recommandons d’en inclure au moins un, même de base, pour obtenir les meilleurs résultats possible.

Messages

Après le rôle système, vous pouvez inclure une série de messages entre le user et le assistant.

 {"role": "user", "content": "What is thermodynamics?"}

Pour déclencher une réponse du modèle, finissez par un message de l’utilisateur afin d’indiquer que c’est au tour de l’assistant de répondre. Vous pouvez également inclure une série d’exemples de messages entre l’utilisateur et l’assistant pour effectuer un apprentissage en quelques essais.

Exemples d’invite de messages

La section suivante présente des exemples de différents styles de prompts que vous pouvez utiliser avec les modèles GPT-35-Turbo et GPT-4. Ces exemples ne sont qu’un point de départ. Vous pouvez faire des essais avec différents prompts pour personnaliser le comportement en fonction de vos propres cas d’usage.

Exemple de base

Si vous souhaitez que le modèle GPT-35-Turbo se comporte de manière similaire à celui de chat.openai.com, vous pouvez utiliser un message système de base tel que Assistant is a large language model trained by OpenAI.

{"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
{"role": "user", "content": "Who were the founders of Microsoft?"}

Exemple avec des instructions

Pour certains scénarios, vous pouvez être amené à donner plus d’instructions au modèle afin de définir des garde-fous permettant de déterminer ce que le modèle est capable de faire.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer their tax related questions.
Instructions: 
- Only answer questions related to taxes. 
- If you're unsure of an answer, you can say "I don't know" or "I'm not sure" and recommend users go to the IRS website for more information. "},
{"role": "user", "content": "When are my taxes due?"}

Utiliser des données de fondement

Vous pouvez également inclure des données ou des informations pertinentes dans le message système afin de donner au modèle un contexte supplémentaire pour la conversation. Si vous devez inclure uniquement une petite quantité d’informations, vous pouvez les coder en dur dans le message système. Si vous disposez d’une grande quantité de données dont le modèle doit avoir connaissance, vous pouvez utiliser des incorporations ou un produit comme Recherche Azure AI pour récupérer les informations les plus pertinentes au moment de la requête.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI Serivce. Only answer questions using the context below and if you're not sure of an answer, you can say 'I don't know'.

Context:
- Azure OpenAI Service provides REST API access to OpenAI's powerful language models including the GPT-3, Codex and Embeddings model series.
- Azure OpenAI Service gives customers advanced language AI with OpenAI GPT-3, Codex, and DALL-E models with the security and enterprise promise of Azure. Azure OpenAI co-develops the APIs with OpenAI, ensuring compatibility and a smooth transition from one to the other.
- At Microsoft, we're committed to the advancement of AI driven by principles that put people first. Microsoft has made significant investments to help guard against abuse and unintended harm, which includes requiring applicants to show well-defined use cases, incorporating Microsoft’s principles for responsible AI use."
},
{"role": "user", "content": "What is Azure OpenAI Service?"}

Apprentissage en quelques essais avec la complétion de conversation

Vous pouvez également fournir quelques exemples rapides au modèle. L’approche de l’apprentissage en quelques essais a légèrement changé en raison du nouveau format de prompt. Vous pouvez désormais inclure une série de messages entre l’utilisateur et l’assistant dans le prompt sous la forme d’un petit nombre d’exemples. Vous pouvez utiliser ces exemples pour fournir des réponses aux questions courantes afin de préparer le modèle, ou de lui enseigner des comportements particuliers.

Cet exemple montre comment utiliser l’apprentissage en quelques essais avec GPT-35-Turbo et GPT-4. Vous pouvez expérimenter différentes approches afin de déterminer celle qui convient le mieux à votre cas d’usage.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer their tax related questions. "},
{"role": "user", "content": "When do I need to file my taxes by?"},
{"role": "assistant", "content": "In 2023, you will need to file your taxes by April 18th. The date falls after the usual April 15th deadline because April 15th falls on a Saturday in 2023. For more details, see https://www.irs.gov/filing/individuals/when-to-file."},
{"role": "user", "content": "How can I check the status of my tax refund?"},
{"role": "assistant", "content": "You can check the status of your tax refund by visiting https://www.irs.gov/refunds"}

Utiliser la complétion de conversation pour les scénarios non basés sur une conversation

L’API de complétion de conversation est conçue pour être utilisée avec des invites multitours, mais elle fonctionne tout aussi bien dans les scénarios non basés sur une conversation.

Par exemple, pour un scénario d’extraction d’entités, vous pouvez utiliser cette prompt :

{"role": "system", "content": "You are an assistant designed to extract entities from text. Users will paste in a string of text and you will respond with entities you've extracted from the text as a JSON object. Here's an example of your output format:
{
   "name": "",
   "company": "",
   "phone_number": ""
}"},
{"role": "user", "content": "Hello. My name is Robert Smith. I'm calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?"}

Créer une boucle de conversation de base

Les exemples présentés jusqu’à maintenant montrent les mécanismes de base de l’interaction avec l’API de complétion de conversation. Cet exemple vous montre comment créer une boucle de conversation qui effectue les actions suivantes :

  • Accepte en continu l’entrée de la console, et la met en forme correctement dans le cadre de la liste des messages en tant que contenu de rôle utilisateur.
  • Génère des réponses qui sont imprimées dans la console et mises en forme et ajoutées à la liste de messages en tant que contenu de rôle d’assistant.

Chaque fois qu’une nouvelle question est posée, une transcription en continu de la conversation est envoyée avec la dernière question. Dans la mesure où le modèle n’a pas de mémoire, vous devez envoyer une transcription mise à jour avec chaque nouvelle question, sinon le modèle perd le contexte des questions et réponses précédentes.

import os
from openai import AzureOpenAI

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")  # Your Azure OpenAI resource's endpoint value.
)

conversation=[{"role": "system", "content": "You are a helpful assistant."}]

while True:
    user_input = input("Q:")      
    conversation.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="gpt-35-turbo", # model = "deployment_name".
        messages=conversation
    )

    conversation.append({"role": "assistant", "content": response.choices[0].message.content})
    print("\n" + response.choices[0].message.content + "\n")

Quand vous exécutez le code précédent, vous obtenez une fenêtre de console vide. Entrez votre première question dans la fenêtre, puis sélectionnez la touche Enter. Une fois la réponse retournée, vous pouvez répéter le processus, et continuer à poser des questions.

Gérer les conversations

L’exemple précédent s’exécute jusqu’à ce que vous atteigniez la limite de jetons du modèle. À chaque question posée et à chaque réponse reçue, la taille de la liste messages augmente. La limite de jetons pour gpt-35-turbo est de 4 096 jetons. Les limites de jetons pour gpt-4 et gpt-4-32k sont respectivement de 8 192 et 32 768. Ces limites incluent le nombre de jetons de la liste de messages envoyé et de la réponse du modèle. Le nombre de jetons dans la liste de messages combiné à la valeur du paramètre max_tokens doit rester inférieur à ces limites, sinon une erreur se produit.

Il vous appartient de vérifier que le prompt et la complétion ne dépassent pas la limite de jetons. Pour les conversations plus longues, vous devez effectuer le suivi du nombre de jetons, et envoyer uniquement au modèle un prompt compris dans la limite.

Remarque

Nous vous recommandons vivement de respecter la limite de jetons d’entrée documentée pour tous les modèles, même si vous découvrez que vous pouvez dépasser cette limite.

L’exemple de code suivant montre un exemple simple de boucle de conversation avec une technique permettant de gérer 4 096 jetons à l’aide de la bibliothèque tiktoken d’OpenAI.

Le code utilise tiktoken 0.5.1. Si vous disposez d’une ancienne version, exécutez pip install tiktoken --upgrade.

import tiktoken
import os
from openai import AzureOpenAI

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")  # Your Azure OpenAI resource's endpoint value.
)

system_message = {"role": "system", "content": "You are a helpful assistant."}
max_response_tokens = 250
token_limit = 4096
conversation = []
conversation.append(system_message)

def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
    """Return the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        print("Warning: model not found. Using cl100k_base encoding.")
        encoding = tiktoken.get_encoding("cl100k_base")
    if model in {
        "gpt-3.5-turbo-0613",
        "gpt-3.5-turbo-16k-0613",
        "gpt-4-0314",
        "gpt-4-32k-0314",
        "gpt-4-0613",
        "gpt-4-32k-0613",
        }:
        tokens_per_message = 3
        tokens_per_name = 1
    elif model == "gpt-3.5-turbo-0301":
        tokens_per_message = 4  # every message follows <|start|>{role/name}\n{content}<|end|>\n
        tokens_per_name = -1  # if there's a name, the role is omitted
    elif "gpt-3.5-turbo" in model:
        print("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.")
        return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613")
    elif "gpt-4" in model:
        print("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.")
        return num_tokens_from_messages(messages, model="gpt-4-0613")
    else:
        raise NotImplementedError(
            f"""num_tokens_from_messages() is not implemented for model {model}."""
        )
    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3  # every reply is primed with <|start|>assistant<|message|>
    return num_tokens
while True:
    user_input = input("Q:")      
    conversation.append({"role": "user", "content": user_input})
    conv_history_tokens = num_tokens_from_messages(conversation)

    while conv_history_tokens + max_response_tokens >= token_limit:
        del conversation[1] 
        conv_history_tokens = num_tokens_from_messages(conversation)

    response = client.chat.completions.create(
        model="gpt-35-turbo", # model = "deployment_name".
        messages=conversation,
        temperature=0.7,
        max_tokens=max_response_tokens
    )


    conversation.append({"role": "assistant", "content": response.choices[0].message.content})
    print("\n" + response.choices[0].message.content + "\n")

Dans cet exemple, une fois le nombre de jetons atteint, les messages les plus anciens de la transcription de conversation sont supprimés. Par souci d’efficacité, del est utilisé à la place de pop(). Nous commençons à l’index 1 pour conserver en permanence le message système, et supprimer uniquement les messages de l’utilisateur ou de l’assistant. Au fil du temps, cette méthode de gestion de la conversation peut entraîner une détérioration de la qualité de la conversation, car le modèle perd progressivement le contexte des parties précédentes de la conversation.

Une autre approche consiste à limiter la durée de la conversation en fonction de la limite maximale de jetons ou d’un nombre spécifique de tours. Une fois la limite maximale de jetons atteinte, le modèle perd le contexte si vous permettez à la conversation de se poursuivre. Vous pouvez demander à l’utilisateur d’entamer une nouvelle conversation, et d’effacer la liste des messages pour démarrer une nouvelle conversation avec la totalité des jetons disponibles.

La partie de comptage de jetons du code présentée précédemment est une version simplifiée de l’un des exemples de livres de recettes d’OpenAI.

Dépannage

Voici un conseil de résolution des problèmes.

N’utilisez pas la syntaxe ChatML ou des jetons spéciaux avec le point de terminaison de saisie semi-automatique des conversations instantanées

Certains clients tentent d’utiliser la syntaxe ChatML héritée avec les points de terminaison de complétion de conversation et les derniers modèles. ChatML était une fonctionnalité en préversion qui fonctionnait uniquement avec le point de terminaison de complétion hérité et le modèle gpt-35-turbo version 0301. Ce modèle est destiné à être mis hors service. Si vous tentez d’utiliser la syntaxe de ChatML avec les derniers modèles et le point de terminaison de complétion de conversation, cela peut entraîner des erreurs et un comportement inattendu de la réponse du modèle. Nous ne recommandons pas cette utilisation. Le même problème peut se produire lorsque vous utilisez des jetons spéciaux courants.

Code d’erreur Message d’erreur Solution
400 400 - « Échec de la génération de la sortie en raison de jetons spéciaux dans l’entrée. » Votre invite contient des jetons spéciaux ou des jetons ChatML hérités non reconnus ou non pris en charge par le modèle/point de terminaison. Vérifiez que votre tableau de messages/invites ne contient aucun jeton ChatML hérité/jeton spécial. Si vous effectuez une mise à niveau à partir d’un modèle hérité, excluez tous les jetons spéciaux avant d’envoyer une requête d’API au modèle.

Désolé... Nous n’avons pas pu créer la saisie semi-automatique, car le modèle a généré une sortie Unicode non valide

Code d’erreur Message d’erreur Solution de contournement
500 500 – InternalServerError : code d’erreur : 500 – {'error': {'message': 'Échec de création de la saisie semi-automatique, car le modèle a généré une sortie Unicode non valide}}. Vous pouvez diminuer l’apparition de ces erreurs en réduisant la température de vos invites pour se situer à moins de 1 et en veillant à utiliser un client avec une logique de nouvelle tentative. Une nouvelle tentative de la requête aboutit souvent à une réponse correcte.

Étapes suivantes