Zum Hauptinhalt springen
Lektion 12 von 12 · Bildgenerierung über die API: GPT Image

Moderation und Sicherheit visueller Inhalte

Lektion 12 von 12 Aktualisiert am 3. November 2026 Entwickler
Auf dieser Seite
  1. Moderation und Sicherheit visueller Inhalte
  2. Das integrierte Moderationssystem
  3. Vorfilterung von Prompts
  4. Auch generierte Bilder prüfen
  5. Wenn Nutzer die Prompts schreiben
  6. Protokollierung zur Rechenschaftspflicht
  7. Urheberrecht und Markenrechte
  8. DSGVO-Konformität
  9. Bevor Sie die Schleusen öffnen
  10. Wissen testen

Aktualisiert am 3. November 2026 basierend auf dem OpenAI-Leitfaden Image generation: Eine Moderationsablehnung wird durch error.code == "moderation_blocked" identifiziert, optionally mit einem moderation_details-Objekt, nicht durch das Vorhandensein der Wörter safety oder content_policy in der Fehlermeldung; hinzugefügt wurde der moderation-Parameter (auto, low). Quelle: Image generation.

Aktualisierung vom 2. November 2026 — Bildmodelle. gpt-image-1, auf dem dieser Kurs ursprünglich basierte, wurde am 23. Oktober 2026 eingestellt, und gpt-image-1.5, gpt-image-1-mini sowie chatgpt-image-latest werden am 1. Dezember 2026 zurückgezogen. Die Beispiele verwenden nun gpt-image-2.5-sunburst, das für Bearbeitungen am präzisesten ist; gpt-image-2.5-flare ist für Standardgenerierungen schneller. Beide Modelle akzeptieren zudem die Qualitäten xhigh und max. GPT-Bildmodelle geben das Bild stets im Base64-Format zurück: Der Parameter response_format von älteren DALL·E-Modellen wird nicht akzeptiert und aus dem Code entfernt. Quelle: Image generation (OpenAI).

Moderation und Sicherheit visueller Inhalte

Solange Sie Bilder nur für sich selbst generieren, ist Moderation eine Frage der persönlichen Einschätzung. Sobald Sie die Generierung für Nutzer öffnen, wird es zu einer rechtlichen und ethischen Verantwortung, die Sie bindet. Diese Lektion behandelt die Moderationswerkzeuge von OpenAI, wie man sie in aufeinanderfolgende Filterketten einbindet, und die Maßnahmen, die sowohl Ihre Anwendung als auch die Nutzer schützen.

Das integrierte Moderationssystem

GPT Image lehnt bestimmte Inhalte von sich aus ab – Gewalt, sexuell explizites Material und anderes mehr – und signalisiert diese Ablehnung mit einem spezifischen Fehler. Ihr Code muss daher eine Ablehnung aufgrund der Inhaltsrichtlinien von einem technischen Fehler unterscheiden, da beide gegensätzliche Reaktionen erfordern: Erstere führt zu einer Nachricht an den Nutzer, letztere zu einem Alarm für Ihr Team. Die Dokumentation von OpenAI gibt den zu verwendenden Unterscheider vor: Eine Moderationsablehnung kommt als BadRequestError mit error.code gleich moderation_blocked (Typ image_generation_user_error) an, und der Fehlerkörper kann ein moderation_details-Objekt enthalten, das die Stufe (input, output oder unknown) und allgemeine Kategorien (harassment, sexual, violence…) spezifiziert. Suchen Sie nicht nach Wörtern in der Fehlermeldung: Der Text ist kein Vertrag, der Code schon. Die folgende Funktion wirft die Ausnahme nur auf, wenn es sich nicht um eine Moderationsablehnung handelt.

from openai import OpenAI, BadRequestError

client = OpenAI()

def generate_with_moderation(prompt: str, output: str) -> dict:
    """Generates an image while handling moderation refusals."""
    try:
        response = client.images.generate(
            model="gpt-image-2.5-sunburst",
            prompt=prompt,
            size="1024x1024",
            quality="medium",
        )

        import base64
        data = base64.b64decode(response.data[0].b64_json)
        with open(output, "wb") as f:
            f.write(data)

        return {"status": "ok", "path": output}

    except BadRequestError as e:
        if e.code != "moderation_blocked":
            raise  # technical failure, quota, invalid request: handle elsewhere
        body = e.body if isinstance(e.body, dict) else {}
        details = body.get("moderation_details") or {}
        return {
            "status": "refused",
            "reason": "Content refused by safety policy",
            "stage": details.get("moderation_stage"),        # input, output or unknown
            "categories": details.get("categories") or [],  # for your logs
        }


