ChatGPT · Die API: Ihre ersten echten Aufrufe
Am schnellsten wachsen Sie über das ChatGPT-Fenster hinaus, wenn dasselbe Modell aus Ihrem eigenen Code heraus antwortet, und bei OpenAI braucht das etwa zehn Zeilen. Diese Lektion behandelt genau diese zehn Zeilen: was daran OpenAI-spezifisch ist, warum die Responses APIAPIApplication Programming Interface: eine standardisierte Schnittstelle, über die Anwendungen kommunizieren und Daten austauschen, ohne die interne Funktionsweise der jeweils anderen zu kennen.Vollständige Definition ansehen → inzwischen der Standard ist und wie Sie TokensTokensEin Token ist die grundlegende Texteinheit, die Sprachmodelle verarbeiten, oft ein Wortfragment, ein ganzes Wort oder ein Satzzeichen und nicht ein einzelnes Zeichen.Vollständige Definition ansehen → streamen, sobald sie eintreffen.
Einmal einrichten, dann vergessen
Holen Sie sich einen Key auf der API-Keys-Seite. Behandeln Sie ihn wie ein Passwort: Er ist an die Abrechnung gekoppelt, und wer ihn hat, kann Ihr Guthaben ausgeben. Fügen Sie ihn nie in Code ein und committen Sie ihn nie in git.
Legen Sie ihn als Umgebungsvariable an, damit das SDK ihn automatisch findet:
export OPENAI_API_KEY="sk-proj-..."
pip install openaiDas offizielle Python-SDK liest OPENAI_API_KEY selbstständig, Sie schreiben den Key also nie in Ihr Skript. Eine Abgrenzung ist hier wichtig: Ihr API-Konto und Ihr ChatGPT-Abo sind getrennt. ChatGPT Plus oder Pro bringt Ihnen kein API-Guthaben, und die API-Nutzung wird pro Token über ein separates Guthaben abgerechnet. Gemeinsam sind die Modelle, nicht das Portemonnaie.
Ihr erster echter Aufruf
Hier ein vollständiges, lauffähiges Skript mit der Responses API, der aktuellen Hauptschnittstelle von OpenAI:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5-mini",
instructions="You are a terse assistant. Answer in one sentence.",
input="Explain what an idempotent API request is.",
)
print(response.output_text)Führen Sie es aus, und Sie bekommen einen einzigen sauberen Satz zurück. Jetzt zu den Teilen, die OpenAI-spezifisch sind.
client = OpenAI()
Das erzeugt den Client und übernimmt stillschweigend Ihren Key aus der Umgebung. Alles, was Sie tun, läuft über dieses Objekt: Textgenerierung, Embeddings, Dateien, Audio. Sie konfigurieren ihn einmal.
model="gpt-5-mini"
Der Modellname ist eine echte, abrechnungsrelevante Entscheidung, kein Etikett. Die aktuelle Standardfamilie ist GPT-5, erschienen im August 2025, in drei Größen: gpt-5 für die schwierigsten Aufgaben, gpt-5-mini als Arbeitspferd für den Alltag und gpt-5-nano für günstige Aufrufe in hohem Volumen. Ein Klassifikator oder ein Formatierer gehört auf nano. Ein Support-Bot kommt meist mit mini gut aus. Eine mehrstufige Planungsaufgabe kann das volle Modell rechtfertigen.
In Tutorials begegnen Ihnen noch ältere Namen: die GPT-4.1-Reihe und die Reasoning-Modelle der o-Serie wie o3 und o4-mini. Sie waren getrennte Familien. GPT-5 führt Reasoning in einer Reihe zusammen, Sie wechseln also nicht mehr die Modellfamilie, um ein Modell zu bekommen, das vor der Antwort nachdenkt. Prüfen Sie die aktuelle Auswahl und die Preise auf der Modellseite, denn das Angebot ändert sich laufend.
Reasoning effort
GPT-5-Modelle denken nach, bevor sie antworten, und wie viel, steuern Sie mit einem einzigen Parameter:
response = client.responses.create(
model="gpt-5-mini",
reasoning={"effort": "low"},
input="Classify this email as billing, bug, or other: 'I was charged twice.'",
)Niedriger effort ist schneller und günstiger. Höherer effort hilft bei Mathematik, Code und mehrstufiger Planung. Bei einfacher Extraktion oder Klassifikation fangen Sie niedrig an und erhöhen nur, wenn die Qualität nachlässt.
instructions vs. input
Das ist die sauberste Verbesserung, die die Responses API mitbringt. instructions enthält die Steuerung auf Systemebene (PersonaPersonaEine halb fiktive, forschungsbasierte Darstellung Ihres idealen Kunden: seine Ziele, Frustrationen, Verhaltensweisen und Entscheidungskriterien.Vollständige Definition ansehen →, Regeln, Ausgabeformat). input ist der eigentliche Beitrag des Nutzers. Für einfache Aufrufe bauen Sie keine Liste von Message-Dictionaries mit Rollen mehr von Hand. Für einen einzelnen Austausch reichen zwei Strings.
response.output_text
Ein bequemer Accessor, der die Antwort zum finalen Textstring zusammenfasst. Das vollständige response-Objekt enthält mehr: Token-Verbrauch, das Modell, das tatsächlich geantwortet hat, Tool-Aufrufe und strukturierte Inhaltsblöcke. Für schnelle Arbeit ist output_text das Richtige. In Produktion lesen Sie die ausführlicheren Felder.
Responses oder Chat Completions?
In Tutorials sehen Sie beides, kennen Sie also den Unterschied.
Chat Completions (client.chat.completions.create) ist die ältere, vielfach kopierte Schnittstelle. Sie erwartet eine messages-Liste aus {"role": ..., "content": ...}-Dicts. Sie funktioniert weiterhin und ist nicht deprecated, bestehender Code ist also sicher.
Responses (client.responses.create) empfiehlt OpenAI für neue Projekte. Sie kann den Gesprächszustand für Sie halten, hat eingebaute Tools (Websuche, Dateisuche, Code Interpreter), die Sie zuschalten kkDie durchschnittliche Zahl neuer Nutzer, die jeder bestehende Nutzer über Empfehlungen generiert. Über 1,0 verstärkt sich das Wachstum selbst und wird exponentiell.Vollständige Definition ansehen →önnen, ohne sie selbst anzubinden, und handhabt mehrstufige Tool-Nutzung sauberer. Die Responses-API-Dokumentation ist die mamaEinsatz von Software, um wiederkehrende Marketingaufgaben und Kampagnen zu automatisieren und Personalisierung in großem Maßstab über Kanäle wie E-Mail, Web und Social zu ermöglichen.Vollständige Definition ansehen →ßgebliche Referenz.
In älteren Anleitungen taucht ein dritter Name auf: die Assistants API. OpenAI hat sie zugunsten von Responses deprecated, beginnen Sie darauf also nichts Neues.
Faustregel: Neuer Code startet mit Responses. Greifen Sie nur dann zu Chat Completions, wenn Sie etwas erweitern, das es bereits verwendet.
Streaming: Tokens, sobald sie eintreffen
Wenn Nutzer warten müssen, bis eine lange Antwort komplett generiert ist, bevor überhaupt etwas erscheint, wirkt das kaputt. Streaming schickt Tokens, während das Modell sie erzeugt, und liefert so den Schreibmaschineneffekt, den Sie aus ChatGPT kennen.
Sie aktivieren es mit stream=True und iterieren über die Events:
from openai import OpenAI
client = OpenAI()
stream = client.responses.create(
model="gpt-5-mini",
input="Write a two-line haiku about slow APIs.",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
print()Der Stream liefert typisierte Events, nicht einfach rohen Text. Sie filtern auf response.output_text.delta, um die inkrementellen Textstücke abzugreifen. Andere Event-Typen melden, wann die Antwort beginnt, wann ein Tool aufgerufen wird und wann die Generierung abgeschlossen ist. flush=True gibt jedes Stück sofort im Terminal aus, statt es zu puffern.
Bei Reasoning-Modellen kann es vor dem ersten Text-Token eine kurze Pause geben, während das Modell nachdenkt. Niedrigerer reasoning effort verkürzt sie.
Streaming ändert nichts an den Kosten oder am Endergebnis. Es ändert nur, *wann* Sie die Bytes sehen. Nutzen Sie es für jede Oberfläche mit Nutzern und lassen Sie es bei Batch-Jobs weg, bei denen niemand zuschaut.
Drei OpenAI-spezifische Dinge, die Sie früh kennen sollten
Structured Outputs
Wenn das Modell Daten zurückgeben soll, die Ihr Code parsen kann, betteln Sie im Prompt nicht um JSON und hoffen. Nutzen Sie Structured Outputs, das die Antwort zwingt, einem von Ihnen definierten SchemaSchemaEin Schema ist der formale Bauplan, der festlegt, wie Daten in einer Datenbank, einer Datei oder einer Nachricht strukturiert, benannt, typisiert und miteinander verknüpft sind.Vollständige Definition ansehen → zu entsprechen. Sie übergeben ein JSON Schema (oder in Python ein Pydantic-Modell), und OpenAI garantiert die Struktur, Sie schreiben also nie wieder defensives Parsing für einen verirrten Markdown-Codeblock.
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class Ticket(BaseModel):
priority: str
summary: str
response = client.responses.parse(
model="gpt-5-mini",
input="My checkout button has been broken for two days, losing sales.",
text_format=Ticket,
)
ticket = response.output_parsed
print(ticket.priority, "|", ticket.summary)response.output_parsed liefert Ihnen ein typisiertes Ticket-Objekt. Für alle, die echte Features bauen, ist das der größte einzelne Gewinn an Zuverlässigkeit. Der Structured-Outputs-Guide erklärt die Schema-Regeln.
Function Calling
Das Modell kann entscheiden, Funktionen aufzurufen, die Sie bereitstellen, und gibt Ihnen Funktionsnamen und Argumente zur Ausführung zurück. Sie beschreiben Ihre Funktionen, das Modell wählt eine, wenn es passt, Sie führen sie aus und geben das Ergebnis zurück. Assistenten mit Tools bauen auf diesem Grundbaustein auf. Beachten Sie die Abgrenzung: Function Calling in der API ist nicht dasselbe wie GPT Actions in Custom GPTs. Actions sind die No-Code-Variante im Produkt ChatGPT. Function Calling ist der rohe Mechanismus, den Sie im Code steuern.
OpenAI Function Calling Explained
Das Agents SDK
Wenn aus einem einzelnen Funktionsaufruf eine Schleife aus Planen, Tool-Aufrufen und Ergebnisprüfung wird, steigen Sie auf das Agents SDK um. Es ist OpenAIs offizielles Framework für mehrstufige Agenten: Es verwaltet die Tool-Call-Schleife, Übergaben zwischen spezialisierten Agenten und GuardrailsGuardrailsRegeln und Kontrollen, die ein KI-System in sicheren, rechtskonformen und markengerechten Grenzen halten und unerwünschte Ausgaben blockieren.Vollständige Definition ansehen →, sodass Sie die Orchestrierung nicht selbst bauen. Für Ihre ersten Aufrufe brauchen Sie es nicht. Sobald ein einzelner Responses-Aufruf nicht mehr reicht, ist es der naheliegende nächste Schritt, und es baut direkt auf der Responses API auf.
Wissenscheck
1. Warum sollten Sie Ihren OpenAI-Key als Umgebungsvariable anlegen, statt ihn direkt in Ihr Skript zu schreiben?
2. Ein Kollege meint, sein ChatGPT-Plus-Abo müsse auch seine API-Nutzung abdecken. Was ist die richtige Klarstellung?
3. Sie sollen einen schnellen, günstigen Textklassifikator bauen, der eingehende Nachrichten nur labelt. Welche Modellwahl passt am besten zur Aufgabe?
4. Wählen Sie ALLE zutreffenden Aussagen über die Responses API und den OpenAI-Client, wie in der Lektion beschrieben.
Wählen Sie alle richtigen Antworten aus.
5. Wählen Sie ALLE zutreffenden Aussagen über den Unterschied zwischen 'instructions' und 'input' in der Responses API.
Wählen Sie alle richtigen Antworten aus.
Das Response-Objekt richtig lesen
Für alles, was über eine Demo hinausgeht, hören Sie auf, nur output_text auszugeben, und sehen sich das ganze Objekt an. Zwei Felder sind sofort wichtig.
Usage. Jede Antwort meldet die Token-Zahlen:
print(response.usage.input_tokens, response.usage.output_tokens)
print(response.usage.output_tokens_details.reasoning_tokens)Damit messen Sie die Kosten. Input-Tokens (Ihr Prompt und die Instructions) und Output-Tokens (die Generierung) haben unterschiedliche Preise, und Output ist meist die teurere Seite. Die Reasoning-Tokens, die ein GPT-5-Modell zum Nachdenken verbraucht, werden als Output abgerechnet, obwohl Sie sie nie sehen. Eine kurze Antwort kann also mehr kosten als erwartet. Wer den Verbrauch vom ersten Tag an loggt, erspart sich eine böse Überraschung auf der Rechnung.
Das ausliefernde Modell. Das Feld model zeigt, welche genaue Modellversion geantwortet hat. Ob Sie einen datierten Snapshot festlegen oder einen Alias nutzen, der sich automatisch aktualisiert: Über dieses Feld bestätigen Sie, was tatsächlich lief. Für reproduzierbares Verhalten in Produktion legen Sie einen bestimmten Snapshot fest statt eines wandernden Alias.
Fehler, die Ihnen tatsächlich begegnen
Echte Aufrufe scheitern aus echten Gründen. Behandeln Sie die häufigen explizit:
from openai import OpenAI, RateLimitError, APIError
client = OpenAI()
try:
response = client.responses.create(
model="gpt-5-mini",
input="Summarize the API economy in one line.",
)
print(response.output_text)
except RateLimitError:
print("Slow down or upgrade your tier, then retry with backoff.")
except APIError as err:
print(f"OpenAI-side issue: {err}")RateLimitError ist der Fehler, dem Einsteiger zuerst begegnen. Neue API-Konten starten auf einer niedrigen Nutzungsstufe mit bescheidenen Limits pro Minute, und die Stufen steigen automatisch, je älter Ihr Konto ist und je mehr Sie ausgeben. Behandeln Sie ein Rate Limit nicht als Bug. Sehen Sie es als Signal, Retry mit Backoff einzubauen, was das SDK über die Einstellung max_retries am Client für Sie übernehmen kann. APIError und seine Unterklassen decken Authentifizierung, fehlerhafte Anfragen und vorübergehende Serverfehler ab. Fangen Sie sie ab, damit ein einzelner Aussetzer nicht Ihre App abstürzen lässt.
Latenz und Kosten im Rahmen halten
Ein paar Gewohnheiten zahlen sich sofort aus:
- Begrenzen Sie den Output mit
max_output_tokens, damit ein gesprächiges Modell nicht ausufert und die Rechnung in die Höhe treibt. Bei Reasoning-Modellen schließt das Limit die verborgenen Reasoning-Tokens ein, lassen Sie also Spielraum: Ein zu knappes Limit kann die Antwort beenden, bevor überhaupt sichtbarer Text erscheint. - Wählen Sie Modell und effort passend. Der Großteil des Produktionsverkehrs läuft gut auf
gpt-5-miniodergpt-5-nanomit niedrigem reasoning effort. Heben Sie das volle Modell und hohen effort für Aufgaben auf, die sie brauchen. - Streamen Sie Aufrufe mit Nutzerkontakt, und schicken Sie unabhängige Hintergrundaufrufe parallel statt in einer langsamen Schleife. Gefühlte Geschwindigkeit kommt vom Streaming, echter Durchsatz von Parallelität.
Diese Hebel (Output-Limit, Modell und effort, Parallelität) decken den Großteil der Kosten- und Latenzoptimierung ab, die Sie am Anfang vornehmen.
Key Takeaways
- Starten Sie neuen Code auf der Responses API (
client.responses.create) mitinstructionsundinput. Behalten Sie Chat Completions für bestehende Codebasen und lassen Sie die deprecated Assistants API links liegen. - Nehmen Sie standardmäßig die GPT-5-Familie (
gpt-5-miniist ein vernünftiger Start) und justieren Sie denreasoningeffort, statt auf ein separates Reasoning-Modell zu wechseln. - Legen Sie
OPENAI_API_KEYals Umgebungsvariable an und denken Sie daran, dass Ihr API-Guthaben von jedem ChatGPT-Abo getrennt ist. - Nutzen Sie Structured Outputs (
responses.parsemit einem Pydantic-Modell), wann immer Sie parsbare Daten brauchen, statt per Prompt um JSON zu bitten und zu hoffen. - Lesen Sie
response.usageeinschließlich der Reasoning-Tokens vom ersten Tag an aus und setzen Siemax_output_tokensmit genug Spielraum. - Streamen Sie Oberflächen mit Nutzerkontakt, indem Sie auf
response.output_text.delta-Events filtern, und fangen SieRateLimitErrormit Backoff ab, statt Ihre App abstürzen zu lassen.
Was Sie aus dieser Lektion umsetzen
Diese Maßnahmen sind im Playbook der Rolle zusammengefasst.
- Neuen Code auf der Responses API starten und response.usage von Tag eins an auslesen