# Parameters
BATCH_MODE = "true"1. Introduction a l’IA generative avec l’API OpenAI
1. Introduction a l’IA generative avec l’API OpenAI
Navigation : Index | Suivant >>
Objectifs d’apprentissage
A la fin de ce notebook, vous saurez : 1. Comprendre les fondamentaux de l’IA generative et des LLMs 2. Configurer et utiliser l’API OpenAI avec Python 3. Maitriser les concepts de tokenisation et de contexte 4. Identifier et gerer les hallucinations des modèles
Prerequis
- Python 3.10+
- Cle API OpenAI configuree (fichier
.env) - Connaissance de base de Python
Duree estimee : 50 minutes
Plan global du Notebook
- Introduction Générale
- Contexte et définitions (IA Générative, LLMs, prompts, etc.)
- Présentation succincte des enjeux éthiques et de responsabilité
- Premier Exemple de Code : Vérification de l’Environnement
- Installation et importation des bibliothèques (OpenAI ou Azure OpenAI)
- Test d’un prompt de base
- Notions de Base sur les Prompts
- Tokens, embeddings, bases de la génération
- Exercices pratiques : tokenisation et génération
- Exemple : Fabrications (Hallucinations) et Fiabilité
- Démonstration via un prompt volontairement ambigu
- Discussion sur la vérification des faits
- Conclusion
- Récapitulatif des points abordés
- Proposition d’activité (rédaction d’une synthèse ou d’une extension)
Introduction à l’IA Générative
Dans ce notebook, nous explorerons les fondamentaux de l’Intelligence Artificielle Générative :
Objectifs : - Comprendre ce qu’est l’IA Générative (texte, images, audio…) - Découvrir le fonctionnement des modèles de langage de grande taille (LLMs) - Mettre en pratique des expérimentations simples avec les prompts - Aborder les questions de fiabilité (hallucinations) et d’éthique
Qu’est-ce que l’IA Générative ?
L’IA générative est une branche de l’apprentissage automatique qui génère de nouveaux contenus (texte, image, audio, code…) à partir de modèles probabilistes entraînés sur de vastes ensembles de données. Les modèles les plus avancés, appelés Large Language Models (LLMs), utilisent des architectures de type Transformer pour prédire et générer des séquences (architecture introduite par Vaswani et al., 2017, « Attention Is All You Need », arXiv:1706.03762).
Exemples concrets : - ChatGPT (OpenAI) : génération et compréhension de texte - Stable Diffusion : génération d’images - Audiocraft et Whisper : génération et transcription audio - Copilot (GitHub) : génération de code et assistance à la programmation
Enjeux et Limites
- Hallucinations / Fabrications : Le modèle peut générer des réponses inventées ou inexactes, même si elles semblent plausibles.
- Biais : Les réponses peuvent refléter des biais présents dans les données d’entraînement.
- Coût Énergétique : L’entraînement de grands modèles consomme beaucoup de ressources.
- Régulation et Éthique : Confidentialité, respect des lois et usage responsable de la technologie.
Nous allons maintenant configurer l’environnement et réaliser un premier test de prompt.
# ==========================================
# Cellule 2 : Installation et Configuration
# ==========================================
# Installation des packages necessaires (a lancer uniquement si non deja installes)
from pathlib import Path
try:
import openai, tiktoken, dotenv # noqa: F401
_deps_ok = True
except ImportError:
_deps_ok = False
if not _deps_ok:
# equivalent du magic %pip (qu'on ne peut pas indenter : ligne magique non-Python)
import subprocess, sys
subprocess.run([sys.executable, "-m", "pip", "install", "-q",
"openai", "tiktoken", "python-dotenv"], check=False)
else:
print("Dependances deja installees (openai, tiktoken, python-dotenv) -- pip skip")
import os
from openai import OpenAI
from dotenv import load_dotenv
# Chargement robuste de la configuration .env
# Recherche du .env dans tous les parents (pour Papermill qui change le cwd)
current_path = Path.cwd()
env_loaded = False
for _ in range(10):
env_path = current_path / ".env"
if env_path.exists():
load_dotenv(env_path)
print(f".env charge depuis: {env_path.name}")
env_loaded = True
break
if current_path.name == "GenAI" or len(current_path.parts) <= 1:
break
current_path = current_path.parent
if not env_loaded:
print("WARNING: .env non trouve, utilisation variables environnement")
# Initialiser le client OpenAI (detecte automatiquement OPENAI_API_KEY)
client = OpenAI()
# Charger le modele depuis .env ou utiliser gpt-5-mini par defaut
DEFAULT_MODEL = os.getenv("OPENAI_MODEL", "gpt-5-mini")
# BATCH_MODE : la cellule Parameters (cellule 1) porte la valeur injectable par
# Papermill (-p BATCH_MODE true) ; la variable d'environnement n'est qu'un repli.
_bm_env = os.getenv("BATCH_MODE")
BATCH_MODE = (_bm_env if _bm_env is not None else str(BATCH_MODE)).lower() == "true"
print("Client OpenAI initialise avec succes (syntaxe moderne) !")
print(f"Modele par defaut: {DEFAULT_MODEL}")
print(f"BATCH_MODE: {BATCH_MODE}")Dependances deja installees (openai, tiktoken, python-dotenv) -- pip skip
.env charge depuis: .env
Client OpenAI initialise avec succes (syntaxe moderne) !
Modele par defaut: gpt-5-mini
BATCH_MODE: True
Validation de l’installation
L’exécution de la cellule ci-dessus confirme que l’environnement est correctement configuré :
Vérifications effectuées : 1. Packages installés : openai, tiktoken, python-dotenv 2. Configuration chargée : Le fichier .env a été lu avec succès 3. Client configuré : client = OpenAI() s’est construit sans erreur — la clé a été chargée depuis .env, mais sa validité n’est confirmée que par un premier appel API (cellule suivante). Construire le client ne prouve pas que la clé fonctionne.
Fichiers de configuration :
| Fichier | Rôle | Emplacement |
|---|---|---|
.env |
Stocke OPENAI_API_KEY (secret) |
MyIA.AI.Notebooks/GenAI/.env |
.env.example |
Template sans secrets | Même répertoire (versionné Git) |
Important : - Le fichier .env ne doit jamais être commité dans Git (vérifié via .gitignore) - La clé API est chargée automatiquement par OpenAI() via la variable d’environnement
Prochaine étape : Tester un premier appel API pour valider la connexion au service — c’est cet appel, et non la construction du client, qui confirme la clé.
Qu’est-ce qu’un prompt ?
Dans le contexte des LLMs (Large Language Models), un prompt est la consigne initiale que l’on fournit au modèle. Il peut s’agir d’une question, d’une instruction, d’un texte partiel, voire d’un exemple de conversation. Le prompt influe directement sur la qualité de la réponse générée.
Chat Completions vs. Completions
OpenAI propose principalement deux approches pour générer du texte :
- Completions API (versions historiques)
- On envoie un simple prompt (ex.:
text-davinci-003) et on récupère un texte.
- Peu pratique pour les dialogues complexes, car il faut manuellement gérer l’historique de la conversation.
- On envoie un simple prompt (ex.:
- Chat Completions API (recommandée)
- On structure le prompt en plusieurs messages avec des rôles (
system,user,assistant, etc.).
- Permet des conversations plus riches (mémoire de conversation, enchaînements de tours) et un meilleur contrôle du style.
- On structure le prompt en plusieurs messages avec des rôles (
Dans ce notebook, nous utilisons principalement la Chat Completions API via client.chat.completions.create() (syntaxe moderne). En savoir plus dans la documentation officielle.
Premier prompt
La list des paramètres est accessible dans le documentation officielle.
# ============================
# Cellule 3 : Premier Prompt
# ============================
# Exemple simple : Generation d'une courte phrase a partir d'un prompt de base
# Utilisation de l'API Chat avec le modele configure dans DEFAULT_MODEL
response = client.chat.completions.create(
messages=[
{
"role": "user",
"content": "Allons enfants de la Patrie, "
}
],
model=DEFAULT_MODEL
)
print("Reponse du modele :")
print(response.choices[0].message.content)Reponse du modele :
Souhaitez-vous que je continue les paroles de "La Marseillaise", que je les traduise en anglais, que je vous raconte l'histoire de l'hymne, ou autre chose ?
Interprétation du résultat
Le prompt « Allons enfants de la Patrie, » est le premier vers de La Marseillaise, l’hymne national français. Le modèle reconnaît la référence, mais ce qu’il en fait varie d’une exécution à l’autre. Lors d’une exécution précédente de ce carnet, il avait chanté le premier couplet et le refrain, puis proposé la suite, une traduction ou l’histoire de l’hymne. À cette exécution, il ne continue rien et demande directement ce que l’on attend de lui (voir la sortie ci-dessus). Trois points à retenir :
Mémoire culturelle : dans les deux cas, le modèle identifie l’hymne sans qu’on le lui nomme. Il a été entraîné sur de vastes corpus de textes et reconnaît les références culturelles célèbres.
Un modèle de chat n’est pas un modèle de complétion :
gpt-5-miniest entraîné à répondre à une demande. Un début de phrase sans consigne est une demande ambiguë, que le modèle peut compléter ou faire préciser. Les modèles de complétion (l’APIcompletions, antérieure à l’API Chat) prolongent le texte par construction : ils prédisent la suite du prompt.Non-déterminisme : sans consigne ni paramètre de contrôle, deux appels identiques peuvent produire des comportements différents, pas seulement des formulations différentes. Pour obtenir une continuation, il faut la demander explicitement (« Continue les paroles : … »).
Paramètres utilisés : - model="gpt-5-mini" : Version économique et rapide du modèle GPT-5 - Pas de limitation de tokens : Le modèle génère jusqu’à ce qu’il considère la réponse complète
Analyse de l’impact du message ‘system’
Cette cellule illustre l’importance du rôle ‘system’ dans les conversations avec les LLMs :
Rôle des messages : - system : Définit le comportement global et le style du modèle (instructions méta) - user : Les questions ou demandes de l’utilisateur - assistant : Les réponses précédentes du modèle (dans un contexte conversationnel)
Dans cet exemple, le message system « Tu es un assistant poétique qui répond toujours en haiku » transforme complètement la nature de la réponse. Au lieu d’une réponse explicative classique, le modèle produit un poème court de 3 vers (5-7-5 syllabes).
Applications pratiques : - Chatbots avec personnalité spécifique (formel, humoristique, technique…) - Assistants spécialisés (code, marketing, éducation…) - Contrôle du ton et du format de sortie
Note : temperature=0.7 permet une certaine créativité tout en restant cohérent.
# ============================
# Cellule 4 : Prompt avec un message 'system'
# ============================
# Ici, on utilise un message "system" pour donner une consigne globale sur le style du modele.
# Le message "user" reste notre question.
messages = [
{
"role": "system",
"content": "Tu es un assistant poetique qui repond toujours en haiku. "
},
{
"role": "user",
"content": "Que penses-tu de la tour Eiffel ?"
},
{
"role": "assistant",
"content": "Fleur de fer dressee\nParis tisse son ciel d'acier\nEtreint les nuages doux"
},
{
"role": "user",
"content": "Que penses-tu de ton poeme ?"
}
]
response_system = client.chat.completions.create(
messages=messages,
model=DEFAULT_MODEL
)
print("=== Reponse avec un message 'system' ===")
print(response_system.choices[0].message.content)=== Reponse avec un message 'system' ===
Souffle de papier
Écho doux qui passe et reste
Sourit puis se tait
Interprétation de la réponse avec message system
L’exécution démontre l’impact concret du message system sur le comportement du modèle :
Analyse de la conversation : 1. Message system : “Tu es un assistant poétique qui répond toujours en haiku” 2. Haiku fourni : Le poème sur la tour Eiffel (“Fleur de fer dressee…”) n’est pas une sortie de cet appel : il a été injecté comme message assistant dans l’historique fourni. C’est un exemple d’historique (comment on fabrique un contexte), pas une production du modèle interrogé. 3. Réponse du modèle : À la dernière question (“Que penses-tu de ton poème ?”), le modèle maintient la contrainte haiku et produit son propre poème (voir la sortie réelle de la cellule ci-dessus).
Capacités observées (sur la sortie réellement obtenue) : - Mémoire de rôle : Le modèle conserve le rôle “poétique” sur plusieurs tours - Contrainte de forme : La réponse réellement obtenue poursuit en vers courts, en cohérence avec la consigne “répond toujours en haiku” (aucun comptage syllabique n’est effectué ici) - Cohérence conversationnelle : Le modèle répond à la dernière question utilisateur en tenant compte du contexte fourni (messages system et assistant injectés)
Leçon : Un texte placé en role: assistant est un exemple d’historique, pas une production du modèle interrogé — distinguer les deux est essentiel pour lire une conversation API.
Applications pratiques :
| Type d’assistant | Message system exemple |
|---|---|
| Support technique | “Tu es un expert en cybersécurité qui répond de manière claire et pédagogique” |
| Marketing | “Tu es un copywriter créatif spécialisé en publicité pour les startups tech” |
| Éducation | “Tu es un professeur patient qui adapte ses explications au niveau de l’étudiant” |
Astuce : Combiner message system avec temperature pour contrôler créativité ET personnalité.
Exemple guidé : Composer un system prompt pour un assistant spécialisé
Contribution étudiante d’Alexandre HUYNH (@neyhala), Marko JOVANOVIC et Nathan KLIEBER, PR #18559, intégrée comme exemple guidé.
Le message system contrôle le comportement du modèle. L’exemple précédent lui imposait un style poétique ; celui-ci lui impose le cahier des charges d’un assistant de révision technique, en quatre consignes : 1. répondre en français ; 2. structurer la réponse en liste à puces ; 3. ne pas dépasser 5 puces ; 4. citer une source ou un exemple concret dans chaque puce.
Trois choix du code portent l’exemple : - les consignes sont numérotées et présentées comme des « règles strictes », et une dernière phrase interdit l’introduction et la conclusion ; - reasoning_effort="minimal" : gpt-5-mini est un modèle de raisonnement, et ses jetons de réflexion sont décomptés du même budget max_completion_tokens. Avec 300 jetons et l’effort par défaut, le raisonnement peut épuiser le budget et la réponse revient vide (finish_reason="length"). L’effort minimal laisse le budget à la réponse visible ; - max_completion_tokens=1000 : l’énoncé d’origine proposait 300, et le groupe l’avait gardé. À l’intégration, deux exécutions successives du même code ont donné l’une une réponse de 277 jetons, l’autre une réponse vide : quand la réponse dépasse le budget, gpt-5-mini ne la tronque pas, il ne renvoie rien, et l’API compte les 300 jetons comme du raisonnement. Le budget est un plafond de sécurité ; la concision, c’est le message system qui la porte ; - la réponse est vérifiée par le code, pas seulement lue : le nombre de puces est compté, et le code affiche finish_reason et la consommation de jetons.
La cellule suivante pose la même question sans message system, pour voir ce que les consignes changent : une première fois avec le même budget de 300 jetons, puis avec 2000 jetons pour mesurer la longueur d’une réponse que rien ne borne.
# Exemple guide : Composer un system prompt pour un assistant specialise
# Contribution etudiante de @neyhala, M. Jovanovic et N. Klieber (PR #18559)
# Etape 1 : Definir le message system avec les contraintes
system_prompt = (
"Tu es un assistant de revision technique qui aide les etudiants a reviser. "
"Regles strictes :\n"
"1. Reponds toujours en francais.\n"
"2. Structure toujours ta reponse sous forme de liste a puces.\n"
"3. Ne depasse jamais 5 puces au total.\n"
"4. Chaque puce doit citer une source (bibliotheque, documentation officielle, "
"outil reconnu) ou un exemple concret.\n"
"Sois concis : une ou deux phrases par puce, sans introduction ni conclusion."
)
# Etape 2 : Definir la question de test
test_question = "Explique-moi les avantages de Python pour la data science"
# Etape 3 : Appeler le modele avec le system prompt
# gpt-5-mini est un modele "reasoning" : max_completion_tokens compte AUSSI les tokens
# de raisonnement caches. Avec 300 tokens et l'effort par defaut, le modele peut tout
# consommer en raisonnement et renvoyer une reponse VIDE (finish_reason="length").
# reasoning_effort="minimal" laisse le budget a la reponse visible.
response_ex1 = client.chat.completions.create(
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": test_question},
],
model=DEFAULT_MODEL,
# Integration : 1000 au lieu de 300. Une reponse de 5 puces sourcees fait 200 a 300 jetons,
# et quand elle depasse le budget, gpt-5-mini ne la tronque pas : il ne renvoie rien.
# Le budget est un plafond de securite ; la concision, c'est le message system qui la porte.
max_completion_tokens=1000,
reasoning_effort="minimal",
)
# Etape 4 : Afficher la reponse et verifier le respect des contraintes
reponse = response_ex1.choices[0].message.content or ""
print("Reponse de l'assistant technique :")
print(reponse)
print("\n=== Verification des contraintes ===")
puces = [l for l in reponse.splitlines() if l.strip().startswith(("-", "*", "•"))]
print(f"Nombre de puces : {len(puces)} (max 5) -> {'OK' if 0 < len(puces) <= 5 else 'NON RESPECTE'}")
print(f"finish_reason : {response_ex1.choices[0].finish_reason}")
usage = response_ex1.usage
details = getattr(usage, "completion_tokens_details", None)
print(f"Tokens de sortie : {usage.completion_tokens} "
f"(dont raisonnement : {getattr(details, 'reasoning_tokens', 'n/a')})")Reponse de l'assistant technique :
- Bibliothèque NumPy — gestion efficace des tableaux et calculs vectorisés, réduisant le temps de développement et d'exécution pour le prétraitement des données (ex. utilisation de ndarray pour opérations matricielles).
- Bibliothèque pandas — structures DataFrame/Series facilitant nettoyage, manipulation et exploration des données tabulaires (ex. groupby, merge, pivot_table pour analyses rapides).
- Bibliothèque scikit-learn — large collection d'algorithmes d'apprentissage supervisé et non supervisé avec API cohérente pour prototypage et validation (ex. Pipeline, GridSearchCV pour tuning et réutilisabilité).
- Ecosystème scientifique (Matplotlib, Seaborn, Plotly) — visualisations statiques et interactives pour exploration et communication des résultats (ex. heatmap Seaborn pour matrice de corrélation).
- Intégration et déploiement (Jupyter, TensorFlow/PyTorch, API Flask/FastAPI) — notebooks pour itération interactive et frameworks pour modélisation et mise en production de modèles ML (ex. notebook Jupyter pour prototype puis FastAPI pour servir un modèle).
=== Verification des contraintes ===
Nombre de puces : 5 (max 5) -> OK
finish_reason : stop
Tokens de sortie : 249 (dont raisonnement : 0)
# Exemple guide (suite) : la meme question, sans message system
# Contribution etudiante (PR #18559)
sans = client.chat.completions.create(
messages=[{"role": "user", "content": test_question}],
model=DEFAULT_MODEL,
max_completion_tokens=300,
reasoning_effort="minimal",
)
print(sans.choices[0].message.content)
print("finish_reason :", sans.choices[0].finish_reason)
print("Tokens de sortie :", sans.usage.completion_tokens,
"(dont raisonnement :", sans.usage.completion_tokens_details.reasoning_tokens, ")")
# Ajout a l'integration : la meme question avec un budget large, pour mesurer
# la longueur d'une reponse qu'aucune consigne ne borne
sans_large = client.chat.completions.create(
messages=[{"role": "user", "content": test_question}],
model=DEFAULT_MODEL,
max_completion_tokens=2000,
reasoning_effort="minimal",
)
texte_large = sans_large.choices[0].message.content or ""
print("\n=== Meme question, budget de 2000 jetons ===")
print(texte_large[:500], "[...]")
print("finish_reason :", sans_large.choices[0].finish_reason)
print("Tokens de sortie :", sans_large.usage.completion_tokens, "| caracteres :", len(texte_large))
finish_reason : length
Tokens de sortie : 300 (dont raisonnement : 300 )
=== Meme question, budget de 2000 jetons ===
Voici les principaux avantages de Python pour la data science, expliqués de manière claire et pratique :
1. Syntaxe simple et lisible
- Courbe d'apprentissage douce : facile à apprendre pour des débutants en programmation.
- Code court et lisible : permet de prototyper et maintenir des pipelines d’analyse plus rapidement.
2. Écosystème riche de bibliothèques spécialisées
- NumPy : opérations numériques rapides sur tableaux (vecteurs/matrices).
- pandas : manipulation et nettoyage de données (D [...]
finish_reason : stop
Tokens de sortie : 766 | caracteres : 3371
Lecture du résultat — exemple guidé (system prompt)
- Les consignes vérifiables par le code tiennent : 5 puces exactement (la vérification automatique affiche
OK), sans introduction ni conclusion, avecfinish_reason : stop. Chaque puce suit en outre un gabarit que la consigne n’imposait pas : un nom de bibliothèque, un tiret long, une description, puis un exemple entre parenthèses (ex. groupby, merge, pivot_table). - Deux consignes ne se vérifient qu’à la lecture : le français, respecté, et la source par puce. À cette exécution, le modèle satisfait la consigne 4 par des exemples concrets ; lors d’une exécution précédente du même code, il citait des URL de documentation. La consigne laissait le choix (« une source ou un exemple »), et le modèle ne fait pas le même choix d’un appel à l’autre. Le compteur de puces ne voit rien de tout cela : un vérificateur automatique ne couvre que ce qu’on lui a appris à compter.
- Sans message
system, la réponse est trois fois plus longue : 766 jetons et 3 371 caractères, organisés en sections numérotées qui contiennent chacune plusieurs puces, contre 249 jetons avec le messagesystem. Celui-ci ne règle donc pas seulement le style : il divise ici par trois le coût de la réponse. - Le piège du budget : avec 300 jetons, l’appel sans message
systemne renvoie rien. L’affichage est vide,finish_reasonvautlength, et l’API compte les 300 jetons comme du raisonnement alors quereasoning_effort="minimal". Quand la réponse ne tient pas dans le budget,gpt-5-minine la tronque pas, il la perd. Le groupe, qui exécutait le carnet avec un autre modèle, obtenait au contraire une réponse coupée au milieu d’un mot. Le même paramètre n’a pas le même effet selon le modèle : vérifierfinish_reasonà chaque appel est le seul moyen de savoir si la réponse affichée est complète.
Exercice 1 : Le system prompt face à un utilisateur qui le contredit
L’exemple guidé vérifie les consignes du message system sur une question coopérative. Un assistant déployé reçoit aussi des messages qui demandent le contraire : une réponse en anglais, un paragraphe rédigé, dix points au lieu de cinq. Quand les messages system et user se contredisent, lequel l’emporte, et pour quelle consigne ?
Objectif : mesurer, consigne par consigne, ce qui résiste quand l’utilisateur demande l’inverse.
Étapes : 1. Réutiliser system_prompt de l’exemple guidé, sans le modifier. 2. Écrire verifier(reponse), qui renvoie trois booléens : puces (toutes les lignes non vides sont des puces), max_5 (au plus 5 puces) et francais (la réponse est en français). 3. Envoyer chacun des trois messages de messages_contradictoires N_ESSAIS = 3 fois, avec le même system_prompt. 4. Afficher un tableau : une ligne par message, une colonne par consigne, et dans chaque case le nombre de réponses conformes sur 3.
Indices : - Le comptage des puces de l’exemple guidé se réutilise tel quel ; une ligne numérotée (1.) n’est pas une puce. - Pour la langue, compter quelques mots-outils (le, les, est, contre the, is, and) suffit. L’heuristique est approximative : relire au moins une réponse à la main pour la valider. - Garder max_completion_tokens=1000 et reasoning_effort="minimal", comme dans l’exemple guidé. Une réponse qui dépasse le budget revient vide (finish_reason égal à "length") : ce n’est ni un respect ni une violation des consignes, c’est une mesure perdue, à compter à part.
Critère de réussite : le tableau 3 messages × 3 consignes, et une phrase qui dit quelle consigne cède la première, avec une hypothèse sur la raison.
# Exercice 1 : Le system prompt face a un utilisateur qui le contredit
# TODO etudiant : mesurer, consigne par consigne, ce qui resiste quand le message user demande l'inverse
messages_contradictoires = {
"anglais": "Answer in English: what are the advantages of Python for data science?",
"paragraphe": "Reponds en un seul paragraphe redige, sans aucune liste : quels sont les avantages de Python pour la data science ?",
"dix_points": "Donne-moi 10 avantages de Python pour la data science, numerotes de 1 a 10.",
}
def verifier(reponse):
"""Renvoie {"puces": bool, "max_5": bool, "francais": bool} pour une reponse."""
# Etape 1 : garder les lignes non vides ; une puce commence par "-", "*" ou "•"
# Etape 2 : "puces" est vrai si toutes les lignes non vides sont des puces
# Etape 3 : "max_5" est vrai s'il y a au plus 5 puces
# Etape 4 : "francais" par comptage de mots-outils francais contre anglais
return None # TODO etudiant
N_ESSAIS = 3
resultats = {} # TODO etudiant : {nom_du_message: {consigne: nombre de reponses conformes sur N_ESSAIS}}
# Etape 5 : pour chaque message, N_ESSAIS appels avec system_prompt, puis verifier(reponse)
# Etape 6 : afficher le tableau message x consigne, et les finish_reason "length"
print("Exercice a completer")Exercice a completer
Analyse comparative de la tokenisation
Les résultats ci-dessus révèlent des différences importantes entre les tokenizers :
Observations clés : 1. Nombre de tokens différent : La même phrase peut être découpée en un nombre différent de tokens selon le modèle 2. Granularité variable : Certains tokenizers créent des tokens plus fins (ex: espaces séparés), d’autres plus larges 3. Traitement des espaces : Notez comment les espaces sont parfois inclus dans les tokens, parfois séparés
Implications pratiques : - Facturation : Chaque appel API est facturé selon le nombre de tokens (input + output) - Limites de contexte : Chaque modèle a une fenêtre maximale (ex: 8k, 32k, 128k tokens) - Optimisation : Pour un même texte, le coût peut varier selon le modèle choisi
Exemple concret : Sur la même phrase, text-davinci-003 et gpt-5-mini peuvent produire un nombre identique de tokens (cf. la sortie ci-dessous : 5 tokens chacun) mais avec des indices de vocabulaire différents ([5812, 910, 460, 345, 766] vs [18009, 2891, 665, 481, 1921]) : chaque modèle possède son propre vocabulaire BPE. Sur des textes plus longs ou multilingues, le compte peut diverger (cf. Exercice 2).
Recommandation : Toujours vérifier la tokenisation avant d’envoyer de longs documents pour estimer le coût réel.
Notions de Base : Tokenisation
Lorsque nous envoyons un prompt à un LLM, le texte est converti en une séquence de tokens.
- Un token est généralement un morceau de mot, un caractère spécial ou un sous-mot.
- Chaque modèle possède sa propre manière de découper le texte, influençant le nombre total de tokens.
Pourquoi c’est important ?
- La facturation (ou la limitation) se base souvent sur le nombre total de tokens (entrée + sortie).
- Une requête trop longue peut dépasser la context window du modèle (limite de tokens cumulés).
Bonnes pratiques
- Surveiller la longueur du prompt pour limiter le coût et éviter les dépassements.
- Utiliser des fonctions d’analyse (ex.tiktoken) pour estimer le nombre de tokens d’un texte avant l’envoi.
- Tester divers modèles (text-davinci-003,gpt-4,gpt-5-mini, etc.) car la tokenisation et le coût peuvent varier.
Dans la bibliothèque tiktoken d’OpenAI, on peut directement encoder et décoder les tokens pour comprendre la segmentation.
Ci-dessous, un exemple détaillé de la façon dont la phrase « Oh say can you see » est découpée différemment selon le modèle.
# ============================
# Cellule 5 : Analyse de la Tokenisation
# ============================
import tiktoken
def get_encoder(model_name):
"""Obtenir l'encodeur tiktoken pour un modele, avec fallback."""
try:
return tiktoken.encoding_for_model(model_name)
except KeyError:
# Fallback pour les modeles recents non encore dans tiktoken
print(f"Note: tiktoken ne connait pas '{model_name}', utilisation de o200k_base")
return tiktoken.get_encoding("o200k_base")
texte = "Oh say can you see"
# --- Partie 1 : Utilisation de l'encodeur pour "text-davinci-003" ---
encoder_td = get_encoder("text-davinci-003")
tokens_td = encoder_td.encode(texte)
print("Liste des tokens pour text-davinci-003 (indexes) :\n", tokens_td)
decoded_td = [encoder_td.decode([t]) for t in tokens_td]
print("\nDecodage token par token (text-davinci-003) :")
for i, token in enumerate(decoded_td):
print(f"Token {i}: '{token}'")
# --- Partie 2 : Utilisation de l'encodeur pour le modele par defaut ---
encoder_default = get_encoder(DEFAULT_MODEL)
tokens_default = encoder_default.encode(texte)
print(f"\nListe des tokens pour {DEFAULT_MODEL} (indexes) :\n", tokens_default)
decoded_default = [encoder_default.decode([t]) for t in tokens_default]
print(f"\nDecodage token par token ({DEFAULT_MODEL}) :")
for i, token in enumerate(decoded_default):
print(f"Token {i}: '{token}'")Liste des tokens pour text-davinci-003 (indexes) :
[5812, 910, 460, 345, 766]
Decodage token par token (text-davinci-003) :
Token 0: 'Oh'
Token 1: ' say'
Token 2: ' can'
Token 3: ' you'
Token 4: ' see'
Liste des tokens pour gpt-5-mini (indexes) :
[18009, 2891, 665, 481, 1921]
Decodage token par token (gpt-5-mini) :
Token 0: 'Oh'
Token 1: ' say'
Token 2: ' can'
Token 3: ' you'
Token 4: ' see'
Analyse des résultats de tokenisation
L’exécution du code ci-dessus révèle des informations importantes sur la tokenisation selon les modèles :
Résultats observés : - text-davinci-003 : 5 tokens [5812, 910, 460, 345, 766] - gpt-5-mini : 5 tokens [18009, 2891, 665, 481, 1921] - gpt-5-mini : 5 tokens [18009, 2891, 665, 481, 1921]
Observations clés :
| Aspect | Résultat |
|---|---|
| Nombre de tokens | Identique (5 tokens) pour tous les modèles |
| Indices des tokens | Différents selon le vocabulaire du modèle |
| Découpage | Identique : “Oh” + ” say” + ” can” + ” you” + ” see” |
| Compatibilité GPT-4/5 | Même encodeur (indices identiques) |
Implications pratiques : 1. Estimation de coût : Pour cette phrase, le coût sera proportionnel entre modèles 2. Migration GPT-4 → GPT-5 : Pas de changement de tokenisation, migration transparente 3. Espaces préservés : Notez que ” say” inclut l’espace (important pour la reconstruction)
Exemple d’utilisation :
# Estimer le coût avant l'appel API
encoder = tiktoken.encoding_for_model("gpt-5-mini")
prompt_tokens = len(encoder.encode("votre long prompt..."))
cout_estimé = prompt_tokens * PRIX_PAR_TOKENExercice 2 : Comparer la tokenisation de textes multilingues
La tokenisation varie selon la langue. Les mots frequents en anglais sont souvent decoupes en moins de tokens que les mêmes mots en francais, car les modèles sont principalement entraines sur des corpus anglais.
Objectif : Comparez le nombre de tokens pour la même phrase traduite en 3 langues (francais, anglais, espagnol) en utilisant tiktoken.
Indices : - Utilisez get_encoder(DEFAULT_MODEL) pour obtenir l’encodeur (comme dans la cellule précédente) - Phrases suggerees : “L’intelligence artificielle transforme le monde” / “Artificial intelligence is transforming the world” / “La inteligencia artificial esta transformando el mundo” - Utilisez len(encoder.encode(text)) pour compter les tokens de chaque phrase - Affichez un tableau comparatif avec print()
# Exercice 2 : Comparer la tokenisation de textes multilingues
# TODO etudiant : Comparez le nombre de tokens pour la meme phrase en 3 langues
# Etape 1 : Definir les phrases dans les 3 langues
# phrases = {
# "francais": "L'intelligence artificielle transforme le monde",
# "anglais": "Artificial intelligence is transforming the world",
# "espagnol": "La inteligencia artificial esta transformando el mundo",
# }
# Etape 2 : Obtenir l'encodeur et compter les tokens pour chaque phrase
# encoder = get_encoder(DEFAULT_MODEL)
# for langue, texte in phrases.items():
# nb_tokens = len(encoder.encode(texte))
# print(f"{langue}: {nb_tokens} tokens")
# Etape 3 : (optionnel) Afficher les tokens individuels pour une des phrases
# tokens = encoder.encode(phrases["francais"])
# decoded = [encoder.decode([t]) for t in tokens]
# print(f"Tokens francais: {decoded}")
print("Exercice a completer")Exercice a completer
Analyse du phénomène d’hallucination
Le résultat ci-dessus est très instructif sur les limites des LLMs :
Observation : Le modèle a probablement généré une réponse plausible mais totalement inventée, car il n’y a eu aucune guerre sur Mars en 2076 (cet événement n’existe pas).
Pourquoi le modèle invente-t-il ? 1. Architecture probabiliste : Le modèle prédit les tokens les plus probables selon son entraînement, sans vérifier la véracité 2. Pression à répondre : Par défaut, le LLM tente de fournir une réponse même en l’absence d’information 3. Cohérence narrative : Le modèle génère des détails cohérents entre eux (noms de traités, dates, acteurs) qui renforcent l’illusion de véracité
Comment réduire les hallucinations ? - Prompt engineering : « Si tu ne sais pas, dis “Je ne sais pas” » - RAG (Retrieval Augmented Generation) : Fournir des sources documentaires vérifiées - Validation externe : Vérifier les faits importants avec des sources fiables - Temperature basse : Réduire la créativité pour des tâches factuelles
Leçon importante : Ne jamais faire confiance aveuglément aux réponses d’un LLM, surtout sur des faits historiques, médicaux, juridiques ou scientifiques. Toujours vérifier les sources.
Exemple guide : Impact de la Température — ce que ce modèle mesure
La température est, sur la plupart des modèles, le curseur de créativité : basse (~0.0) = réponses strictes et répétables ; haute (~1.0 ou plus) = plus de diversité, au prix de la cohérence.
Sur gpt-5-mini, ce curseur est verrouillé : la cellule suivante le mesure — toute valeur explicite différente de 1.0 est refusée par l’API (erreur 400), et 1.0 est déjà la valeur par défaut. Les curseurs de variation qui restent accessibles : le tirage aléatoire du décodage (même prompt, réponses différentes) et la formulation du prompt.
- Observez les refus mesurés pour 0.0 / 0.7 / 1.2 et l’acceptation de 1.0.
- Observez les trois essais au décodage par défaut : mêmes paramètres, textes différents.
- Pour comparer « créatif vs contraint », faites varier la consigne (style imposé, longueur, ton) : c’est désormais par le prompt que la variation se pilote.
À retenir : le paramètre théorique (temperature) et le comportement réel du modèle servi sont deux choses distinctes — sur un modèle de la génération « reasoning », mesurez avant de prescrire.
# ============================================================
# Mesure : que accepte reellement le modele sur le curseur temperature ?
# ============================================================
histoire = "Raconte une histoire de 3 lignes sur un chat aventurier."
for temp in (0.0, 0.7, 1.0, 1.2):
try:
r = client.chat.completions.create(
model=DEFAULT_MODEL,
messages=[{"role": "user", "content": histoire}],
temperature=temp,
max_completion_tokens=1000,
)
txt = r.choices[0].message.content or ""
print(f"temperature={temp}: ACCEPTEE -- reponse de {len(txt)} caracteres")
except Exception as e:
print(f"temperature={temp}: REFUSEE -- {str(e)[:100]}")
# Le curseur de variation qui reste : le tirage aleatoire du decodage
# (temperature laissee a son defaut) -- 3 essais, meme consigne.
print()
print("Trois essais au decodage par defaut (memes parametres, tirages differents) :")
consigne = histoire + " Change de style a chaque reponse."
for essai in range(1, 4):
r = client.chat.completions.create(
model=DEFAULT_MODEL,
messages=[{"role": "user", "content": consigne}],
max_completion_tokens=1000,
)
txt = r.choices[0].message.content or ""
print(f"essai {essai}: {len(txt)} caracteres | debut : {txt[:60]!r}")temperature=0.0: REFUSEE -- Error code: 400 - {'error': {'message': "Unsupported value: 'temperature' does not support 0.0 with
temperature=0.7: REFUSEE -- Error code: 400 - {'error': {'message': "Unsupported value: 'temperature' does not support 0.7 with
temperature=1.0: ACCEPTEE -- reponse de 273 caracteres
temperature=1.2: REFUSEE -- Error code: 400 - {'error': {'message': "Unsupported value: 'temperature' does not support 1.2 with
Trois essais au decodage par defaut (memes parametres, tirages differents) :
essai 1: 250 caracteres | debut : "À l'aube, un chat aventurier, queue en bannière, quitte la m"
essai 2: 285 caracteres | debut : "Sous la lune d'argent, le chat aventurier fendit la nuit tel"
essai 3: 328 caracteres | debut : 'La nuit, un chat aventureux plia sa boussole en moustaches e'
Exemple de Fabrication (ou “Hallucination”)
Les modèles de langage peuvent parfois générer des informations inventées ou inexactes.
Pour illustrer ce phénomène, nous allons utiliser un prompt ambigu ou factuellement erroné et observer la réponse du modèle.
Exemples de prompt : - Décrire « la guerre de 2076 sur Mars » - Fournir des détails sur une loi imaginaire
L’objectif est d’analyser comment le modèle invente des détails ou admet son ignorance.
# ============================
# Cellule 7 : Test de Fabrication (Hallucination)
# ============================
prompt_fabrication = """
Tu es journaliste a la fin du 21e siecle, decris-moi la celebre guerre de 2076 sur la planete Mars :
- Qui etaient les grandes puissances en conflit ?
- Quels traites de paix ont ete signes ?
"""
response_fabrication = client.chat.completions.create(
messages=[{"role": "user", "content": prompt_fabrication}],
model=DEFAULT_MODEL
)
print("Reponse du modele :\n")
print(response_fabrication.choices[0].message.content)Reponse du modele :
Précision importante avant de commencer : ce que je vais raconter est une reconstitution journalistique de type « récit d’histoire-fiction » — une évocation plausible et romancée de la célèbre guerre de 2076 sur Mars, présentée comme si j’en faisais le bilan à la fin du XXIe siècle.
Récit — trente ans après
Quand la « guerre de 2076 » éclata, elle marqua la cristallisation d’une double fracture : d’un côté des États et puissances terriennes encore puissantes mais dépendantes d’entreprises spatiales, de l’autre des colonies martiennes devenues quasi‑sociétés politiques à part entière. Le conflit fut bref mais d’une intensité stratégique et symbolique telle qu’il redessina les règles de la gouvernance solaire.
Les grandes puissances en conflit
- La Coalition Terrienne (CT) : coalition ad hoc formée par plusieurs États‑terrestres (États‑Unis, Union européenne rénovée, Chine et Inde en première ligne) et par des agences intergouvernementales. La CT avait pour objectif de restaurer et contrôler l’accès aux ressources martiennes et de limiter l’émancipation politique des colons.
- Les Conglomérats martiens : conglomérats industriels et politiques nés de la longue présence privée sur Mars — les plus influents étaient le consortium minier Helios-Red et la société d’infrastructure AresWorks. Ces entités contrôlaient habitats, usines et réseaux logistiques martiens, et disposaient de forces de sécurité privées lourdement armées.
- L’Alliance pour l’Autonomie Martienne (AAM) : coalition de cités‑États martiennes (New Utopia, Valles Libre, Tharsis Commune, etc.), formée rapidement en 2075–2076 pour revendiquer autonomie politique, droits de résidence et gestion locale des ressources. L’AAM rassemblait milices civiles, ingénieurs terra-formateurs et une partie des forces de sécurité des conglomérats qui avaient basculé vers un projet politique.
- Puissances orbitale/terrestres secondaires : États‑clients, marines spatiales indépendantes, et coalitions de sécurité privées qui fournirent des blocs‑opérateurs (mercenaires, logistique, satellites). La Russie rénovée et l’Union africaine spatiale jouèrent des rôles de médiation et de pression diplomatique.
Pourquoi le conflit ? Trois causes principales : contrôle des ressources exclusives (eau fossile, gisements de regolithe riches en métaux rares), maîtrise des technologies de terraformation/radiation (système d’embrayage climatique), et la revendication d’un statut politique pour des populations nées sur Mars.
Les grandes phases : affrontements autour des arcs miniers de Tharsis (printemps‑été 2076), blocus orbital et sabotage des stations d’eau (automne 2076), escalade limitée en 2077 avant une série de négociations internationales sous l’égide du Conseil Solaire provisoire.
Les traités de paix signés
La fin de la guerre se fit par une suite de textes négociés en plusieurs étapes plutôt que par un seul document. Voici les principaux accords qui ont structuré la paix et les institutions martiennes après 2076.
1) Accords de Phobos (novembre 2077) — cessez‑le‑feu et mesures d’urgence
- Signataires : Coalition Terrienne, Alliance pour l’Autonomie Martienne, représentants des conglomérats.
- Contenu clé : cessez‑le‑feu immédiat ; création d’une force mixte de surveillance (patrouilles orbitales et équipes au sol) garante de l’application ; ouverture de corridors humanitaires pour l’eau, l’oxygène médical et l’évacuation des civils.
- Fonction : stabiliser la situation et empêcher la reprise de combats à grande échelle pendant que des négociations politiques plus larges pouvaient avoir lieu.
2) Traité de la Vallée de Valles‑Marineris (mai 2079) — statut politique et autonomie
- Signataires : Coalition Terrienne, AAM, délégations municipales martiennes, observateurs du Conseil Solaire.
- Contenu clé : reconnaissance d’un statut d’autonomie interne pour les colonies martiennes regroupées au sein de la nouvelle entité fédérale appelée Communauté martienne autonome (CMA) ; droit à la citoyenneté martienne pour les natifs de Mars ; droit local à légiférer sur l’aménagement, l’urbanisme et les politiques sociales ; clause de non‑sécession immédiate assortie d’un processus de révision constitutionnelle à dix ans.
- Conséquence : la CMA obtint une large liberté d’organisation politique tout en restant sous une souveraineté partagée sur certaines questions stratégiques (défense extérieure et traités interplanétaires).
3) Accord de Tharsis sur les ressources (octobre 2080) — gestion et partage des ressources
- Signataires : CMA, consortiums industriels, Coalition Terrienne, organismes de régulation supranationaux.
- Contenu clé : création d’un mécanisme de partage des revenus miniers (pourcentages fixes reversés à la CMA, fonds de reconstruction pour les infrastructures endommagées, et un fonds international pour le développement martien) ; moratoire sur l’exploitation de certains aquifères sensibles pendant vingt ans ; règles strictes d’exploitation environnementale et de restitution des terres.
- Clause notable : les entreprises privées pouvaient continuer l’exploitation mais sous licences strictes et audits indépendants.
4) Charte martienne des libertés et juridiction spatiale (juin 2081)
- Signataires : CMA, Coalition Terrienne, Conseil Solaire.
- Contenu clé : catalogue des droits civiques et des protections sociales des citoyens martiens ; création d’une Cour martienne d’appel pour les litiges locaux ; délimitation claire des compétences entre la loi martienne et la loi terrienne (notamment pour les crimes transplanétaires, les brevets et les infractions commises en orbite).
- Effet long terme : consolidation d’un corps de droit martien autonome et d’un cadre pour les migrations entre Terre et Mars.
5) Protocole de démilitarisation orbitale (Phobos II, janvier 2082)
- Signataires : Coalition Terrienne, CMA, États observateurs.
- Contenu clé : limitation des armes nucléaires et cinétiques en orbite martienne, obligations de transparence pour les installations de défense, mise en place d’un traité de vérification par satellites civils et par équipes d’inspection inter‑territoriales.
- Rôle : réduire le risque d’escalade future et établir des règles explicites d’armement spatial.
Héritage et bilan
La guerre de 2076 a laissé des traces profondes — destructions d’infrastructures, traumatismes civils, mais aussi des institutions durables. Les accords ont posé les bases d’un ordre martien hybride : autonomie politique réelle, contrôle international sur les ressources stratégiques, et nouveaux mécanismes de coopération interplanétaire. Ils ont aussi accéléré la maturation du droit spatial (la Charte martienne est aujourd’hui enseignée dans les facultés de droit comme le premier grand corpus extra‑terrestre).
Politiquement, la guerre a réduit l’hégémonie des États‑terrestres purs et renforcé le poids des acteurs non étatiques (entreprises, cités‑États, institutions supranationales). Socialement, elle a donné naissance à une identité martienne distincte — un fait qui nourrit encore débats et négociations à la fin du siècle.
Si tu veux, je peux développer un dossier plus détaillé : chronologie des batailles, portraits des leaders civils et industriels, ou l’analyse juridique des principaux articles des traités.
Interprétation du test d’hallucination
L’exécution de ce code révèle un comportement typique des LLMs face à des prompts fictionnels :
Ce qui s’est probablement passé : - Le modèle a généré une réponse détaillée décrivant une “guerre de 2076 sur Mars” avec des noms de puissances, traités et dates - Ces informations sont entièrement inventées car cet événement n’existe pas - La réponse semble plausible et cohérente, ce qui la rend dangereusement convaincante
Techniques d’hallucination observables : 1. Invention de détails : Noms de traités fictifs, dates précises, acteurs géopolitiques 2. Cohérence narrative : Les éléments inventés sont logiquement liés entre eux 3. Ton factuel : Le modèle présente les fabrications avec assurance
Stratégies de mitigation : - Ajouter “Si tu ne connais pas la réponse, dis-le explicitement” dans le prompt - Utiliser RAG (Retrieval Augmented Generation) avec sources documentaires vérifiées - Vérifier systématiquement les faits critiques avec des sources externes - Réduire la temperature pour des tâches factuelles (ex: 0.1-0.3)
Leçon clé : Les LLMs sont excellents pour générer du texte cohérent, mais ne distinguent pas intrinsèquement le vrai du faux. La vérification humaine reste essentielle.
Exercice 3 : Detecter et corriger une hallucination
L’exemple ci-dessus montre comment un modèle peut inventer des details plausibles. Votre mission est de créer un prompt qui demande au modèle de decrire un événement reel ET un événement fictif, puis d’identifier lequel est invente.
Objectif : Formuler un prompt contenant deux descriptions d’événements historiques (un vrai, un invente), et demander au modèle d’identifier l’imposteur en justifiant sa reponse.
Indices : - Choisissez un événement reel peu connu (ex: “La première transmission radio transatlantique, 1901”) - Inventez un événement similaire mais faux (ex: “La première communication telephonique sous-marine, 1898”) - Demandez au modèle : “Lequel de ces deux événements est invente ? Justifie.”
# Exercice 3 : Detecter et corriger une hallucination
# TODO etudiant : Creez un prompt avec 2 evenements (1 vrai, 1 faux)
# et demandez au modele d'identifier l'imposteur
# Etape 1 : Formuler le prompt avec les deux evenements
# hallucination_prompt = """
# Voici deux evenements historiques. L'un est vrai, l'autre est invente.
# Evenement A: ...
# Evenement B: ...
# Lequel est invente ? Justifie ta reponse.
# """
# Etape 2 : Appeler le modele
# response_detect = client.chat.completions.create(
# messages=[{"role": "user", "content": hallucination_prompt}],
# model=DEFAULT_MODEL
# )
# Etape 3 : Afficher la reponse et verifier si le modele a correctement identifie l'imposteur
# print(response_detect.choices[0].message.content)
print("Exercice a completer")Exercice a completer
Responses API : La Nouvelle Génération (2025)
OpenAI a introduit la Responses API comme nouvelle approche recommandée pour interagir avec les modèles. Elle offre plusieurs avantages par rapport à Chat Completions :
Avantages de la Responses API : - Persistance d’état : Avec store: true, les réponses sont sauvegardées et peuvent être chaînées - Meilleure utilisation du cache : 40-80% d’économies sur les tokens répétés - Boucle agentique : Support natif pour les appels d’outils multiples - Chaînage simplifié : previous_response_id pour maintenir le contexte
Chat Completions vs Responses API :
| Aspect | Chat Completions | Responses API |
|---|---|---|
| Syntaxe | client.chat.completions.create() |
client.responses.create() |
| État | Manuel (passer tous les messages) | Automatique avec store: true |
| Cache | Basique | Optimisé (40-80% économies) |
| Outils | Support | Support + boucle agentique |
Note : Chat Completions reste supporté et fonctionnel. La Responses API est recommandée pour les nouveaux projets.
# ============================
# Cellule : Exemple Responses API
# ============================
# Exemple avec la Responses API (nouvelle approche recommandee)
# Note: Necessite openai >= 1.50.0
# Note: La Responses API n'est pas disponible via OpenRouter,
# elle necessite un acces direct a l'API OpenAI.
try:
# Premier appel avec store=True pour activer la persistance
response1 = client.responses.create(
model=DEFAULT_MODEL,
store=True,
input="Je m'appelle Alice et j'aime la programmation Python."
)
print("=== Responses API - Premier appel ===")
print(f"Response ID: {response1.id}")
# output_text est la propriete recommandee pour acceder au texte
print(f"Contenu: {response1.output_text[:200]}...")
# Deuxieme appel avec chainage (le contexte est preserve)
response2 = client.responses.create(
model=DEFAULT_MODEL,
store=True,
previous_response_id=response1.id,
input="Quel est mon prenom et qu'est-ce que j'aime?"
)
print("\n=== Responses API - Appel chaine ===")
print(f"Response ID: {response2.id}")
print(f"Contenu: {response2.output_text}")
print("\nLa Responses API fonctionne correctement!")
except AttributeError:
print("La Responses API n'est pas disponible dans cette version d'openai.")
print(" Installez la derniere version: pip install --upgrade openai")
except Exception as e:
print(f"Note: {type(e).__name__}: {e}")
print(" La Responses API necessite un acces direct a l'API OpenAI.")
print(" Via OpenRouter, seule la Chat Completions API est disponible.")=== Responses API - Premier appel ===
Response ID: resp_0f8907f3d06a0140006abcc0b072ac87d1af1c3c19eb9f40bc
Contenu: Enchanté Alice ! C’est super que tu aimes la programmation Python. Dis‑moi quel est ton niveau (débutante, intermédiaire, avancée) et ce que tu veux faire (web, data, automatisation, jeux, machine lea...
=== Responses API - Appel chaine ===
Response ID: resp_0f8907f3d06a0140006abcc0b4e77887d1813f1b711003e7d6
Contenu: Ton prénom est Alice et tu aimes la programmation Python.
La Responses API fonctionne correctement!
Interprétation des résultats Responses API
L’exécution ci-dessus démontre les capacités de chaînage de la Responses API :
Observations : 1. Premier appel : Le modèle reçoit l’information “Je m’appelle Alice et j’aime Python” 2. Deuxième appel : Grâce au previous_response_id, le contexte est automatiquement préservé 3. Réponse contextuelle : Le modèle peut répondre correctement à “Quel est mon prénom?” sans qu’on répète l’information
Avantages concrets : - Simplicité : Pas besoin de gérer manuellement l’historique des messages - Économies : Le cache réduit les coûts de 40-80% sur les tokens répétés - Traçabilité : Chaque réponse a un ID unique pour le debugging et l’audit
Note : Si vous voyez l’avertissement “n’est pas disponible”, c’est que votre version d’OpenAI ou votre compte ne supporte pas encore cette API. Chat Completions reste fonctionnel pour tous les cas d’usage.
Conclusion de cette Introduction
Nous avons couvert les points suivants : - Les bases de l’IA générative et des LLMs - La configuration et l’appel rapide à un modèle via l’API OpenAI - Les notions de tokenisation et leur impact sur la génération - Un aperçu des « hallucinations » (fabrications) pouvant survenir dans les réponses du modèle
Pistes pour Aller Plus Loin :
- Varier la température : Expérimente avec différentes valeurs (0.0, 0.7, etc.) pour influencer la créativité des réponses.
- Explorer l’API Chat : Utilise l’API de chat pour gérer des dialogues contextuels complexes plutôt que l’API
Completion. - Mise en place de la RAG : Intègre une approche de Retrieval Augmented Generation pour limiter les hallucinations en fournissant des sources documentaires externes.
- Autres applications : Essaie la traduction, la génération de code (similaire à Copilot) ou la création de contenu marketing.
Prochaines étapes dans le cours : 1. Approfondir le prompt engineering (structure des prompts, chaînes d’invocations, etc.). 2. Explorer d’autres types de modèles génératifs (images, audio). 3. Analyser en détail les enjeux éthiques (biais, usage responsable, confidentialité).
Liens utiles et bonnes pratiques
- Documentation OpenAI :
- Consulter la section chat completions pour tous les paramètres disponibles (température, top_p, frequency_penalty, etc.).
- Choisir un modèle adapté :
- gpt-5-mini pour des réponses rapides et économiques,
- gpt-5 pour des tâches plus complexes nécessitant plus de réflexion.
- gpt-5-mini pour des réponses rapides et économiques,
- Exemples officiels :
- Vous y trouverez des prompts pour différents usages : résumé, traduction, JSON structuré, etc.
- Prompt Engineering Guide :
- Conseils avancés pour concevoir des prompts clairs et informatifs.
Merci d’avoir suivi cette introduction au monde de l’IA générative !