Rôles et messages
Le cœur du protocole conversationnel
L’API Chat Completions ne reçoit pas un simple texte brut : elle attend un tableau de messages structurés, chacun associé à un rôle. Ce système de rôles permet au modèle de distinguer qui parle, quel est le contexte, et comment il doit répondre.
Maîtriser les rôles et la structure des messages est fondamental. C’est la différence entre un chatbot qui répond de manière cohérente et un système qui produit des résultats incohérents.
Les quatre rôles
L’API Mistral reconnaît quatre rôles distincts :
Le rôle system
Le message système définit le comportement global du modèle. Il est placé en première position et lu par le modèle avant tout échange. C’est ici que vous fixez le ton, les contraintes et le contexte de votre application.
messages = [
{
"role": "system",
"content": "Vous êtes un assistant juridique spécialisé en droit français. "
"Répondez de manière précise et citez les articles de loi pertinents. "
"Si vous n'êtes pas sûr, dites-le explicitement."
}
]
Le message système est géré par le développeur, pas par l’utilisateur final. Il n’apparaît jamais dans l’interface de votre application.
Le rôle user
C’est le message de l’utilisateur humain — la question, l’instruction, ou le texte à traiter :
messages.append({
"role": "user",
"content": "Quels sont les délais de prescription en matière civile ?"
})
Le rôle assistant
Ce rôle représente les réponses précédentes du modèle. Il est essentiel pour les conversations multi-tours : vous renvoyez l’historique complet pour que le modèle conserve le contexte.
messages.append({
"role": "assistant",
"content": "En droit civil français, le délai de prescription de droit commun est de 5 ans..."
})
Le rôle tool
Utilisé dans le cadre du function calling. Quand le modèle demande l’exécution d’une fonction externe, vous renvoyez le résultat avec ce rôle :
messages.append({
"role": "tool",
"content": '{"temperature": 22, "ville": "Paris"}',
"tool_call_id": "call_abc123"
})
Structure complète d’un échange multi-tours
Voici un exemple complet de conversation en Python :
from mistralai import Mistral
import os
client = Mistral(api_key=os.getenv("MISTRAL_API_KEY"))
conversation = [
{
"role": "system",
"content": "Vous êtes un chef cuisinier français. Proposez des recettes simples et savoureuses."
},
{
"role": "user",
"content": "Je veux préparer un dessert avec des pommes."
}
]
# Premier tour
response = client.chat.complete(
model="mistral-large-latest",
messages=conversation
)
assistant_reply = response.choices[0].message.content
print(assistant_reply)
# Ajouter la réponse à l'historique
conversation.append({"role": "assistant", "content": assistant_reply})
# Deuxième tour
conversation.append({
"role": "user",
"content": "Peux-tu adapter cette recette pour 8 personnes ?"
})
response = client.chat.complete(
model="mistral-large-latest",
messages=conversation
)
print(response.choices[0].message.content)
Le modèle reçoit tout l’historique à chaque appel. Il n’a pas de mémoire persistante entre les requêtes — c’est à vous de gérer l’état de la conversation.
Le contenu structuré
Le champ content d’un message peut être une simple chaîne de caractères ou une liste de types pour les contenus multimodaux :
# Contenu simple (texte)
{"role": "user", "content": "Décrivez cette image."}
# Contenu structuré (multimodal)
{"role": "user", "content": [
{"type": "text", "text": "Décrivez cette image."},
{"type": "image_url", "image_url": {"url": "https://exemple.com/image.jpg"}}
]}
Le prefix flag
Mistral propose une fonctionnalité unique : le prefix flag. Il vous permet de commencer la réponse de l’assistant avec un texte de votre choix, forçant le modèle à continuer dans cette direction :
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{"role": "system", "content": "Vous répondez toujours en JSON."},
{"role": "user", "content": "Liste 3 capitales européennes."},
{"role": "assistant", "content": '{"capitales": [', "prefix": True}
]
)
Le modèle continuera la réponse à partir de {"capitales": [, garantissant un format JSON valide. C’est particulièrement utile pour les sorties structurées en production.
Bonnes pratiques
- Gardez le message système concis — un paragraphe bien rédigé vaut mieux que deux pages de règles
- Renvoyez tout l’historique pour les conversations multi-tours, mais limitez-le si la fenêtre de contexte est dépassée
- N’inventez pas de fausses réponses assistant sauf pour le few-shot learning (leçon 10)
- Utilisez le prefix flag quand vous avez besoin d’un format de sortie strict
Points clés à retenir
- Quatre rôles :
system(comportement),user(requête),assistant(réponse),tool(résultat de fonction) - Le message système se place en premier et définit le cadre de l’application
- Le modèle n’a pas de mémoire : renvoyez l’historique complet à chaque requête
- Le prefix flag force le début de la réponse pour contrôler le format de sortie