Zurück zum Blog

API & SDKAnleitung

OpenAI Python SDK Timeout und Retries: für CheapTokens setzen

Setzen Sie timeout, max_retries und max_tokens im OpenAI Python SDK, fangen Sie die richtigen Fehler ab, und verhindern Sie, dass eine hängende Anfrage 10 Minuten läuft.

Von CheapTokens TeamVeröffentlicht am 5 Min. Lesezeit

Python-Code mit timeout=30.0 und max_retries=2 auf dunklem Hintergrund
Auf dieser Seite
  1. Was das SDK tut, wenn Sie nichts setzen
  2. Timeout und max_retries am Client setzen
  3. Für eine einzelne Anfrage überschreiben
  4. Die Fehler abfangen, die wichtig sind
  5. max_tokens begrenzen, damit eine lange Antwort nicht davonläuft
  6. Was Retries mit der Rechnung machen
  7. Bevor Sie ausliefern

Ihr Skript hat das Modell aufgerufen, es kam nichts zurück, und zehn Minuten später wartet es immer noch. Das ist der Standard des OpenAI Python SDK: ein 10-Minuten-Timeout und 2 Retries. Um das zu ändern, übergeben Sie timeout=30.0 und max_retries=2 an OpenAI(...), überschreiben Sie sie pro Aufruf mit client.with_options(...), und begrenzen Sie die Antwort mit max_tokens.

Das README des SDK (geprüft am 27. Oktober 2026) dokumentiert all das. Unten wird es auf den CheapTokens-Endpunkt angewendet, https://api.cheaptokens.dev/v1, der das OpenAI Chat Completions-Format spricht. Details zu diesem Setup finden Sie in Your first API request with CheapTokens und in den docs.

Was das SDK tut, wenn Sie nichts setzen#

Zwei Standards sind wichtig. Der Timeout beträgt 10 Minuten. Die Retries sind 2, mit einem kurzen exponentiellen Backoff, für Verbindungsfehler und für 408, 409, 429 und 5xx-Antworten, und nur wenn der Request-Body sicher erneut gesendet werden kann. Eine Anfrage, die in einen Timeout läuft, wird ebenfalls erneut versucht.

Jeder Versuch bekommt also seinen eigenen Timeout, und der Worst Case ist ungefähr der Timeout multipliziert mit der Anzahl der Versuche, plus die Pausen dazwischen:

  • Standard: 600 × 3 = 1800 Sekunden, eine halbe Stunde
  • timeout=30.0, max_retries=2: 30 × 3 = 90 Sekunden

Angenommen, ein Web-Endpunkt muss innerhalb von 30 Sekunden antworten. Mit den Standards kann er eine halbe Stunde hängen, bevor Ihr Code einen Fehler sieht. Probieren Sie es mit einer anderen Einstellung, bevor Sie weiterlesen.

Zahl erraten

Ein Client hat timeout=45.0 und max_retries=3. Wie hoch ist die Worst-Case-Wartezeit in Sekunden bis zur Exception, ohne die Pausen zwischen den Versuchen?

Antwort anzeigen

Antwort: 180

45 × (3 Retries + 1 erster Versuch) = 180 Sekunden; die Pausen zwischen den Versuchen kommen noch etwas obendrauf.

Timeout und max_retries am Client setzen#

Die einfachste Lösung ist, beides einmal zu setzen, wenn Sie den Client erstellen:

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
    timeout=30.0,      # seconds per attempt
    max_retries=2,     # 0 turns retries off
)

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Summarize this ticket in two sentences: ..."}],
    max_tokens=800,
)
print(resp.choices[0].message.content)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)

max_retries muss eine nicht-negative Ganzzahl sein. timeout nimmt einen Float, oder ein httpx Timeout-Objekt, wenn Sie separate Limits für Verbinden und Lesen wollen. Das README des aktuellen main-Branches importiert dafür httpx2, ältere Versionen nutzten httpx, führen Sie also pip show openai aus und prüfen Sie, welche Ihre Installation verwendet. Ein einfacher Float braucht keinen Import und funktioniert in beiden Fällen.

The request path with timeout=30 and two retries
One request: an attempt, a timeout, up to two retries, then an exception

Verwenden Sie die vollständige Modell-ID aus den CheapTokens docs, hier deepseek-ai/DeepSeek-V4-Flash-0731: IDs unterscheiden sich zwischen Anbietern. Dieses Modell nimmt bis zu 32.768 Output-Tokens pro Antwort und hat einen 380K-Kontext, weshalb die Zeile max_tokens oben absichtlich dort steht. Mehr dazu unten, und zum Modell in cheap DeepSeek.

Für eine einzelne Anfrage überschreiben#