result = generate_with_moderation(
    "A kitten playing with a ball of yarn",
    "kitten.png"
)
print(result)

OpenAI rät, eine generische Nachricht für den Endnutzer zu verwenden und moderation_details für Ihre Protokolle und den Support vorzubehalten. Diese Fehler lösen sich nicht durch einen Neustart: Ohne Änderung des Prompts oder der bereitgestellten Bilder wird derselbe Antrag erneut abgelehnt. Beachten Sie abschließend, dass die Filterung der Schweregrad durch den moderation-Parameter der GPT Image-Modelle festgelegt wird: auto (Standardfilterung, Standard) oder low (weniger restriktiv).

Vorfilterung von Prompts

Es ist unbefriedigend, auf die Ablehnung eines Prompts durch GPT Image zu warten, um festzustellen, dass es problematisch war: Sie haben bereits den API-Aufruf verbraucht und erfahren nichts Spezifisches über den Grund. Die Moderations-API ist jedoch kostenlos, schnell und liefert benannte Kategorien. Der Aufruf vor der Generierung ermöglicht es Ihnen, sauber abzulehnen, dem Nutzer zu erklären, was markiert wurde, und diese Informationen für Ihre Prüfung aufzubewahren. Die Funktion verify_prompt extrahiert die Liste der ausgelösten Kategorien, und generate_safe_image verknüpft einfach die beiden Schritte: zuerst prüfen, dann generieren.

from openai import OpenAI

client = OpenAI()

def verify_prompt(prompt: str) -> dict:
    """Checks a prompt with the Moderation API before generation."""
    moderation = client.moderations.create(
        model="omni-moderation-latest",
        input=prompt
    )

    result = moderation.results[0]

    if result.flagged:
        categories_flagged = [
            cat for cat, flagged in result.categories.__dict__.items()
            if flagged
        ]
        return {
            "allowed": False,
            "categories": categories_flagged,
            "message": "This prompt was flagged by the moderation system."
        }

    return {"allowed": True}


def generate_safe_image(prompt: str, output: str):
    """Complete pipeline: moderation + generation."""
    # Step 1: pre-filtering
    check = verify_prompt(prompt)

    if not check["allowed"]:
        print(f"Prompt refused: {check['message']}")
        print(f"Categories: {check['categories']}")
        return None

    # Step 2: generation
    print("Prompt validated, generating...")
    return generate_with_moderation(prompt, output)


# Test with a harmless prompt
generate_safe_image(
    "A mountain landscape with a crystal clear lake",
    "mountain.png"
)

Auch generierte Bilder prüfen

Ein harmloser Prompt kann ein Bild ergeben, das es nicht ist. Eine umständliche Formulierung, die Mehrdeutigkeit eines Begriffs oder einfach eine unglückliche Modellinterpretation reicht aus, um visuelle Inhalte zu produzieren, die Sie nicht unter Ihrem Logo anzeigen möchten. Das Modell omni-moderation-latest akzeptiert Bilder als Eingabe, sodass Sie den Kreis schließen können: Die gleichen Kategorienmechaniken gelten für die generierte Datei. Die vollständige Pipeline unten verknüpft die drei Phasen – Prompt-Prüfung, Generierung, Bildprüfung – und löscht im Falle einer Markierung die Datei vom Festplattenspeicher, bevor sie ihr Urteil zurückgibt. Ein problematisches Bild, das auf dem Server „während wir schauen” verbleibt, ist ein Bild, das am Ende undicht wird.

from openai import OpenAI
import base64

client = OpenAI()

def moderate_generated_image(image_path: str) -> dict:
    """Analyzes a generated image to detect problematic content."""
    with open(image_path, "rb") as f:
        image_b64 = base64.b64encode(f.read()).decode()

    moderation = client.moderations.create(
        model="omni-moderation-latest",
        input=[
            {
                "type": "image_url",
                "image_url": {
                    "url": f"data:image/png;base64,{image_b64}"
                }
            }
        ]
    )

    result = moderation.results[0]

    if result.flagged:
        categories_flagged = [
            cat for cat, flagged in result.categories.__dict__.items()
            if flagged
        ]
        return {
            "safe": False,
            "categories": categories_flagged
        }

    return {"safe": True}


