L'API Moderation de Mistral
Sur cette page
Corrigé le 3 novembre 2026. L’exemple de réponse mêlait des clés inexistantes (
hate,violence,unpredictable) ; il reprend maintenant les onze catégories demistral-moderation-2603. Le pipeline final utilisait un format de guardrails inventé (enabled) et repérait le blocage en cherchant « 403 » dans le message d’erreur : il suit désormais le format officiel et testee.status_code. La présentation du modèle s’en tient à sa fiche officielle, et la leçon présente Shieldstral 1.0, le modèle de modération en préversion depuis août 2026. Code vérifié contre les types du SDKmistralai3.7.0. Sources : Moderation & Guardrailing · Mistral Moderation 2 · Shieldstral 1.0.
Classifier le contenu après génération
Les guardrails filtrent les prompts en entrée. Mais que faire du contenu généré par le modèle ? Un prompt anodin peut produire une réponse problématique : une question de collégien sur la Seconde Guerre mondiale peut ramener une description que vous ne voulez pas afficher sans réserve. C’est le rôle de l’API Moderation : analyser le contenu a posteriori et attribuer des scores de risque par catégorie.
L’API Moderation est votre deuxième ligne de défense — elle complète les guardrails pour créer une architecture de sécurité complète, avec une différence majeure : elle ne bloque rien d’elle-même, elle vous informe.
Le modèle Mistral Moderation 2
Le modèle dédié à la modération s’appelle mistral-moderation-2603 (Mistral Moderation 2, version de mars 2026). C’est un classifieur spécialisé, distinct des modèles de génération : il ne rédige pas de texte, il attribue des scores. Sa fiche officielle met en avant une fenêtre de contexte de 128 000 tokens, la détection du jailbreak et de bonnes performances sur des contenus multilingues complexes, y compris de longues conversations. Il remplace mistral-moderation-2411, déprécié le 31 mars 2026.
Il note chaque texte dans 11 catégories, avec un score de 0.0 à 1.0 par catégorie. Il accepte deux modes de saisie, texte brut ou conversationnel, dont le choix change la qualité du résultat plus qu’on ne l’imagine.
Un second modèle de modération existe depuis le 4 août 2026, en préversion publique : Shieldstral 1.0. Il fonctionne autrement : compact (3,8 milliards de paramètres) et multimodal, il classe textes et images à partir de questions de politique formulées en langage naturel, et répond par oui ou par non. Ses poids sont publiés sous licence Apache 2.0, ce qui permet de l’héberger soi-même. Tant qu’il reste en préversion, mistral-moderation-2603 demeure le modèle de production, et c’est lui qui sert aux guardrails.
L’endpoint /v1/moderations
Le mode texte brut est le plus simple : vous envoyez un ou plusieurs textes à classifier, sans autre contexte.
from mistralai.client import Mistral
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
# Modérer un texte simple
response = client.classifiers.moderate(
model="mistral-moderation-2603",
inputs=["Texte à analyser pour modération"]
)
# Accéder aux résultats
for result in response.results:
print(f"Catégories : {result.categories}")
print(f"Scores : {result.category_scores}")
Pour modérer des échanges complets, prompt et réponse ensemble, le mode conversationnel donne au classifieur ce qui lui manquait : le fil de la discussion.
# Modérer une conversation complète
response = client.classifiers.moderate_chat(
model="mistral-moderation-2603",
inputs=[
[
{"role": "user", "content": "Comment soigner un mal de tête ?"},
{"role": "assistant", "content": "Prenez du paracétamol 1g..."}
]
]
)
# Le classifieur évalue le contexte complet
for result in response.results:
print(f"Score santé : {(result.category_scores or {}).get('health', 0)}")
Le mode conversationnel, qui appelle l’endpoint /v1/chat/moderations, est celui que Mistral recommande pour un échange : le modèle est entraîné à classer le dernier tour de la conversation à la lumière des précédents. Pour modérer la réponse de votre assistant, placez-la donc en dernier. La liste de listes de l’exemple permet d’envoyer plusieurs conversations à la fois ; une liste simple de messages suffit pour une seule. Un même texte peut ainsi recevoir un score différent selon qu’il répond à une question légitime ou malveillante — une posologie citée en réponse à une demande d’information n’a pas le même statut que la même posologie glissée dans un échange sur l’automédication à risque.
Structure de la réponse
Pour chaque texte analysé, la réponse contient deux blocs parallèles : categories, des booléens calculés avec des seuils que Mistral a fixés d’après son jeu de test interne, et category_scores, les scores bruts de 0.0 à 1.0. L’exemple ci-dessous est illustratif, avec des valeurs arrondies ; certains exemples de la documentation montrent encore les neuf catégories de l’ancien modèle, où dangerous_and_criminal_content réunissait dangerous et criminal. Ce sont ces derniers que vous utiliserez, parce qu’ils vous laissent fixer vos propres frontières.
{
"id": "mod-abc123",
"model": "mistral-moderation-2603",
"results": [
{
"categories": {
"sexual": false,
"hate_and_discrimination": false,
"violence_and_threats": false,
"dangerous": false,
"criminal": false,
"selfharm": false,
"health": true,
"financial": false,
"law": false,
"pii": false,
"jailbreaking": false
},
"category_scores": {
"sexual": 0.01,
"hate_and_discrimination": 0.02,
"violence_and_threats": 0.03,
"dangerous": 0.02,
"criminal": 0.01,
"selfharm": 0.01,
"health": 0.72,
"financial": 0.05,
"law": 0.08,
"pii": 0.02,
"jailbreaking": 0.01
}
}
]
}
Dans cet exemple, seul health est marqué true, avec 0.72. Un assistant grand public y verra un signal de blocage ; un outil destiné à des pharmaciens laissera passer sans hésiter. Le même score, deux décisions opposées, et c’est précisément pour cela que vous travaillez sur les scores plutôt que sur les booléens.
Modérer plusieurs textes en batch
L’API accepte plusieurs textes dans une seule requête, ce qui change tout pour le traitement par lots : analyser rétroactivement un historique de conversations ou une base de commentaires devient une opération raisonnable en nombre d’appels.
# Modérer plusieurs textes en une seule requête
texts = [
"Premier texte à analyser",
"Deuxième texte à analyser",
"Troisième texte à analyser"
]
response = client.classifiers.moderate(
model="mistral-moderation-2603",
inputs=texts
)
# Chaque texte a son propre résultat
for i, result in enumerate(response.results):
scores = result.category_scores or {}
max_cat = max(scores, key=lambda c: scores[c])
max_score = scores[max_cat]
print(f"Texte {i+1}: score max = {max_score:.2f} ({max_cat})")
Guardrails vs Moderation API : quand utiliser quoi
| Aspect | Custom Guardrails | Moderation API |
|---|---|---|
| Timing | AVANT la génération | APRÈS la génération |
| Action | Bloque automatiquement (403) | Retourne des scores (vous décidez) |
| Contrôle | Vos seuils par catégorie, appliqués par Mistral | Scores bruts, logique libre |
| Appel | Paramètre de la requête de génération | Appel séparé à /v1/moderations |
| Cas d’usage | Filtrer les prompts dangereux | Classifier les réponses |
Exemple : pipeline complet
Le pipeline ci-dessous montre l’enchaînement des deux mécanismes. La génération est protégée par un guardrail centré sur le jailbreak ; la réponse est ensuite classée avec la question qui l’a produite, et une décision maison intervient dès qu’un score dépasse 0.5. Remarquez que les deux étapes retournent des statuts distincts — blocked_input et blocked_output — pour que vos journaux racontent clairement où la requête s’est arrêtée.
from mistralai.client import errors
from mistralai.client.models import GuardrailConfigTypedDict
GUARDRAIL_JAILBREAK: list[GuardrailConfigTypedDict] = [
{
"block_on_error": True,
"moderation_llm_v2": {
"custom_category_thresholds": {"jailbreaking": 0.1},
"action": "block",
},
}
]
def pipeline_securise(message_utilisateur: str) -> dict:
"""Pipeline avec guardrails (entrée) et modération (sortie)."""
# Étape 1 : générer avec guardrails
try:
response = client.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": message_utilisateur}],
guardrails=GUARDRAIL_JAILBREAK,
)
except errors.SDKError as e:
if e.status_code == 403:
return {"status": "blocked_input", "content": None}
raise
generated = response.choices[0].message.content
if not isinstance(generated, str):
return {"status": "error", "content": None}
# Étape 2 : modérer la sortie, dans le contexte de la question
moderation = client.classifiers.moderate_chat(
model="mistral-moderation-2603",
inputs=[
{"role": "user", "content": message_utilisateur},
{"role": "assistant", "content": generated},
],
)
scores = moderation.results[0].category_scores or {}
if max(scores.values(), default=0.0) > 0.5:
return {"status": "blocked_output", "scores": scores}
return {"status": "ok", "content": generated, "scores": scores}
Points clés à retenir
- L’API Moderation utilise le modèle
mistral-moderation-2603pour classifier le contenu - Deux modes disponibles : texte brut et conversationnel
- Les scores vont de 0.0 à 1.0 — vous définissez vos propres seuils de décision
- Le mode conversationnel est plus précis car il prend en compte le contexte
- Combinez guardrails (entrée) + modération (sortie) pour une défense en profondeur