Moderation Scores and Thresholds
Auf dieser Seite
Aktualisiert am 3. November 2026. Die zuvor verwendeten Profilreferenzen bezogen sich auf nicht existierende Kategorien (
hate,violence,unpredictable); sie stimmen nun mit den elf Schlüsseln vonmistral-moderation-2603überein, einschließlichdangerous. Die Anleitung zur Interpretation der Scores dient als Trainingsreferenz, da Mistral diese nicht veröffentlicht. Der Monitor hob zuvor für jede Kategorie an, die im Profil fehlte, eineKeyErrorauf und verwendetedatetime.utcnow(), was seit Python 3.12 veraltet ist. Quellen: Moderation & Guardrailing · datetime.utcnow.
Interpretation von Moderation Scores
Jede Kategorie liefert einen Score zwischen 0,0 und 1,0. Was bedeuten diese Zahlen jedoch wirklich? Und wie setzen Sie Entscheidungsschwellen für Ihre Anwendung? Diese Lektion gibt Ihnen die Schlüssel, um aus rohen Scores automatisierte Entscheidungen zu ableiten – vom Messen zur Politik.
Verstehen Sie zunächst, dass Mistral diese Scores nicht als kalibrierte Wahrscheinlichkeiten darstellt. Ein Score von 0,6 bedeutet nicht „eine Sechs-zu-Zehn-Chance, dass dieser Text gefährlich ist”; es ist ein starkes Signal des Klassifizierers. Die Dokumentation hebt zwei nützliche Punkte hervor. Die booleschen categories in der Antwort wenden Schwellenwerte an, die Mistral für optimale Leistung auf seinem internen Testdatensatz gewählt hat; Sie können diese verwenden oder von den rohen Scores ausgehend Ihre eigenen festlegen. Auf diesem Testdatensatz liegt die Kategorie-Präzision zwischen 0,8 und 1,0 und die Recall zwischen 0,7 und 1,0: Falsch-Positivs und übersehene Inhalte treten auf, weshalb manuell justierte Schwellenwerte von Bedeutung sind.
Das untenstehende Raster wurde nicht von Mistral veröffentlicht: Es dient als Ausgangspunkt, um es gegen Ihre eigenen Metriken zu validieren.
| Bereich | Interpretation |
|---|---|
| 0,0 - 0,1 | Offensichtlich sicherer Inhalt, kein Signal erkannt |
| 0,1 - 0,3 | Schwaches Signal, möglicherweise harmlos, aber mehrdeutig |
| 0,3 - 0,5 | Mäßiges Signal, potenziell problematischer Inhalt |
| 0,5 - 0,7 | Starkes Signal, sehr wahrscheinlich problematischer Inhalt |
| 0,7 - 1,0 | Sehr starkes Signal, offensichtlich gefährlicher Inhalt |
Definition Ihrer Schwellenwerte: Die Entscheidungsmatrix
Die Wahl einer Schwelle ist ein Kompromiss zwischen Sicherheit (so viel wie möglich blockieren) und Benutzbarkeit (Minimierung von Falsch-Positivs). Keine Einstellung gewinnt auf beiden Fronten, und Behauptungen, dies zu tun, führen zu endlosem Hin- und Her. Die Arbeitsmethode besteht darin, drei explizite Profile zu definieren und jede Anwendung einem dieser zuzuordnen.
Das strenge Profil zielt auf eine Konsumenten-Anwendung ab, bei der Minderjährige anwesend sein können; das ausgewogene Profil passt zu einer B2B-professionellen Anwendung mit identifizierten Nutzern; das nachsichtige Profil ist für ein internes Werkzeug vorbehalten, das von Experten verwaltet wird, die wissen, wonach sie suchen.
# Drei Schwellenwertprofile
PROFILES = {
"strict": {
# Konsumenten-Anwendung, Kinder möglich
"sexual": 0.1,
"hate_and_discrimination": 0.1,
"violence_and_threats": 0.1,
"dangerous": 0.1,
"criminal": 0.1,
"selfharm": 0.1,
"health": 0.2,
"financial": 0.2,
"law": 0.2,
"pii": 0.1,
"jailbreaking": 0.1,
},
"balanced": {
# B2B-professionelle Anwendung
"sexual": 0.2,
"hate_and_discrimination": 0.15,
"violence_and_threats": 0.25,
"dangerous": 0.15,
"criminal": 0.15,
"selfharm": 0.15,
"health": 0.4,
"financial": 0.4,
"law": 0.4,
"pii": 0.2,
"jailbreaking": 0.15,
},
"permissive": {
# Internes Werkzeug für Experten
"sexual": 0.3,
"hate_and_discrimination": 0.2,
"violence_and_threats": 0.4,
"dangerous": 0.2,
"criminal": 0.2,
"selfharm": 0.2,
"health": 0.7,
"financial": 0.7,
"law": 0.7,
"pii": 0.3,
"jailbreaking": 0.2,
},
}
Vergleichen Sie die health-Spalte über die Profile hinweg: 0,2, dann 0,4, dann 0,7. Der gleiche Austausch über Dosierung wird im ersten Fall blockiert und im letzten akzeptiert. Der Nutzungskontext entscheidet, nicht die Natur des Textes.
Mehrstufiges Klassifizierungssystem
Blockieren oder Akzeptieren ist eine vereinfachte Sicht auf die Realität. Zwischen offensichtlich sicherem Inhalt und offensichtlich verletzendem Inhalt liegt eine Grauzone, in der die richtige Entscheidung besteht, den Inhalt anzuzeigen, aber zu markieren. Die folgende Funktion führt diesen dritten Zustand ein: oberhalb der Schwelle blockieren; oberhalb von 60 % der Schwelle warnen und protokollieren; darunter durchlassen.
from enum import Enum
class RiskLevel(Enum):
SAFE = "safe" # Grün: sicherer Inhalt
WARNING = "warning" # Orange: Inhalt zur Überwachung
BLOCKED = "blocked" # Rot: blockierter Inhalt
def classify_content(scores: dict, thresholds: dict) -> dict:
"""Klassifiziert Inhalte in drei Risikostufen."""
blocking_violations = []
warnings = []
for category, threshold in thresholds.items():
score = scores.get(category, 0)
if score > threshold:
blocking_violations.append({
"category": category,
"score": round(score, 3)
})
elif score > threshold * 0.6:
# Warnzone: 60 % der Schwelle
warnings.append({
"category": category,
"score": round(score, 3)
})
if blocking_violations:
return {
"level": RiskLevel.BLOCKED,
"violations": blocking_violations,
"action": "block_and_log"
}
elif warnings:
return {
"level": RiskLevel.WARNING,
"warnings": warnings,
"action": "display_and_log"
}
else:
return {
"level": RiskLevel.SAFE,
"action": "display"
}
Der Wert der orangen Zone ist sowohl operativ als auch lehrreich: Sie zeigt Ihnen, was an Ihren Schwellenwerten vorbeizieht. Wenn eine Kategorie viele Warnungen generiert, ohne die Linie zu überschreiten, wissen Sie, dass eine Anpassung um einige Hundertstel einen erheblichen Teil des Verkehrs verschieben würde.
Arbeitsbeispiel: Analysieren und Entscheiden
Die Zusammenfassung reduziert sich auf eine Funktion: den Klassifizierer aufrufen, das Profil anwenden und die Entscheidung treffen. Der folgende Vergleich dient als Demonstration – eine Paracetamol-Dosierung wird im strengen Profil unter health blockiert und im nachsichtigen Profil akzeptiert, ohne dass sich eine einzige Zeile Text ändert.
from mistralai.client import Mistral
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
def moderate_and_decide(text: str, profile: str = "balanced") -> dict:
"""Moderiert Text und trifft eine Entscheidung basierend auf dem Profil."""
# Aufruf der Moderations-API
response = client.classifiers.moderate(
model="mistral-moderation-2603",
inputs=[text]
)
scores = response.results[0].category_scores or {}
# Anwendung der Profil-Schwellenwerte
thresholds = PROFILES[profile]
classification = classify_content(scores, thresholds)
return {
"text": text[:80],
"profile": profile,
"raw_scores": {k: round(v, 3) for k, v in scores.items()},
"decision": classification
}
# Test mit verschiedenen Profilen
text = "Take 2 paracetamol tablets every 6 hours"
# Strenges Profil: wahrscheinlich blockiert (health)
result_strict = moderate_and_decide(text, "strict")
# Nachsichtiges Profil: wahrscheinlich akzeptiert
result_permissive = moderate_and_decide(text, "permissive")
Dynamische Anpassung von Schwellenwerten
In der Produktion müssen Ihre Schwellenwerte sich entwickeln, und Sie steuern diese Entwicklung mit Daten. Der Monitor unten schreibt jede Entscheidung in eine JSONL-Datei und hält Zähler für Blockierungen, Warnungen und Durchläufe pro Kategorie aufrecht. Der resultierende Bericht gibt Ihnen die Blockquote pro Kategorie – die einzige Metrik, die Ihnen sagt, ob eine Schwelle zu niedrig ist.
import json
from datetime import datetime, timezone
class ModerationMonitor:
"""Sammelt Moderationsmetriken zur Anpassung von Schwellenwerten."""
def __init__(self, log_file: str = "moderation_logs.jsonl"):
self.log_file = log_file
self.stats = {cat: {"blocked": 0, "warned": 0, "passed": 0}
for cat in PROFILES["balanced"].keys()}
def log_decision(self, scores: dict, thresholds: dict, decision: str):
"""Protokolliert eine Moderationsentscheidung."""
entry = {
"timestamp": datetime.now(timezone.utc).isoformat(),
"scores": scores,
"thresholds": thresholds,
"decision": decision
}
with open(self.log_file, "a") as f:
f.write(json.dumps(entry) + "\n")
# Aktualisiere Zähler
for cat, threshold in thresholds.items():
score = scores.get(cat, 0.0)
self.stats.setdefault(cat, {"blocked": 0, "warned": 0, "passed": 0})
if score > threshold:
self.stats[cat]["blocked"] += 1
elif score > threshold * 0.6:
self.stats[cat]["warned"] += 1
else:
self.stats[cat]["passed"] += 1
def report(self) -> dict:
"""Generiert einen Bericht zur Anpassung von Schwellenwerten."""
report = {}
for cat, stats in self.stats.items():
total = sum(stats.values())
if total > 0:
report[cat] = {
"block_rate": round(stats["blocked"] / total, 3),
"warning_rate": round(stats["warned"] / total, 3),
"total": total
}
return report
Zu vermeidende Fallstricke
Der erste Fallstrick ist eine einzelne Schwelle, die auf alle Kategorien angewendet wird. Jede Kategorie hat ihre eigene Score-Verteilung: Eine Schwelle von 0,3 für hate_and_discrimination bedeutet nicht dasselbe wie 0,3 für health, wo legitimer Inhalt natürlicherweise höher auf der Skala liegt. Passen Sie jede Kategorie einzeln an, auch wenn das bedeutet, elf Entscheidungen statt einer zu treffen.
Der zweite ist das Ignorieren von Falsch-Positivs. Eine hohe Blockquote untergräbt das Nutzervertrauen viel schneller als ein isolierter Vorfall, da sie Menschen betrifft, die in gutem Glauben handeln. Verfolgen Sie die Blockquote pro Kategorie und erhöhen Sie die Schwellenwerte, wenn die Daten dies rechtfertigen.
Der dritte, heimtückischere, ist das Versäumnis, Entscheidungen zu protokollieren. Ohne Protokolle können Sie Ihre Schwellenwerte nicht informiert anpassen und fallen auf Meinungsbesprechungen zurück. Protokollieren Sie systematisch Scores, angewandte Schwellenwerte und getroffene Entscheidungen – dieser Korpus ist es, der die nächste Revision schnell und unanfechtbar macht.
Kernaussagen
- Scores reichen von 0,0 bis 1,0; sie sind keine kalibrierten Wahrscheinlichkeiten, und Mistral empfiehlt, Ihre eigenen Schwellenwerte festzulegen
- Definieren Sie Schwellenwertprofile, die an Ihren Kontext angepasst sind (streng, ausgewogen, nachsichtig)
- Implementieren Sie ein 3-Stufen-System: sicher, Warnung, blockiert
- Protokollieren Sie alle Entscheidungen, um Ihre Schwellenwerte kontinuierlich anzupassen
- Jede Kategorie erfordert ihren eigenen Schwellenwert – kein einzelner Wert passt allen