def secure_pipeline(prompt: str, output: str):
    """Complete pipeline: prompt moderation + generation + image moderation."""
    # 1. Check the prompt
    check_prompt = verify_prompt(prompt)
    if not check_prompt["allowed"]:
        return {"status": "prompt_refused", "details": check_prompt}

    # 2. Generate the image
    response = client.images.generate(
        model="gpt-image-2.5-sunburst",
        prompt=prompt,
        size="1024x1024",
        quality="medium",
    )

    data = base64.b64decode(response.data[0].b64_json)
    with open(output, "wb") as f:
        f.write(data)

    # 3. Check the generated image
    check_image = moderate_generated_image(output)
    if not check_image["safe"]:
        import os
        os.remove(output)
        return {
            "status": "image_deleted",
            "reason": "Generated image was flagged",
            "categories": check_image["categories"]
        }

    return {"status": "ok", "path": output}

Wenn Nutzer die Prompts schreiben

Nutzererstellte Inhalte verändern die Natur des Problems: Sie stehen nicht mehr vor Unbeholfenheit, sondern manchmal vor gezielten Versuchen, Umgehungen zu finden. Die Klasse PromptModerator stapelt vier Abwehrmaßnahmen unterschiedlicher Art, was das Prinzip einer ernsthaften Sicherheit ist. Die Reinigung entfernt Steuerzeichen, durch die Injektionen passieren, und begrenzt die Länge auf fünf hundert Zeichen, wodurch Überschwemmungsprompts, die darauf ausgelegt sind, Anweisungen zu ertränken, abgekürzt werden. Die lokale Überprüfung über eine Liste verbotener Wörter – leer gelassen, um nach Ihrer Richtlinie und Ihrem Sektor gefüllt zu werden – fängt zu null Kosten ab, was Sie ohnehin bereits kennen. Die Moderations-API übernimmt dann für alles, was Ihre Liste nicht vorhergesehen hat. Schließlich der Sicherheitspräfix, der vor dem endgültigen Prompt angehängt wird: Er erinnert das Modell explizit an den erwarteten Rahmen und verschiebt die Grenze zu Ihren Gunsten bei Grenzfällen.

from openai import OpenAI
import re

client = OpenAI()

class PromptModerator:
    """Multi-layer filter for user prompts."""

    def __init__(self):
        self.forbidden_words = []  # Fill according to your policy
        self.security_prefix = (
            "Safe and appropriate image for all audiences. "
            "No violent, sexual, or discriminatory content. "
        )

    def clean(self, prompt: str) -> str:
        """Cleans and normalizes a user prompt."""
        # Remove potential injections
        prompt = prompt.strip()
        # Limit length
        prompt = prompt[:500]
        # Remove control characters
        prompt = re.sub(r'[\x00-\x1f\x7f-\x9f]', '', prompt)
        return prompt

    def check_words(self, prompt: str) -> bool:
        """Checks for absence of forbidden words."""
        prompt_lower = prompt.lower()
        for word in self.forbidden_words:
            if word in prompt_lower:
                return False
        return True

    def secure(self, prompt: str) -> str:
        """Adds a security prefix to the prompt."""
        return f"{self.security_prefix}{prompt}"

    def pipeline(self, raw_prompt: str) -> dict:
        """Complete moderation pipeline for a user prompt."""
        # Step 1: cleaning
        prompt = self.clean(raw_prompt)

        # Step 2: local verification
        if not self.check_words(prompt):
            return {"allowed": False, "reason": "Forbidden word detected"}

        # Step 3: API moderation
        check = verify_prompt(prompt)
        if not check["allowed"]:
            return {"allowed": False, "reason": check["message"]}

        # Step 4: add security prefix
        final_prompt = self.secure(prompt)

        return {"allowed": True, "prompt": final_prompt}


moderator = PromptModerator()

# Simulate a user prompt
result = moderator.pipeline("A tabby cat sleeping on a red cushion")
if result["allowed"]:
    print(f"Secure prompt: {result['prompt']}")
else:
    print(f"Refused: {result['reason']}")

Protokollierung zur Rechenschaftspflicht

Der Tag, an dem ein problematisches Bild wieder auftaucht, wird die Frage gestellt, die Sie hören werden: Wer hat es angefordert, wann, und was hat Ihr System getan? Ohne Protokolle haben Sie keine Antwort. AuditLogger schreibt pro Generierung eine JSON-Zeile in eine .jsonl-Datei – ein append-only-Format, das das parallele Schreiben unterstützt und Zeile für Zeile gelesen werden kann, ohne alles in den Arbeitsspeicher zu laden. Jeder Eintrag verknüpft eine Nutzer-ID mit einem abgeschnittenen Prompt, dem Generierungsergebnis und, falls zutreffend, dem Grund der Ablehnung. Die Methode report leitet dann die Akzeptanzrate der letzten hundert Generierungen ab und detailliert Ablehnungen: Dies ist das Dashboard, das Sie alarmieren wird, wenn ein bestimmtes Konto Anhäufungen von Markierungen aufweist.

