Kosten optimieren
Auf dieser Seite
Aktualisiert am 2. November 2026 — Bildmodelle. Das Modell
gpt-image-1, für das dieser Kurs ursprünglich geschrieben wurde, wurde am 23. Oktober 2026 eingestellt.gpt-image-1.5,gpt-image-1-miniundchatgpt-image-latestwerden am 1. Dezember 2026 eingestellt. Die Beispiele verwenden nungpt-image-2.5-sunburst, das die höchste Präzision für Bearbeitungen bietet;gpt-image-2.5-flareist für die Standardgenerierung schneller. Beide Modelle unterstützen auch die Qualitätsstufenxhighundmax. GPT-Bildmodelle geben Bilder immer im Base64-Format zurück: Der Parameterresponse_formatvon älteren DALL·E-Modellen wird nicht mehr akzeptiert und aus dem Code entfernt. Quelle: Bildgenerierung (OpenAI).
Kosten optimieren
In der Produktion hört die Bildgenerierung auf, eine technische Neugierde zu sein, und wird zu einem Budgetposten. Jedes Team, das monatlich nur ein paar hundert Visuals produziert, merkt dies schnell. Die erste Reaktion – die Nutzung einzuschränken – ist auch die unklügste. Diese Lektion behandelt fünf Strategien, die die Ausgaben senken, ohne die Qualität Ihrer Ergebnisse zu beeinträchtigen, da sie sich darauf konzentrieren, was Sie wegwürfen, anstatt darauf, was Sie behalten.
Kostenstruktur verstehen
Die Generierungskosten hängen von drei Faktoren ab.
| Faktor | Auswirkung auf die Kosten |
|---|---|
Qualität (low, medium, high) | Direkter Multiplikator |
| Auflösung (1024, 1536) | Größer = teurer |
Anzahl der Bilder (n) | Lineare Kosten (n × Einheitspreis) |
Diese drei Faktoren multiplizieren sich miteinander, was erklärt, warum ungebremste Explorationen eine Größenordnung mehr kosten als dieselbe Exploration, die diszipliniert durchgeführt wird. Der folgende Skriptauflistung zeigt die fünf Kombinationen, die Sie in der Produktion am häufigsten antreffen werden. Während die genauen Beträge auf Ihrem OpenAI-Dashboard erscheinen, zeigt die Reihenfolge der Zeilen bereits die Skala der Abwägungen.
from openai import OpenAI
client = OpenAI()
# Kosten vergleichen: gleicher Prompt, unterschiedliche Parameter
configs = [
{"quality": "low", "size": "1024x1024", "label": "Low / 1024"},
{"quality": "medium", "size": "1024x1024", "label": "Medium / 1024"},
{"quality": "high", "size": "1024x1024", "label": "High / 1024"},
{"quality": "medium", "size": "1536x1024", "label": "Medium / 1536"},
{"quality": "high", "size": "1536x1024", "label": "High / 1536"},
]
print("Konfiguration | Nutzung (geschätzt)")
print("-" * 50)
for config in configs:
print(f"{config['label']:22s} | Prüfen Sie Ihr OpenAI-Dashboard")
Prototypen in Low erstellen, liefern in High
Dies ist bei weitem die kosteneffektivste Strategie und die einfachste umzusetzen. Während der Explorationsphase urteilen Sie nicht über die Feinheit eines Farbverlaufs: Sie urteilen über Komposition, Bildrahmen und die allgemeine Stimmung, die alle in quality: low perfekt sichtbar sind. Der Wechsel zu high macht nur dann Sinn, wenn Sie das Bild tatsächlich veröffentlichen möchten. Der folgende Workflow formalisiert diese Sequenz, indem er fünf wirtschaftliche Entwürfe erstellt, gefolgt von einer einzigen finalen Renderung, mit dem zusätzlichen Vorteil des Wechsels zum Querformat (1536×1024) für die definitive Version. Über fünf Versuche und eine Lieferung hinweg schwanken die am Ende des Skripts zitierten Einsparungen bei etwa 60 % im Vergleich zu einer Exploration, die vollständig in high durchgeführt wurde.
from openai import OpenAI
import base64
client = OpenAI()
def economical_workflow(prompt: str, output: str, n_drafts: int = 5):
"""
Zweiphasen-Workflow:
1. Schnelle Entwürfe in niedriger Qualität
2. Finale Renderung in hoher Qualität
"""
# Phase 1: Schnelle Exploration
print("Phase 1: schnelle Entwürfe (niedrige Qualität)")
drafts = []
for i in range(n_drafts):
response = client.images.generate(
model="gpt-image-2.5-sunburst",
prompt=prompt,
size="1024x1024",
quality="low",
)
path = f"draft_{i+1}.png"
data = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(data)
drafts.append(path)
print(f" Entwurf {i+1}: {path}")
# Phase 2: Finale Renderung (nach manueller Auswahl des besten Entwurfs)
print("\nPhase 2: finale Renderung (hohe Qualität)")
response = client.images.generate(
model="gpt-image-2.5-sunburst",
prompt=prompt,
size="1536x1024",
quality="high",
)
data = base64.b64decode(response.data[0].b64_json)
with open(output, "wb") as f:
f.write(data)
print(f" Finale Renderung: {output}")
# Zusammenfassung: 5 Low + 1 High statt 5 High
print(f"\nZusammenfassung: {n_drafts} Low-Entwürfe + 1 finale High")
print("Geschätzte Einsparungen: ~60 % im Vergleich zur High-Exploration")
economical_workflow(
"Illustration eines grünen Technologie-Campus mit Solarpanelen, architektonischer Stil",
"campus_final.png"
)
Bezahlen Sie niemals doppelt für dasselbe Bild
In einer echten Anwendung wird derselbe Prompt viel häufiger zurückgegeben, als man erwarten würde: Ein Benutzer aktualisiert die Seite, ein Build-Skript führt eine Generierung erneut aus, oder ein Icon wird über drei Seiten hinweg wiederverwendet. Jeder dieser Fälle ist eine unnötige Gebühr. Der folgende Cache eliminiert sie, indem er einen SHA-256-Hash des Triplets (Prompt, Größe, Qualität) berechnet – die drei Elemente, die das abgerechnete Ergebnis bestimmen – und diesen Hash auf sechzehn Zeichen kürzt, um einen handhabbaren Dateinamen zu erstellen. Beachten Sie die os.path.exists-Prüfung: Der Index könnte einen Eintrag kennen, dessen Datei vom Datenträger gelöscht wurde, in welchem Fall das Bild neu generiert wird, anstatt einen toten Pfad zurückzugeben.
import hashlib
import json
import os
from openai import OpenAI
import base64
client = OpenAI()
CACHE_DIR = "image_cache"
CACHE_INDEX = os.path.join(CACHE_DIR, "index.json")
def load_cache() -> dict:
"""Lädt den Cache-Index."""
if os.path.exists(CACHE_INDEX):
with open(CACHE_INDEX, "r") as f:
return json.load(f)
return {}
def save_cache(cache: dict):
"""Speichert den Cache-Index."""
os.makedirs(CACHE_DIR, exist_ok=True)
with open(CACHE_INDEX, "w") as f:
json.dump(cache, f, indent=2, ensure_ascii=False)
def generate_with_cache(
prompt: str,
size: str = "1024x1024",
quality: str = "medium"
) -> str:
"""Generiert ein Bild oder gibt das gecachte Ergebnis zurück."""
# Erstellen Sie einen eindeutigen Schlüssel basierend auf den Parametern
key_data = f"{prompt}|{size}|{quality}"
cache_key = hashlib.sha256(key_data.encode()).hexdigest()[:16]
cache = load_cache()
if cache_key in cache:
cached_path = cache[cache_key]["path"]
if os.path.exists(cached_path):
print(f"Cache-Treffer: {cached_path}")
return cached_path
else:
print("Cache abgelaufen, Neugenerierung...")
# Nicht im Cache: Generieren
response = client.images.generate(
model="gpt-image-2.5-sunburst",
prompt=prompt,
size=size,
quality=quality,
)
path = os.path.join(CACHE_DIR, f"{cache_key}.png")
os.makedirs(CACHE_DIR, exist_ok=True)
data = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(data)
cache[cache_key] = {
"prompt": prompt[:100],
"size": size,
"quality": quality,
"path": path
}
save_cache(cache)
print(f"Generiert und gecacht: {path}")
return path
# Erste Generierung: API-Aufruf
path1 = generate_with_cache("Minimalistisches Logo für ein Tech-Startup, blau und weiß")
# Zweiter identischer Aufruf: wird aus dem Cache bedient
path2 = generate_with_cache("Minimalistisches Logo für ein Tech-Startup, blau und weiß")
Größe präzise bestimmen
Die Generierung eines hochauflösenden Vorschaubildes, das in einem 80-Pixel-Quadrat angezeigt wird, ist wie das Bezahlen für eine Ausstellungsdarstellung, nur um sie in eine Brieftasche zu stecken. Die Lösung besteht darin, diese Entscheidung nicht dem Willkür des Entwicklers zu überlassen, sondern sie aus der deklarierten Nutzung abzuleiten. Das generate_for_usage-Wörterbuch teilt Fälle in drei Familien auf: kleine Webformate – Vorschaubilder und Avatare –, die mit low in Ordnung sind; Standard-Webnutzung – Blog-Header, Social-Media-Posts –, die medium erfordern; und Medien, bei denen Feinheit wirklich zählt – Hero-Banner, A4-Druck, Portfolios –, die high rechtfertigen. Die letzten beiden Aufrufe illustrieren die Lücke: derselbe Astronaut-Katze kostet ein Vielfaches, je nachdem, ob er als Vorschaubild oder als Homepage-Banner endet.
from openai import OpenAI
import base64
client = OpenAI()
def generate_for_usage(prompt: str, usage: str, output: str):
"""Wählt automatisch die optimale Auflösung und Qualität."""
configs = {
# Kleine Webnutzung
"thumbnail": {"size": "1024x1024", "quality": "low"},
"avatar": {"size": "1024x1024", "quality": "low"},
# Standard-Webnutzung
"blog_header": {"size": "1536x1024", "quality": "medium"},
"social_post": {"size": "1024x1024", "quality": "medium"},
# Hochwertige Nutzung
"hero_banner": {"size": "1536x1024", "quality": "high"},
"print_a4": {"size": "1024x1536", "quality": "high"},
"portfolio": {"size": "1024x1024", "quality": "high"},
}
config = configs.get(usage, {"size": "1024x1024", "quality": "medium"})
response = client.images.generate(
model="gpt-image-2.5-sunburst",
prompt=prompt,
size=config["size"],
quality=config["quality"],
)
data = base64.b64decode(response.data[0].b64_json)
with open(output, "wb") as f:
f.write(data)
print(f"Nutzung {usage} ({config['quality']}/{config['size']}) → {output}")
generate_for_usage("Nette Katze in einer Astronautenanzug", "thumbnail", "cat_thumb.png")
generate_for_usage("Nette Katze in einer Astronautenanzug", "hero_banner", "cat_hero.png")
Bearbeiten statt neu zu generieren
Der Kunde genehmigt das Foto, möchte aber einen anderen Himmel. Die natürliche Reflexion – die vollständige Generierung erneut mit einem angepassten Prompt auszuführen – lässt Sie für ein ganzes Bild bezahlen und, schlimmer noch, den Rest der Komposition verlieren, die alle genehmigt hatten. images.edit() behandelt diese Situation zum Preis einer Bearbeitung: Die edit_detail-Funktion erstellt eine Maske, die nur das relevante Rechteck freigibt, hier die oberen 300 Pixel Höhe, die dem Himmel entsprechen, und der Prompt beschreibt nur den Inhalt dieses Streifens. Die Landschaft bewegt nicht ein Pixel.
import base64
from openai import OpenAI
from PIL import Image, ImageDraw
client = OpenAI()
# Anstatt das gesamte Bild neu zu generieren, um ein Detail zu ändern,
# bearbeiten Sie nur den relevanten Bereich.
def edit_detail(image_path: str, zone: tuple, new_content: str, output: str):
"""
Bearbeitet ein Detail in einem bestehenden Bild.
zone: (x1, y1, x2, y2) des Bereichs, der geändert werden soll
"""
source = Image.open(image_path)
mask = Image.new("RGBA", source.size, (0, 0, 0, 255))
draw = ImageDraw.Draw(mask)
draw.rectangle(zone, fill=(0, 0, 0, 0))
mask.save("temp_mask.png")
response = client.images.edit(
model="gpt-image-2.5-sunburst",
image=open(image_path, "rb"),
mask=open("temp_mask.png", "rb"),
prompt=new_content
)
with open(output, "wb") as f:
f.write(base64.b64decode(response.data[0].b64_json))
print(f"Detail bearbeitet: {output}")
print("Kosten: 1 Bearbeitung statt 1 vollständige Generierung")
# Beispiel: Ändern Sie nur den Himmel eines Fotos
edit_detail(
"landschaft.png",
(0, 0, 1024, 300),
"Blauer Himmel mit einigen flauschigen weißen Wolken",
"landschaft_himmel_bearbeitet.png"
)
Wissen, wohin das Geld fließt
Die vier vorherigen Strategien setzen voraus, dass Sie wissen, was Sie verbrauchen, und diese Sichtbarkeit kommt nicht automatisch: Das Dashboard des Anbieters gibt Ihnen einen Gesamtbetrag, keine Aufschlüsselung nach Projekt oder Qualität. Ein lokales Log füllt diese Lücke für vernachlässigbare Entwicklungskosten. log_generation fügt für jeden Aufruf eine zeitgestempelte Zeile hinzu, wobei der Prompt auf 100 Zeichen gekürzt wird, um lesbar zu bleiben, und usage_report aggregiert dann alles nach Qualitätsstufe. Diese Aufschlüsselung löst Entscheidungen aus: Wenn Ihr Log zeigt, dass 80 % Ihrer Bilder in high generiert werden, während die Mehrheit auf Social-Media-Posts landet, haben Sie gerade Ihren Einsparpool gefunden.
import json
import os
from datetime import datetime
USAGE_FILE = "image_usage_log.json"
def log_generation(prompt: str, size: str, quality: str, n: int = 1):
"""Loggt jede Generierung, um Kosten zu verfolgen."""
if os.path.exists(USAGE_FILE):
with open(USAGE_FILE, "r") as f:
log = json.load(f)
else:
log = []
entry = {
"timestamp": datetime.now().isoformat(),
"prompt": prompt[:100],
"size": size,
"quality": quality,
"n_images": n,
}
log.append(entry)
with open(USAGE_FILE, "w") as f:
json.dump(log, f, indent=2, ensure_ascii=False)
def usage_report():
"""Zeigt einen Verbrauchsbericht an."""
if not os.path.exists(USAGE_FILE):
print("Keine Verbrauchsdaten.")
return
with open(USAGE_FILE, "r") as f:
log = json.load(f)
total = len(log)
by_quality = {}
for entry in log:
q = entry["quality"]
by_quality[q] = by_quality.get(q, 0) + entry["n_images"]
print(f"Gesamtgenerierungen: {total}")
print("Aufschlüsselung nach Qualität:")
for q, count in sorted(by_quality.items()):
print(f" {q}: {count} Bilder")
usage_report()
Wo anfangen
Nicht alle Strategien bieten denselben Ertrag im Verhältnis zum Aufwand, und die folgende Tabelle hilft Ihnen, sie zu priorisieren.
| Strategie | Geschätzte Einsparungen | Aufwand |
|---|---|---|
| Low für Prototypen | 50-70 % | Minimal |
| Prompt-Caching | 10-30 % (wiederholend) | Mäßig |
| Angepasste Auflösung | 20-40 % | Minimal |
| Bearbeiten vs. Neugenerierung | 30-50 % (pro Änderung) | Mäßig |
| Kostenverfolgung | Indirekt (Sichtbarkeit) | Mäßig |
Zwei Zeilen fallen deutlich auf: Prototypen in low erstellen und die Auflösung an die Nutzung anpassen erfordern minimalen Aufwand für die Hälfte der möglichen Einsparungen. Beginnen Sie damit, fügen Sie dann Caching und gezielte Bearbeitung hinzu, wenn Ihr Volumen dies rechtfertigt. Die Kostenverfolgung selbst spart nichts direkt – aber sie sagt Ihnen, welche der anderen vier in Ihrem spezifischen Kontext tatsächlich Früchte tragen.
Der beste Weg, aufzuhören, darüber nachzudenken, besteht darin, diese Regeln in einer einzigen Engstelle zu kapseln. Schreiben Sie eine Wrapper-Funktion um client.images.generate(), die Prompt-Caching, automatische Anpassung von Qualität und Auflösung basierend auf deklarierten Nutzung sowie Protokollierung jedes Aufrufs integriert; führen Sie es dann auf zehn Generierungen aus und lesen Sie den Verbrauchsbericht. Ab da spart Ihr gesamtes Team Geld, ohne sich daran erinnern zu müssen.