Ein Client, verschiedene Aufgaben. Eine Chat-Antwort sollte schnell aufgeben, eine nächtliche Zusammenfassung kann warten. Statt einen zweiten Client zu erstellen, leiten Sie einen für den Aufruf ab:

python
quick = client.with_options(timeout=5.0, max_retries=0)
resp = quick.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Reply with one word: ok"}],
    max_tokens=5,
)

with_options gibt eine Kopie mit den neuen Werten zurück und lässt client unangetastet. max_retries=0 zu setzen ist die richtige Wahl, wenn Ihr eigener Code bereits Retries macht, zum Beispiel eine Job-Queue, die die Aufgabe erneut einreiht. Andernfalls multiplizieren sich die beiden Ebenen: 3 SDK-Versuche innerhalb von 3 Queue-Versuchen sind 9 Anfragen für eine Aufgabe.

Die Fehler abfangen, die wichtig sind#

Nachdem die Retries aufgebraucht sind, wirft das SDK eine Exception. Jede Fehlerklasse erbt von openai.APIError, und fehlgeschlagene Anfragen tragen request_id, was Sie loggen:

python
import openai

def ask(prompt: str) -> str | None:
    try:
        r = client.chat.completions.create(
            model="deepseek-ai/DeepSeek-V4-Flash-0731",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=800,
        )
        return r.choices[0].message.content
    except openai.APITimeoutError:
        print("timed out after retries")
    except openai.RateLimitError as e:
        print("429, slow down:", e.request_id)
    except openai.APIConnectionError:
        print("cannot reach the API")
    except openai.APIStatusError as e:
        print("HTTP", e.status_code, e.request_id)
    return None

Die Reihenfolge ist von eng nach weit. APIStatusError deckt jede 4xx- oder 5xx-Antwort ab, würde also, wenn es zuerst käme, RateLimitError verschlucken. Dasselbe Prinzip beim Timeout: es steht über dem allgemeinen Verbindungsfehler. In einem Batch-Skript ist return None der ganze Sinn: den Prompt loggen, zur nächsten weitergehen und die Fehlschläge am Ende erneut ausführen.

Wenn der Timeout auslöst und die Retries aufgebraucht sind, sieht die Exception so aus:

The APITimeoutError message after retries are used up
What a caught timeout looks like in the log

Für den 429-Fall im Detail, einschließlich Warten zwischen den Versuchen, siehe 429 Too Many Requests from an AI API.

max_tokens begrenzen, damit eine lange Antwort nicht davonläuft#

Ein Timeout beendet das Warten. Es bringt das Modell nicht dazu, weniger zu schreiben. Ohne max_tokens kann ein Modell mit einem 32.768-Token-Antwortlimit eine sehr lange Antwort schreiben, und eine lange Antwort ist eine langsame. Setzen Sie ein Limit, das zur Aufgabe passt: 800 für eine Ticket-Zusammenfassung, 5 für ein Ja/Nein.

Der Preis dafür ist, dass eine Antwort abgeschnitten werden kann. Prüfen Sie resp.choices[0].finish_reason: length bedeutet, das Limit wurde erreicht, bevor das Modell fertig war. Why does an AI answer stop mid-sentence? behandelt das. Wenn Sie die Antwort stattdessen streamen, kommen die ersten Wörter früh an und die Wartezeit fühlt sich kürzer an, siehe Streaming responses in Python.

Was Retries mit der Rechnung machen#

Ein Retry ist eine neue Anfrage. Wenn ein Versuch verarbeitet wurde, ist er eine separate Anfrage mit eigenen Tokens. Angenommen, eine Ticket-Zusammenfassung hat 1.500 Tokens Input und 400 Output: eine Anfrage kostet $0.000063 zu heutigen Preisen, und die vollständige pricing table enthält die anderen Modelle. Preise sind pro Modell fest, ohne Peak-Zeiten, ein Retry um 3 Uhr nachts kostet also dasselbe wie einer mittags.

Bewegen Sie die Regler auf Ihren eigenen Batch:

Kostenrechner

Ein Batch von 1.000 Ticket-Zusammenfassungen

Eingabe-Tokens pro Anfrage: 1.500 · Ausgabe-Tokens pro Anfrage: 400 · Anfragen pro Tag: 1.000

ModellPro TagPro Monat
GLM-5.3-Flash$0.046$1.38
DeepSeek-V4-Flash$0.0625$1.88
MiniMax-M2.7$0.135$4.05

Die Tabelle zeigt einen Durchlauf. Wenn ein Zehntel des Batches einen zweiten Versuch braucht, fügen Sie ein Zehntel hinzu. Retries sind eine günstige Versicherung, wenn Fehler selten sind, und eine teure Angewohnheit, wenn Sie max_retries=10 gegen einen Endpunkt setzen, der ständig ausfällt.

Bevor Sie ausliefern#

Checkliste

Timeouts und Retries, produktionsbereit