Aller au contenu principal

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

AspectCustom GuardrailsModeration API
TimingAVANT la générationAPRÈS la génération
ActionBloque automatiquement (403)Retourne des scores (vous décidez)
ContrôleSeuils prédéfinisScores bruts, logique libre
LatenceAjoutée à chaque requêteAppel séparé
Cas d’usageFiltrer les prompts dangereuxClassifier 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-2603 pour 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