Stop sequences
Mis à jour le 29 juillet 2026
Arrêter la génération au bon moment
Par défaut, le modèle s’arrête pour deux raisons seulement : il estime avoir terminé sa réponse et émet son token de fin, ou il bute sur le plafond de max_tokens. Ces deux critères ne couvrent pas tous les besoins. Vous voulez parfois que la génération cesse à un endroit que vous seul connaissez — juste avant la section suivante d’un document, juste après la fermeture d’un bloc JSON, dès que le modèle s’apprête à ajouter un commentaire dont vous n’avez pas besoin.
Les stop sequences ajoutent ce troisième critère : dès que le modèle produit une séquence de texte que vous avez désignée, la génération s’interrompt immédiatement. C’est un instrument de découpe précis, et le complément naturel des consignes de format données dans le message système, qu’un modèle suit bien mais pas toujours.
Fonctionnement du paramètre stop
Le paramètre accepte une liste de chaînes de caractères. La première qui apparaît dans la sortie met fin à la génération :
from mistralai import Mistral
import os
client = Mistral(api_key=os.getenv("MISTRAL_API_KEY"))
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{"role": "user", "content": "Listez les 10 plus grandes villes de France."}
],
stop=["6."] # Arrêter après les 5 premières
)
print(response.choices[0].message.content)
# 1. Paris
# 2. Marseille
# 3. Lyon
# 4. Toulouse
# 5. Nice
Deux comportements sont à retenir de cet exemple. La séquence d’arrêt n’est pas incluse dans la réponse : vous récupérez le texte qui la précède, sans avoir à le nettoyer vous-même. Et le finish_reason vaut "stop", exactement comme pour un arrêt naturel — l’API ne distingue pas les deux, c’est donc à vous de savoir ce que vous avez demandé.
Trois usages typiques
Le premier cas est celui du modèle bavard. Vous demandez une capitale, il vous donne la capitale puis trois phrases d’explication que votre interface n’attendait pas. La consigne système pose l’intention, les stop sequences la font respecter :
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "system",
"content": "Répondez uniquement par le nom de la ville, rien d'autre."
},
{
"role": "user",
"content": "Quelle est la capitale de l'Italie ?"
}
],
stop=["\n", ".", "Explication"] # Arrêter au premier retour à la ligne ou point
)
print(response.choices[0].message.content.strip())
# Rome
Le deuxième cas concerne la génération de documents section par section, quand vous voulez garder la main entre chaque partie plutôt que de laisser le modèle produire un rapport entier d’un seul jet. Vous stoppez sur les délimiteurs qui annoncent la suite :
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "system",
"content": "Rédigez la section Introduction d'un rapport."
},
{
"role": "user",
"content": "Sujet : l'impact de l'IA sur l'emploi en Europe."
}
],
stop=["## ", "---", "Conclusion"] # Arrêter avant la section suivante
)
Le troisième cas est le plus rentable en pratique : extraire du JSON exploitable sans passer par une étape de nettoyage. Le modèle a une propension à encadrer sa sortie de texte explicatif, ce qui fait échouer json.loads() ; couper au double saut de ligne ou aux triples backticks élimine le problème à la source.
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "system",
"content": "Répondez uniquement en JSON valide."
},
{
"role": "user",
"content": "Donnez-moi les infos de Paris : population, pays, fuseau horaire."
}
],
stop=["\n\n", "```"] # Arrêter après le bloc JSON
)
Combiner stop sequences et streaming
Rien n’interdit d’associer les deux mécanismes : le flux s’interrompt dès que l’une des séquences d’arrêt est détectée dans le texte généré, et les fragments déjà reçus restent valides.
stream = client.chat.stream(
model="mistral-large-latest",
messages=[
{"role": "user", "content": "Racontez une courte histoire."}
],
stop=["Fin.", "THE END", "---"]
)
full_text = ""
for chunk in stream:
content = chunk.data.choices[0].delta.content
if content:
full_text += content
print(content, end="", flush=True)
print(f"\n\nTexte : {len(full_text)} caractères")
Limites du mécanisme
Quatre contraintes encadrent l’usage du paramètre stop. Vous ne pouvez fournir que quatre séquences au maximum par requête, ce qui impose de choisir les plus discriminantes plutôt que d’en empiler. Elles sont sensibles à la casse : "fin" ne captera jamais "Fin", et il faut donc prévoir les variantes qui comptent. La séquence n’est jamais incluse dans la réponse, ce qu’il faut garder en tête si votre format attendu se termine par ce délimiteur. Enfin, la détection se fait token par token : si votre séquence tombe au milieu d’un token, elle passera inaperçue — raison de plus pour choisir des délimiteurs de plusieurs caractères plutôt qu’un signe isolé.
Les erreurs qui coûtent cher
La faute la plus fréquente est la séquence trop courte, qui déclenche des arrêts intempestifs. Un point seul stoppe la génération à la première phrase venue, y compris au milieu d’une abréviation ; la faute symétrique consiste à choisir une chaîne que le modèle ne produira jamais, auquel cas le paramètre ne sert à rien et vous croyez à tort avoir posé une garde.
# MAUVAIS : séquence trop courte, arrêts intempestifs
stop=["."] # Arrêtera à chaque phrase !
# BON : séquence spécifique au contexte
stop=[".\n\n"] # Arrête après un point suivi d'un double retour à la ligne
# MAUVAIS : séquence jamais produite par le modèle
stop=["XYZZY"] # N'aura aucun effet
# BON : séquence réaliste basée sur le format attendu
stop=["Question suivante :", "---"]
La règle qui découle de ces quatre lignes est simple : une bonne séquence d’arrêt se déduit du format que vous avez demandé au modèle, jamais de votre imagination.
Exemple complet : Q&A contrôlé
Assemblons ces éléments dans une fonction de questions-réponses courte, où la température basse assure la stabilité factuelle, max_tokens pose un plafond de sécurité et les stop sequences coupent les commentaires que le modèle serait tenté d’ajouter après sa réponse :
from mistralai import Mistral
import os
client = Mistral(api_key=os.getenv("MISTRAL_API_KEY"))
def ask_single_question(question: str) -> str:
"""Pose une question et obtient une réponse concise sans bavardage."""
response = client.chat.complete(
model="mistral-large-latest",
messages=[
{
"role": "system",
"content": "Répondez en une seule phrase, directement et factuellement."
},
{"role": "user", "content": question}
],
max_tokens=100,
stop=["\n\n", "Remarque :", "Note :"],
temperature=0.1
)
return response.choices[0].message.content.strip()
# Test
questions = [
"Quelle est la vitesse de la lumière ?",
"Qui a inventé le téléphone ?",
"Combien de planètes dans le système solaire ?"
]
for q in questions:
print(f"Q: {q}")
print(f"R: {ask_single_question(q)}\n")
Exécutez ce script une première fois tel quel, puis une seconde en retirant le paramètre stop : la comparaison des deux sorties vous montrera exactement ce que ces trois séquences retiennent.
Points clés à retenir
- Les stop sequences arrêtent la génération quand le modèle produit un texte spécifique
- Maximum 4 séquences par requête, sensibles à la casse
- La séquence d’arrêt n’est jamais incluse dans la réponse
- Utilisez des séquences suffisamment spécifiques pour éviter les arrêts intempestifs
- Combinables avec le streaming et tous les autres paramètres