Conversations Multi-Tour en Python
Le principe des conversations multi-tour
Contrairement à un moteur de recherche, un modèle de langage peut maintenir le fil d’une conversation. Il se souvient de ce que vous avez dit précédemment et construit ses réponses en tenant compte du contexte accumulé. C’est ce qu’on appelle une conversation multi-tour.
Techniquement, le modèle ne « se souvient » de rien. À chaque requête, vous lui envoyez l’intégralité de l’historique : il le relit à chaque fois pour produire une réponse cohérente.
Les trois rôles de messages
Chaque message dans l’historique porte un rôle qui indique au modèle qui parle :
Le rôle system
Le message système définit le comportement global du modèle. Il est placé en premier et influence toutes les réponses :
{"role": "system", "content": "Vous êtes un assistant expert en cuisine française. Répondez toujours en français avec des termes culinaires précis."}
Le rôle user
Les messages de l’utilisateur. C’est la question ou l’instruction envoyée :
{"role": "user", "content": "Comment réussir une pâte feuilletée ?"}
Le rôle assistant
Les réponses précédentes du modèle, renvoyées dans l’historique pour maintenir la cohérence :
{"role": "assistant", "content": "Pour réussir une pâte feuilletée, commencez par..."}
Construire une conversation
Voici un exemple complet de conversation multi-tour :
import os
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
historique = [
{
"role": "system",
"content": "Vous êtes un assistant pédagogique spécialisé en programmation Python. Répondez de façon concise et avec des exemples de code."
}
]
def poser_question(question: str) -> str:
"""Envoie une question et met à jour l'historique."""
historique.append({"role": "user", "content": question})
response = client.chat.complete(
model="mistral-small-latest",
messages=historique,
)
reponse_texte = response.choices[0].message.content
historique.append({"role": "assistant", "content": reponse_texte})
return reponse_texte
# Tour 1
print("Q: Qu'est-ce qu'un décorateur en Python ?")
r1 = poser_question("Qu'est-ce qu'un décorateur en Python ?")
print(f"R: {r1}\n")
# Tour 2 — le modèle connaît le contexte
print("Q: Pouvez-vous me montrer un exemple concret ?")
r2 = poser_question("Pouvez-vous me montrer un exemple concret ?")
print(f"R: {r2}\n")
# Tour 3 — référence implicite aux tours précédents
print("Q: Comment l'utiliser avec des arguments ?")
r3 = poser_question("Comment l'utiliser avec des arguments ?")
print(f"R: {r3}\n")
Au tour 3, le modèle comprend que « l’utiliser » fait référence au décorateur discuté précédemment, car il a accès à tout l’historique.
Gérer la taille du contexte
Chaque modèle a une fenêtre de contexte limitée (mesurée en tokens). Plus l’historique est long, plus vous consommez de tokens à chaque requête, et plus le coût augmente.
Stratégies de gestion
Troncation par nombre de messages :
MAX_MESSAGES = 20
def ajouter_message(historique, role, content):
historique.append({"role": role, "content": content})
# Garder le message system + les N derniers messages
if len(historique) > MAX_MESSAGES + 1: # +1 pour le system
system_msg = historique[0]
historique = [system_msg] + historique[-(MAX_MESSAGES):]
return historique
Résumé du contexte :
Pour les conversations très longues, résumez périodiquement l’historique :
def resumer_historique(client, historique):
"""Résume les anciens messages pour libérer du contexte."""
texte_complet = "\n".join(
f"{m['role']}: {m['content']}"
for m in historique[1:-4] # Exclure system et les 4 derniers
)
resume = client.chat.complete(
model="mistral-small-latest",
messages=[
{"role": "user", "content": f"Résumez cette conversation en 3-4 phrases :\n{texte_complet}"}
]
)
return [
historique[0], # System message
{"role": "assistant", "content": f"[Résumé de la conversation] {resume.choices[0].message.content}"},
] + historique[-4:] # Les 4 derniers messages
Le message système : bonnes pratiques
Le message système est puissant mais souvent sous-exploité. Voici comment l’optimiser :
system_prompt = """Vous êtes un assistant technique Corsen AI.
Règles :
- Répondez en français avec un ton professionnel
- Fournissez des exemples de code quand c'est pertinent
- Si vous n'êtes pas sûr, dites-le plutôt que d'inventer
- Limitez vos réponses à 200 mots sauf demande contraire
Contexte : l'utilisateur travaille sur un projet Python 3.12 avec FastAPI."""
Un bon message système est concis, précis, et définit les contraintes sans ambiguïté.
Points clés à retenir
- L’historique complet est renvoyé à chaque requête — le modèle ne « mémorise » rien
- Les trois rôles (
system,user,assistant) structurent la conversation - Le message
systemdéfinit le comportement global — placez-le toujours en premier - Gérez la taille du contexte en tronquant ou en résumant les anciens messages
- Plus l’historique est long, plus chaque requête coûte cher en tokens