Zum Hauptinhalt springen
Lektion 11 von 12 · KI-Moderation und Sicherheit mit Mistral

DSGVO-Konformität und Datenschutz

Lektion 11 von 12 Aktualisiert am 3. November 2026 Entwickler
Auf dieser Seite
  1. KI und personenbezogene Daten: Ein strenger Rahmen
  2. Die Kategorie PII in der Mistral-Moderation
  3. Anonymisierung vor der Verarbeitung
  4. DSGVO-konforme Moderationsprotokolle
  5. Prüfpfad für die Konformität
  6. DSGVO-Checkliste für Ihre KI-Anwendung
  7. Kernaussagen

Aktualisiert am 3. November 2026. Die Liste der durch die Kategorie pii erfassten Elemente stimmt nun mit der Definition von Mistral überein (Gesundheitsdaten unterliegen anderen Regeln, und die Kategorie health richtet sich an Anfragen nach medizinischen Ratschlägen). Der zuvor konforme Logger hat sein Ende des Aufbewahrungszeitraums falsch berechnet, was dazu führte, dass Bereinigungsvorgänge alles löschten; zudem verwendete er einen fest codierten Standard-Salzschlüssel für die Pseudonymisierung und die veraltete Funktion datetime.utcnow(). Die Pseudonymisierung verwendet nun HMAC-SHA-256 mit einem zwingenden Schlüssel. Quellen: Moderation & Guardrailing · DSGVO, Erwägungsgrund 26 und Artikel 4 und 22 · Python hmac.

KI und personenbezogene Daten: Ein strenger Rahmen

Es gibt einen Paradoxon im Kern dieser Lektion, und ein klares Verständnis desselben vermeidet viele Designfehler: Ihr Moderationssystem ist selbst eine Verarbeitung personenbezogener Daten. Um Ihre Nutzer zu schützen, analysieren Sie deren Texte, generieren Sie Bewertungen und speichern Sie Protokolle – alles Operationen, die die DSGVO genau wie jede andere Verarbeitungstätigkeit regelt.

Konformität bedeutet daher nicht, eine Schutzschicht über das Moderationssystem zu legen. Es bedeutet, das Moderationssystem selbst so zu gestalten, dass es die minimale Datenmenge verarbeitet, für den kürzest möglichen Zeitraum, während gleichzeitig ein Nachweis seiner Entscheidungen geführt wird. Dies ist das rote Faden, der durch die folgenden Abschnitte führt.

Die DSGVO (General Data Protection Regulation) gilt vollständig für KI-Anwendungen, die Daten von europäischen Bewohnern verarbeiten. Die Inhaltsmoderation selbst erzeugt Daten, die in den Geltungsbereich der DSGVO fallen. Sie müssen Ihre Verpflichtungen verstehen, um Strafen bis zu 4 % des weltweiten Jahresumsatzes zu vermeiden.

Die Kategorie PII in der Mistral-Moderation

Die Klassifizierung von Mistral in der Kategorie pii erkennt Anfragen oder Enthüllungen personenbezogener Informationen. Ein architektonischer Punkt muss sofort gemacht werden: Dieser Klassifizierer ist ein Sicherheitsnetz, keine Garantie. Er erfasst verschiedene Formulierungen, die ein Regex übersehen würde („meine Nummer ist…”), aber wie jedes Modell weist er auch falsch negative Ergebnisse auf. Umgekehrt erfasst ein Regex zuverlässig strukturierte Formate – IBANs, Sozialversicherungsnummern, Kreditkarten – aber nichts anderes. Best Practice kombiniert beides: Regex für bekannte Formate, Klassifizierer für den Rest. Erfasste Typen umfassen:

  • Vollständige Namen
  • Adressen
  • Telefonnummern
  • Sozialversicherungsnummern
  • Details zu Finanzkonten

Die Definition von Mistral konzentriert sich auf die Anfrage, das Teilen oder den Versuch, diese identifizierenden Informationen zu erhalten.

from mistralai.client import Mistral
import os
import re

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

def detect_pii(text: str) -> dict:
    """Erkennt personenbezogene Daten im Text."""
    # Ebene 1: Mistral-Klassifizierer
    response = client.classifiers.moderate(
        model="mistral-moderation-2603",
        inputs=[text]
    )
    pii_score = (response.results[0].category_scores or {}).get("pii", 0)

    # Ebene 2: Regex für gängige Muster
    pii_patterns = {
        "email": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
        "telephone_fr": r"(?:0|\+33)[1-9](?:\d{2}){4}",
        "secu_sociale": r"\d{13,15}",
        "carte_bancaire": r"\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}",
        "iban": r"FR\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{3}"
    }

    detected_pii = {}
    for name, pattern in pii_patterns.items():
        matches = re.findall(pattern, text)
        if matches:
            detected_pii[name] = len(matches)

    return {
        "score_classifieur": round(pii_score, 3),
        "pii_regex": detected_pii,
        "contient_pii": pii_score > 0.2 or len(detected_pii) > 0
    }

