L'API Moderation de Mistral
Mis à jour le 29 juillet 2026
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 (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. Cette spécialisation le rend rapide, ce qui compte quand vous l’appelez sur chaque réponse produite.
Il analyse simultanément 11 catégories de contenu et retourne pour chacune un score continu de 0.0 à 1.0. 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.
L’endpoint /v1/moderations
Le mode texte brut est le plus simple : vous envoyez un ou plusieurs textes à classifier, sans autre contexte.
from mistralai 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"Scores santé : {result.category_scores.get('health', 0)}")
Le mode conversationnel est plus précis car il prend en compte le contexte de l’échange. Un même texte peut avoir 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 selon les seuils par défaut de Mistral, et category_scores, les scores bruts de 0.0 à 1.0. 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": false,
"violence": false,
"criminal": false,
"selfharm": false,
"health": true,
"financial": false,
"law": false,
"pii": false,
"jailbreaking": false,
"unpredictable": false
},
"category_scores": {
"sexual": 0.01,
"hate": 0.02,
"violence": 0.03,
"criminal": 0.01,
"selfharm": 0.01,
"health": 0.72,
"financial": 0.05,
"law": 0.08,
"pii": 0.02,
"jailbreaking": 0.01,
"unpredictable": 0.04
}
}
]
}
Dans cet exemple, seul health dépasse le seuil par défaut, 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):
max_score = max(result.category_scores.values())
max_cat = max(result.category_scores, key=result.category_scores.get)
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 | Seuils prédéfinis | Scores bruts, logique libre |
| Latence | Ajoutée à chaque requête | Appel séparé |
| 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 sortie est ensuite classifiée, 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.
def pipeline_securise(user_message: str) -> dict:
"""Pipeline avec guardrails + modération."""
# Étape 1 : Générer avec guardrails
try:
response = client.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": user_message}],
guardrails={
"enabled": True,
"custom_category_thresholds": {"jailbreaking": 0.1},
"action": "block",
"block_on_error": True
}
)
except Exception as e:
if "403" in str(e):
return {"status": "blocked_input", "content": None}
raise
generated = response.choices[0].message.content
# Étape 2 : Modérer la sortie
moderation = client.classifiers.moderate(
model="mistral-moderation-2603",
inputs=[generated]
)
scores = moderation.results[0].category_scores
max_score = max(scores.values())
if max_score > 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