import json
import os
from datetime import datetime

class AuditLogger:
    """Audit log for image generations."""

    def __init__(self, log_file: str = "audit_images.jsonl"):
        self.log_file = log_file

    def log(
        self,
        prompt: str,
        user_id: str,
        result: str,
        image_path: str = None,
        refusal_reason: str = None
    ):
        """Logs an audit entry."""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "user_id": user_id,
            "prompt": prompt[:200],
            "result": result,  # "ok", "prompt_refused", "image_deleted"
            "image_path": image_path,
            "refusal_reason": refusal_reason,
        }

        with open(self.log_file, "a") as f:
            f.write(json.dumps(entry, ensure_ascii=False) + "\n")

    def report(self, last_n: int = 100):
        """Generates a report of recent generations."""
        if not os.path.exists(self.log_file):
            print("No logs found.")
            return

        entries = []
        with open(self.log_file, "r") as f:
            for line in f:
                entries.append(json.loads(line))

        recent = entries[-last_n:]

        total = len(recent)
        ok = sum(1 for e in recent if e["result"] == "ok")
        refused = sum(1 for e in recent if e["result"] != "ok")

        print(f"Report of last {total} generations:")
        print(f"  Accepted: {ok} ({100*ok/total:.1f}%)")
        print(f"  Refused   : {refused} ({100*refused/total:.1f}%)")

        if refused > 0:
            print(f"\nRefusal details:")
            for e in recent:
                if e["result"] != "ok":
                    print(f"  [{e['timestamp'][:10]}] {e['user_id']} : {e['refusal_reason']}")


logger = AuditLogger()
logger.report()

Urheberrecht und Markenrechte

GPT Image weiß, wie es Bilder produzieren kann, die den Stil eines Künstlers oder die visuelle Identität einer Marke evozieren, und genau diese Fähigkeit setzt Sie bloß. Technische Moderation schützt Sie auf diesem Gebiet nicht: Sie erkennen nicht, dass ein Plakat sehr ähnlich zu dem eines Wettbewerbers aussieht. Der Schutz ist daher vertraglich und organisatorisch, in Form einer schriftlichen, durchsetzbaren Nutzungsrichtlinie, die Ihre Nutzer akzeptieren und Ihr Team anwendet. Der Block PRODUCTION_RULES gibt die minimale Formulierung, die in Ihrer Dokumentation angezeigt und in Ihren Bedingungen erinnert werden soll.

# Best practices to integrate into your usage policy

PRODUCTION_RULES = """
1. Do not request imitation of a living artist's style by name
2. Do not reproduce logos or registered trademarks
3. Do not generate faces of real people
4. Add an "AI-generated image" notice when required
5. Retain generation logs for at least 12 months
6. Allow users to report problematic content
"""

def usage_warning():
    """Displays production usage rules."""
    print("=" * 60)
    print("PRODUCTION RULES — AI Image Generation")
    print("=" * 60)
    print(PRODUCTION_RULES)

DSGVO-Konformität

Für ein europäisches Unternehmen sind Aufbewahrungsfristen und Einwilligungen keine Konfigurationsoptionen, sondern Verpflichtungen, deren Einhaltung nachweisbar sein muss. Die Aufzeichnung in einem expliziten Konfigurationsobjekt, statt sie im Code zu zerstreuen, gibt Ihnen einen einzigen Ort, an dem Sie während einer Prüfung zeigen können. ComplianceConfig setzt daher die Protokollierungsaufbewahrung auf ein Jahr, die Bildaufbewahrung auf neunzig Tage und macht die AI-Benachrichtigung und die Einwilligung obligatorisch. Die Methode add_ai_metadata verdient besondere Aufmerksamkeit: Sie schreibt in das PNG selbst, über PngInfo, die Tatsache, dass das Bild generiert wurde, das Werkzeug, das es produziert hat, und das Datum. Diese Metadaten reisen mit der Datei, auch außerhalb Ihrer Plattform, was eine auf einer Webseite angezeigte Benachrichtigung nicht tut.