Anonymisierung vor der Verarbeitung

Die Anonymisierung im Vorfeld ist die kosteneffektivste Maßnahme in dieser gesamten Lektion, da sie die Natur des Problems ändert: Daten, die Ihre Infrastruktur nie verlassen, werfen keine Übertragungsprobleme auf. Das Ersetzen von Namen, E-Mails und Nummern durch Token ([PERSON_1], [EMAIL_1]) vor dem Aufruf des Modells bewahrt fast immer die Bedeutung für die Analyse – und wenn Sie die Zuordnungstabelle lokal behalten, können Sie die echten Werte in die Antwort wieder einfügen. Solange diese Tabelle existiert, handelt es sich rechtlich um Pseudonymisierung, nicht um Anonymisierung: Die Daten bleiben personenbezogen, aber die an das Modell gesendeten Daten erlauben allein keine Identifizierung der Person.

def anonymize_text(text: str) -> tuple:
    """Anonymisiert Text und behält eine Wiederherstellungszuordnung bei."""
    mapping = {}
    anonymized_text = text

    # Anonymisieren von E-Mails
    emails = re.findall(
        r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
        text
    )
    for i, email in enumerate(set(emails)):
        placeholder = f"[EMAIL_{i+1}]"
        mapping[placeholder] = email
        anonymized_text = anonymized_text.replace(email, placeholder)

    # Anonymisieren von Telefonnummern
    phones = re.findall(
        r"(?:0|\+33)[1-9](?:[\s.-]?\d{2}){4}",
        text
    )
    for i, tel in enumerate(set(phones)):
        placeholder = f"[TEL_{i+1}]"
        mapping[placeholder] = tel
        anonymized_text = anonymized_text.replace(tel, placeholder)

    # Anonymisieren von Namen (wenn von einem upstream NER erkannt)
    # Fügen Sie Ihre eigene NER-Logik hier ein

    return anonymized_text, mapping

def restore_text(anonymized_text: str, mapping: dict) -> str:
    """Stellt anonymisierte Daten nach der Verarbeitung wieder her."""
    restored_text = anonymized_text
    for placeholder, value in mapping.items():
        restored_text = restored_text.replace(placeholder, value)
    return restored_text

# Verwendung in der Pipeline
original_text = "Contactez [email protected] au 06 12 34 56 78"
anonymized_text, mapping = anonymize_text(original_text)
# → "Contactez [EMAIL_1] au [TEL_1]"

# Anonymisierten Text an das Modell senden
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": anonymized_text}]
)

DSGVO-konforme Moderationsprotokolle

Protokolle sind der klassische Blindflecken: Wir denken „personenbezogene Daten” bezüglich Nutzer-Nachrichten, aber selten bezüglich der technischen Spuren, die sie kopieren. Dennoch ist ein Moderationsprotokoll, das den analysierten Text speichert, eine personenbezogene Datenbank mit allen daraus resultierenden Verpflichtungen. Die Faustregel: Speichern Sie Text nur für blockierte Inhalte – Sie werden ihn im Streitfall benötigen – und speichern Sie nur Bewertungen für akzeptierte Inhalte.

import hashlib
import hmac
from datetime import datetime, timedelta, timezone


class LogModerationRGPD:
    """DSGVO-konformer Moderationslogger."""

    def __init__(self, retention_jours: int = 90):
        self.retention_jours = retention_jours
        # Zwingender geheimer Schlüssel, außerhalb des Codes gehalten (Vault oder Umgebungsvariable)
        self.key = os.environ["PII_HMAC_KEY"].encode()

    def _pseudonymiser(self, user_id: str) -> str:
        """Pseudonymisiert einen Benutzerkennzeichner (HMAC-SHA-256)."""
        return hmac.new(self.key, user_id.encode(), hashlib.sha256).hexdigest()[:16]

    def log_moderation(self, user_id: str, scores: dict, decision: str,
                       text: str | None = None) -> dict:
        """Verzeichnet eine Moderationsentscheidung."""
        maintenant = datetime.now(timezone.utc)
        entry = {
            "timestamp": maintenant.isoformat(),
            "user_hash": self._pseudonymiser(user_id),
            "scores": scores,
            "decision": decision,
            # Speichern Sie den vollständigen Text standardmäßig NICHT
            "texte_longueur": len(text) if text else 0,
            "conserver_jusqu_au": (maintenant + timedelta(days=self.retention_jours)).isoformat(),
        }

        # Speichern Sie Textausschnitt nur, wenn blockiert (für Prüfung)
        if decision == "blocked" and text:
            entry["texte_tronque"] = text[:200]

        return entry

    def purger_anciens_logs(self, logs: list[dict]) -> list[dict]:
        """Behält Protokolle bei, deren Aufbewahrungsfrist noch nicht abgelaufen ist."""
        maintenant = datetime.now(timezone.utc)
        return [
            log for log in logs
            if datetime.fromisoformat(log["conserver_jusqu_au"]) > maintenant
        ]

