Aller au contenu principal

Configurer les guardrails en Python

Mis à jour le 29 juillet 2026

Passer de la théorie au code

Vous connaissez maintenant le principe des guardrails. Dans cette leçon, vous allez apprendre à les configurer précisément : choisir vos catégories, définir vos seuils, et gérer les réponses de blocage dans votre code Python. Le travail réel de sécurisation se joue ici, dans quelques dizaines de lignes que vous relirez plus souvent que le reste de votre application.

Le point de départ tient en deux commandes : le SDK Mistral installé, et une clé d’API lue depuis l’environnement plutôt qu’écrite dans le code.

pip install mistralai
from mistralai import Mistral
import os

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

Le paramètre guardrails en détail

Le paramètre guardrails accepte un dictionnaire avec quatre clés principales : enabled active le mécanisme, custom_category_thresholds porte vos seuils par catégorie, action indique quoi faire en cas de dépassement, et block_on_error définit le comportement quand le classifieur lui-même est indisponible.

guardrails = {
    # Activer les guardrails
    "enabled": True,

    # Seuils personnalisés par catégorie (0.0 à 1.0)
    "custom_category_thresholds": {
        "sexual": 0.2,
        "hate": 0.1,
        "violence": 0.3,
        "criminal": 0.1,
        "selfharm": 0.1,
        "health": 0.5,
        "financial": 0.5,
        "law": 0.5,
        "pii": 0.2,
        "jailbreaking": 0.1,
        "unpredictable": 0.3
    },

    # Action à effectuer
    "action": "block",

    # Bloquer si le classifieur est indisponible
    "block_on_error": True
}

custom_category_thresholds

C’est le coeur de la configuration. Chaque catégorie reçoit un seuil entre 0.0 (tout bloquer) et 1.0 (tout laisser passer). Un seuil bas, entre 0.1 et 0.2, rend le filtre très restrictif : il bloque au moindre doute, quitte à écarter des requêtes légitimes. Un seuil moyen, de 0.3 à 0.5, cherche l’équilibre et ne bloque que le contenu clairement problématique. Au-delà, entre 0.6 et 0.8, vous devenez permissif : seul le contenu explicite est arrêté.

Ces valeurs n’ont de sens que rapportées à votre application. Un chatbot ouvert au grand public verrouille tout au plus bas, alors qu’un outil interne destiné à des professionnels de santé doit au contraire laisser passer les discussions médicales tout en restant intransigeant sur les données personnelles des patients.

# Chatbot grand public : seuils très bas
public_thresholds = {
    "sexual": 0.1,
    "hate": 0.1,
    "violence": 0.1,
    "criminal": 0.1,
    "selfharm": 0.1
}

# Outil interne médical : plus permissif sur la santé
medical_thresholds = {
    "sexual": 0.2,
    "hate": 0.1,
    "violence": 0.3,
    "health": 0.8,  # Permet les discussions médicales
    "pii": 0.1       # Mais strict sur les données personnelles
}

ignore_other_categories

Par défaut, toutes les 11 catégories sont évaluées. Si vous ne spécifiez des seuils que pour certaines catégories, les autres utilisent les seuils par défaut — vous restez donc couvert sur l’ensemble du spectre. Pour n’évaluer que vos catégories spécifiées, il faut le demander explicitement.

guardrails = {
    "enabled": True,
    "custom_category_thresholds": {
        "hate": 0.1,
        "violence": 0.2
    },
    "ignore_other_categories": True,  # Ignore les 9 autres
    "action": "block"
}

Attention : utiliser ignore_other_categories: True désactive la protection sur les catégories non listées. Ne l’utilisez que si vous avez une raison précise. Dans l’exemple ci-dessus, une tentative de jailbreak ou une demande de données personnelles passerait sans obstacle.

Exemple complet : chatbot avec guardrails

Voici une fonction de production minimale : elle envoie un message avec l’ensemble des seuils renseignés, journalise les scores retournés et transforme un blocage en réponse lisible pour l’utilisateur.

from mistralai import Mistral
import os

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