class ComplianceConfig:
    """Compliance configuration for image generation."""

    def __init__(self):
        self.log_retention_days = 365
        self.image_retention_days = 90
        self.ai_notice_mandatory = True
        self.consent_required = True

    def verify_consent(self, user_id: str) -> bool:
        """Verifies that the user has consented to AI generation."""
        # Implement with your consent management system
        return True

    def add_ai_metadata(self, image_path: str):
        """Adds metadata indicating AI generation."""
        from PIL import Image
        from PIL.PngImagePlugin import PngInfo

        img = Image.open(image_path)
        metadata = PngInfo()
        metadata.add_text("AI-Generated", "true")
        metadata.add_text("Generator", "GPT Image via OpenAI API")
        metadata.add_text("Date", datetime.now().isoformat())
        img.save(image_path, pnginfo=metadata)
        print(f"AI metadata added: {image_path}")

Bevor Sie die Schleusen öffnen

Acht Bestimmungen müssen an dem Tag an Ort und Stelle sein, an dem Ihr System zugänglich wird, und es ist ehrlicher, sie vorher als nachher zu fordern. Moderation zuerst, in ihren zwei Phasen: Vorfilterung von Prompts und Nachprüfung von Bildern, wie secure_pipeline es tut. Protokollierung als Nächstes, vollständig, jede Generierung mit ihrem Prompt, Autor und Ergebnis verknüpfend – dies ist Ihr einziger Beweis im Falle eines Streits, und er muss unabhängig von den Bildern selbst gespeichert werden, sonst würde ein Speicherbereinigung Ihre Nachverfolgbarkeit mitnehmen.

Dann kommt die Nutzerseite. Ein Limit pro Konto verhindert, dass ein einzelner Abonnent Ihr monatliches Budget in einer Nacht verbraucht, freiwillig oder durch ein schlecht geschriebenes Skript. Informationen über die generierte Natur der Bilder betreffen sowohl Fairness als auch zunehmend regulatorische Beschränkung; sie wird durch technische Markierung in den PNG- oder EXIF-Metadaten der Datei verdoppelt. Das Recht auf Löschung setzt voraus, dass Sie alle Daten eines Nutzers auf einfache Anfrage finden und löschen können, was nur möglich ist, wenn Ihre Audit-Einträge eine user_id tragen. Schließlich einen Meldeweg öffnen: Ihre Nutzer werden immer sehen, was problematisch ist, bevor Sie es tun, und das Entziehen ihrer Mittel, Ihnen das zu sagen, macht das Problem nicht verschwinden.

Montieren Sie nun das Ganze zu einem einzigen Bildgenerierungsdienst: Vorfilterung von Prompts über die Moderations-API und Wortliste, Sicherheitspräfix, Nachprüfung des erzeugten Bildes, Audit-Protokoll und AI-Metadaten in jeder Datei. Testen Sie es mit fünf variierenden Prompts, wobei mindestens einer abgelehnt werden muss – dies ist der einzige Weg, um zu überprüfen, dass Ihre Schutzvorrichtungen tatsächlich funktionieren und nicht nur im Code vorhanden sind.

Wissen testen

Visuelle Generierung über API: Reflexe vor der Produktion validieren.

1. Was ermöglichen Inpainting und Outpainting?

Antwort: Inpainting modifiziert einen bestimmten Bereich eines bestehenden Bildes (ersetzen, korrigieren); Outpainting erweitert das Bild über seinen ursprünglichen Rahmen hinaus – zwei gezielte Bearbeitungen, ohne alles neu zu generieren.

2. Was macht einen guten fortgeschrittenen visuellen Prompt aus?

Antwort: Beschreiben Sie das Motiv, die Komposition, das Licht und die Perspektive – nicht nur das Thema: Je mehr der Prompt die Szene wie ein Kameramann rahmt, desto mehr gehorcht das Bild.

3. Wie effektiv durch Iterationen arbeiten?

Antwort: Beginnen Sie mit einer Basisgenerierung, fordern Sie dann gezielte Variationen (Stil, Rahmung, Detail) an, anstatt den Prompt von vorne zu schreiben – behalten Sie, was funktioniert, und passen Sie nur die Lücke an.

4. Welche Hebel, um Generierungskosten zu optimieren?

Antwort: Passen Sie Qualität und Auflösung an den tatsächlichen Bedarf an (Entwürfe in niedrig, Finals in hoch), begrenzen Sie Iterationen durch bessere Prompts und cachen/wiederverwenden Sie validierte Visuals.

5. Warum ist die Moderation visueller Inhalte unerlässlich?

Antwort: Weil die API und Ihre Bedingungen Grenzen auferlegen (verbotene Inhalte, reale Personen, Marken): Das Filtern von Prompts und das Kontrollieren von Ausgaben schützt Ihre Nutzer und Ihre Anwendung.

Rahmen, iterieren, Kosten und Compliance meistern: Visuelle Produktion ist eine Pipeline – kein Würfeln.