Zwei Vorsichtsmaßnahmen in diesem Code verdienen Erwähnung. Der Pseudonymisierungsschlüssel hat keinen Standardwert: Ein in den Code geschriebener Schlüssel, der allen bekannt ist, würde die Neuberechnung des Hashes für jeden Kennzeichner ermöglichen. Darüber hinaus bleiben pseudonymisierte Daten gemäß der DSGVO (Erwägungsgrund 26) personenbezogene Daten: Dieses Protokoll unterliegt weiterhin Aufbewahrungsfristen und Rechten der betroffenen Personen.

Prüfpfad für die Konformität

Der Prüfpfad beantwortet eine spezifische Frage, die ein Nutzer oder eine Behörde Ihnen stellen könnte: „Warum wurde dieser Inhalt blockiert?” Ohne eine Spur ist Ihre einzige ehrliche Antwort „Ich weiß es nicht mehr” – was angesichts der Tatsache, dass die DSGVO für vollautomatische Entscheidungen gemäß Artikel 22 die Information der Person über die zugrundeliegende Logik verlangt (Artikel 13 bis 15), und der KI-Gesetzgeber eigene Transparenzpflichten hinzufügt, nicht haltbar ist. Der Prüfpfad speichert die Entscheidung, die Bewertungen, die diese motiviert haben, und die Version der angewandten Richtlinie – ohne den Text selbst unbedingt zu speichern.

class AuditTrail:
    """Prüfpfad für Moderationsentscheidungen."""

    def __init__(self, storage_path: str):
        self.storage_path = storage_path

    def record_decision(self, data: dict) -> str:
        """Verzeichnet eine Entscheidung mit einer eindeutigen Kennung."""
        import uuid

        audit_id = str(uuid.uuid4())
        entry = {
            "audit_id": audit_id,
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "type_decision": data.get("decision"),
            "modele_moderation": "mistral-moderation-2603",
            "scores": data.get("scores"),
            "seuils_appliques": data.get("seuils"),
            "politique_version": data.get("politique_version"),
            "action_prise": data.get("action"),
            "base_legale": "interet_legitime",
            "responsable": "systeme_automatise"
        }

        # Schreiben in Audit-Datei
        import json
        with open(self.storage_path, "a") as f:
            f.write(json.dumps(entry, ensure_ascii=False) + "\n")

        return audit_id

DSGVO-Checkliste für Ihre KI-Anwendung

Hier sind die Punkte zur Überprüfung, um sicherzustellen, dass Ihr Moderationssystem konform ist:

Rechtliche Grundlage

  • Dokumentiertes berechtigtes Interesse an der Inhaltsmoderation
  • Benachrichtigung des Nutzers über automatisierte Verarbeitung
  • Möglichkeit, eine automatisierte Entscheidung anzufechten

Datenminimierung

  • Speichern Sie nur streng notwendige Daten
  • Anonymisieren oder pseudonymisieren Sie Benutzerkennzeichner
  • Kürzen Sie Texte in Moderationsprotokollen
  • Behalten Sie akzeptierte Texte nicht (nur Bewertungen)

Aufbewahrungsfrist

  • Definieren Sie eine Aufbewahrungsfrist für jede Datentyp
  • Moderationsprotokolle: maximal 90 Tage (es sei denn, eine gesetzliche Verpflichtung verlangt anderes)
  • Prüfpfad: gemäß sektoraler Verordnung
  • Geplante automatische Bereinigung

Rechte der Nutzer

  • Recht auf Zugang zu Moderationsentscheidungen, die sie betreffen
  • Recht auf Berichtigung, wenn die Entscheidung angefochten wird
  • Recht auf Erklärung der automatisierten Entscheidung

Kernaussagen

  • Die DSGVO gilt vollständig für Ihre KI-Moderationssysteme
  • Verwenden Sie die Kategorie pii von Mistral UND Regex, um personenbezogene Daten zu erkennen
  • Anonymisieren Sie Texte, bevor Sie sie an das Modell senden, wenn möglich
  • Pseudonymisieren Sie Benutzerkennzeichner in Protokollen
  • Implementieren Sie einen Prüfpfad für die Nachverfolgbarkeit von Entscheidungen
  • Definieren Sie eine Aufbewahrungsfrist und bereinigen Sie Protokolle automatisch