Aller au contenu principal

L'API Moderation d'OpenAI

Un outil de modération intégré

OpenAI fournit une API de modération gratuite qui analyse le texte pour détecter du contenu potentiellement dangereux. C’est la première ligne de défense à intégrer dans toute application utilisant les modèles OpenAI — et elle fonctionne aussi pour filtrer les entrées vers d’autres modèles.

Fonctionnement de l’API Moderation

Appel de base

from openai import OpenAI

client = OpenAI()

def moderer_contenu(texte: str) -> dict:
    """Analyse un texte via l'API Moderation d'OpenAI."""
    response = client.moderations.create(input=texte)
    result = response.results[0]

    return {
        "bloque": result.flagged,
        "categories": {
            cat: flagged
            for cat, flagged in result.categories.__dict__.items()
            if flagged
        },
        "scores": {
            cat: round(score, 4)
            for cat, score in result.category_scores.__dict__.items()
            if score > 0.01
        },
    }

# Test avec différents contenus
exemples = [
    "Comment cuisiner un gâteau au chocolat ?",
    "Je vais te tuer si tu ne me réponds pas",
    "Explique-moi comment fonctionne le chiffrement AES",
]

for texte in exemples:
    resultat = moderer_contenu(texte)
    statut = "BLOQUÉ" if resultat["bloque"] else "OK"
    print(f"{statut} : {texte[:50]}...")
    if resultat["categories"]:
        print(f"  Catégories : {list(resultat['categories'].keys())}")

Catégories de modération

L’API détecte plusieurs catégories de contenu problématique :

Catégorie Description
harassment Harcèlement, menaces, intimidation
hate Discours haineux basé sur l'identité
self-harm Automutilation, suicide
sexual Contenu sexuel explicite
violence Violence graphique, menaces

Chaque catégorie a aussi des sous-catégories (ex: harassment/threatening, violence/graphic) pour un filtrage plus fin.

Modération par lots

def moderer_lot(messages: list[str]) -> list[dict]:
    """Modère plusieurs messages en un seul appel."""
    response = client.moderations.create(input=messages)
    resultats = []
    for i, result in enumerate(response.results):
        resultats.append({
            "index": i,
            "texte": messages[i][:50],
            "bloque": result.flagged,
            "score_max": max(
                score
                for score in result.category_scores.__dict__.values()
            ),
        })
    return resultats

Intégration dans un pipeline

Architecture complète de modération

class PipelineModeration:
    """Pipeline de modération entrée + sortie pour une application LLM."""

    def __init__(self, seuil_custom: float = 0.7):
        self.client = OpenAI()
        self.seuil = seuil_custom

    def moderer_entree(self, message: str) -> tuple[bool, dict]:
        """Modère le message AVANT envoi au modèle."""
        result = self.client.moderations.create(input=message).results[0]
        scores = result.category_scores.__dict__
        categories_elevees = {
            cat: score for cat, score in scores.items() if score > self.seuil
        }
        bloque = result.flagged or bool(categories_elevees)
        return bloque, {"flagged_api": result.flagged, "categories_custom": categories_elevees}

    def moderer_sortie(self, reponse: str) -> tuple[bool, dict]:
        """Modère la réponse du modèle AVANT envoi à l'utilisateur."""
        return self.moderer_entree(reponse)

    def traiter_message(self, message_utilisateur: str, prompt_systeme: str) -> str:
        """Pipeline complet : modération entrée, LLM, modération sortie."""
        # Étape 1 : modérer l'entrée
        bloque_entree, details = self.moderer_entree(message_utilisateur)
        if bloque_entree:
            return "Votre message ne peut pas être traité. Veuillez le reformuler."

        # Étape 2 : appeler le modèle
        response = self.client.chat.completions.create(
            model="gpt-5.4",
            messages=[
                {"role": "system", "content": prompt_systeme},
                {"role": "user", "content": message_utilisateur},
            ],
        )
        reponse_modele = response.choices[0].message.content

        # Étape 3 : modérer la sortie
        bloque_sortie, _ = self.moderer_sortie(reponse_modele)
        if bloque_sortie:
            return "La réponse a été filtrée pour non-conformité."

        return reponse_modele

# Utilisation
pipeline = PipelineModeration(seuil_custom=0.5)
reponse = pipeline.traiter_message(
    "Comment protéger mon application contre les injections SQL ?",
    "Vous êtes un expert en cybersécurité défensive."
)
print(reponse)

Limites de l’API Moderation

  • Pas de détection de prompt injection — elle ne détecte que le contenu offensant, pas les tentatives de manipulation
  • Faux positifs — le contexte sécurité ou médical peut être faussement flaggé
  • Latence — ajoute un appel réseau supplémentaire à chaque requête
  • Anglais prioritaire — la détection est moins fiable dans d’autres langues
  • Évolution — les catégories et seuils changent au fil des mises à jour

Bonnes pratiques

  1. Modérez les deux sens — entrées ET sorties
  2. Ajustez les seuils par catégorie selon votre cas d’usage
  3. Combinez avec d’autres couches de défense (détection d’injection, filtrage métier)
  4. Journalisez les résultats pour améliorer vos seuils dans le temps
  5. Gérez les erreurs — l’API peut être indisponible, prévoyez un fallback

Points clés à retenir

  • L’API Moderation est gratuite, rapide et simple à intégrer
  • Elle détecte le contenu offensant mais pas les injections ni les jailbreaks
  • Le pipeline entrée vers modèle vers sortie doit être modéré aux deux extrémités
  • Les seuils par défaut conviennent rarement — adaptez-les à votre contexte
  • C’est une couche parmi d’autres, jamais la seule ligne de défense