Exercices Prompt Engineering Pipeline complet : preparer un appel OpenAI
🎉

Bravo!

Avancé 🧠 Fondamentaux 30 XP 0 personnes ont réussi

Pipeline complet : preparer un appel OpenAI

C'est le projet final. On assemble tout ce qu'on a appris dans un pipeline de production complet. Avant chaque appel a l'API OpenAI, tu dois :

1. Construire le system prompt adaptatif
2. Construire la liste de messages
3. Compter les tokens pour estimer le cout
4. Tronquer la conversation si nécessaire pour rester dans le budget

Écris une fonction preparer_appel(config, historique, question, budget_tokens=4000, modèle='gpt-4o-mini') qui :

- Construit un system prompt a partir de config (un dictionnaire avec 'produit' et optionnellement 'niveau', 'langue')
- Crée la liste de messages : system prompt + historique (liste de dicts existants) + nouveau message user avec la question
- Compte les tokens de la conversation avec tiktoken (formule : 2 + 4 par message + tokens du contenu)
- Si le total dépasse budget_tokens, supprime les messages d'historique les plus anciens (garde toujours le system et la question)
- Retourne un dictionnaire avec :
'messages' : la liste de messages finale
'tokens_estimes' : le nombre de tokens de la conversation
'dans_budget' : True si on n'a pas eu besoin de tronquer, False sinon

Exemple :
result = preparer_appel(
config={'produit': 'Python'},
historique=[],
question='Comment créer une liste ?'
)
result['messages'] contient 2 messages (system + user)
result['dans_budget'] vaut True

Tests (1/1)

Tests
# Cas simple sans historique
result = preparer_appel(config={'produit': 'Python'}, historique=[], question='Salut')
assert len(result['messages']) == 2, 'Sans historique, il doit y avoir 2 messages (system + user)'
assert result['messages'][0]['role'] == 'system', 'Le premier message doit etre system'
assert result['messages'][-1]['role'] == 'user', 'Le dernier message doit etre user'
assert result['messages'][-1]['content'] == 'Salut', 'Le contenu user doit etre la question'
assert 'Python' in result['messages'][0]['content'], 'Le system prompt doit mentionner le produit'
assert result['dans_budget'] == True, 'Sans historique, on doit etre dans le budget'
assert isinstance(result['tokens_estimes'], int), 'Les tokens estimes doivent etre un entier'

# Avec historique
hist = [
    {'role': 'user', 'content': 'Message 1'},
    {'role': 'assistant', 'content': 'Réponse 1'},
]
result2 = preparer_appel(config={'produit': 'Django'}, historique=hist, question='Suite')
assert len(result2['messages']) == 4, 'Avec 2 msgs historique, il doit y avoir 4 messages au total'
assert result2['messages'][0]['role'] == 'system', 'Le system doit rester en premier'
assert result2['messages'][-1]['content'] == 'Suite', 'La question doit etre en dernier'

# Budget tres petit force la troncature
result3 = preparer_appel(config={'produit': 'X'}, historique=hist, question='Q', budget_tokens=30)
assert result3['messages'][0]['role'] == 'system', 'Le system doit toujours etre garde'
assert result3['messages'][-1]['content'] == 'Q', 'La question doit toujours etre gardee'
assert len(result3['messages']) <= len(hist) + 2, 'La conversation doit etre tronquee'

# Config avec niveau
result4 = preparer_appel(config={'produit': 'FastAPI', 'niveau': 'debutant'}, historique=[], question='Help')
assert 'debutant' in result4['messages'][0]['content'], 'Le niveau doit apparaitre dans le system prompt'

Indices (3 disponibles)

solution.py
Non stockée