def chat_securise(user_message: str) -> str:
    """Envoie un message avec guardrails activés."""
    try:
        response = client.chat.complete(
            model="mistral-large-latest",
            messages=[
                {
                    "role": "system",
                    "content": "Vous êtes un assistant professionnel."
                },
                {
                    "role": "user",
                    "content": user_message
                }
            ],
            guardrails={
                "enabled": True,
                "custom_category_thresholds": {
                    "sexual": 0.2,
                    "hate": 0.1,
                    "violence": 0.2,
                    "criminal": 0.1,
                    "selfharm": 0.1,
                    "health": 0.4,
                    "financial": 0.4,
                    "law": 0.4,
                    "pii": 0.2,
                    "jailbreaking": 0.1,
                    "unpredictable": 0.3
                },
                "action": "block",
                "block_on_error": True
            }
        )

        # Récupérer les scores de modération
        if hasattr(response, "guardrails"):
            print(f"Scores: {response.guardrails}")

        return response.choices[0].message.content

    except Exception as e:
        if "403" in str(e):
            return "Désolé, cette requête ne peut pas être traitée."
        raise

# Utilisation
print(chat_securise("Expliquez-moi le machine learning"))
# → Réponse normale avec scores

print(chat_securise("Comment pirater un système ?"))
# → "Désolé, cette requête ne peut pas être traitée."

Gérer les erreurs de blocage proprement

L’interception par sous-chaîne "403" convient à un script de démonstration, pas à un service en production. Il faut distinguer les cas : un blocage par politique de contenu et une indisponibilité du classifieur n’appellent ni le même message ni la même alerte côté exploitation.

from mistralai import Mistral
from mistralai.models import SDKError

def chat_avec_gestion_erreurs(user_message: str) -> dict:
    """Chat avec gestion complète des erreurs guardrails."""
    try:
        response = client.chat.complete(
            model="mistral-large-latest",
            messages=[{"role": "user", "content": user_message}],
            guardrails={
                "enabled": True,
                "custom_category_thresholds": {
                    "hate": 0.1,
                    "violence": 0.2,
                    "jailbreaking": 0.1
                },
                "action": "block",
                "block_on_error": True
            }
        )
        return {
            "status": "ok",
            "content": response.choices[0].message.content,
            "guardrails": getattr(response, "guardrails", None)
        }

    except SDKError as e:
        if e.status_code == 403:
            return {
                "status": "blocked",
                "content": "Votre message a été bloqué par notre "
                           "politique de sécurité.",
                "reason": str(e)
            }
        elif e.status_code == 3201:
            return {
                "status": "error",
                "content": "Service de modération indisponible. "
                           "Requête bloquée par précaution."
            }
        raise

Bonnes pratiques de configuration

Démarrez restrictif, puis desserrez. Des seuils bas au lancement vous font découvrir vos faux positifs sur un volume encore maîtrisable, et chaque relèvement se décide alors sur des cas observés plutôt que sur une intuition. La progression ressemble à ceci : lancement très serré, ajustement après analyse des blocages injustifiés, puis stabilisation.

# Phase 1 : Lancement (très restrictif)
phase1 = {"hate": 0.1, "violence": 0.1, "criminal": 0.1}

# Phase 2 : Après analyse des faux positifs
phase2 = {"hate": 0.15, "violence": 0.25, "criminal": 0.1}

# Phase 3 : Production stable
phase3 = {"hate": 0.2, "violence": 0.3, "criminal": 0.15}

Gardez block_on_error activé en production : si le classifieur tombe, mieux vaut bloquer que laisser passer du contenu non vérifié. Et conservez les scores de modération de chaque requête — ce sont eux qui alimenteront les ajustements de la phase suivante et vous permettront de repérer une dérive avant qu’un utilisateur ne la signale.

Points clés à retenir

  • Le paramètre guardrails se configure avec 4 clés : enabled, custom_category_thresholds, action, block_on_error
  • Les seuils vont de 0.0 (tout bloquer) à 1.0 (tout accepter)
  • Interceptez les erreurs 403 pour fournir une réponse utilisateur claire
  • Commencez restrictif et ajustez selon les faux positifs
  • block_on_error: True est obligatoire en production