AnmeldenKontaktKostenlos starten
Base URL and SDK Migration27. Juli 2026Flatkey Team

OpenAI-Client-Migration: RPM, TPM und Retry-Verhalten beibehalten

Migrieren Sie einen OpenAI-ähnlichen Client zu einem einheitlichen Gateway, ohne Retry-Stürme zu verursachen, indem Sie RPM, TPM, Timeouts, Streaming, Backoff, Canaries und Rollback prüfen.

OpenAI-Client-Migration: RPM, TPM und Retry-Verhalten beibehalten

Eine OpenAI-Client-Migration kann nach zwei Konfigurationsänderungen bereits abgeschlossen wirken: Ersetzen Sie den API-Schlüssel und verweisen Sie das SDK auf eine neue Base-URL. Die erste Anfrage ist erfolgreich, die Antwortstruktur wirkt vertraut, und der Pull Request scheint bereit zum Merge.

Das beweist die Schnittstellenkompatibilität. Es beweist nicht das Produktionsverhalten.

Der schwierigere Teil einer OpenAI-Client-Migration ist es, zu bewahren, was passiert, wenn der Traffic ungleichmäßig wird: Anfragen kommen in Schüben an, Prompts werden größer, Streams laufen länger als erwartet, ein Anbieter gibt 429 zurück, oder eine Antwort läuft in ein Timeout, nachdem die Arbeit möglicherweise bereits begonnen hat. Wenn das SDK, Ihre Anwendung und eine Job-Queue unabhängig voneinander erneut versuchen, kann ein einziger fehlgeschlagener Aufruf zu mehreren nahezu gleichzeitigen Versuchen werden.

Dieses Tutorial zeigt, wie Sie eine bestehende OpenAI-ähnliche Python- oder TypeScript-Integration auf ein einheitliches Gateway migrieren und dabei das Verhalten bei Rate Limits und Retries explizit machen. Die Beispiele verwenden die OpenAI-kompatible Base-URL von Flatkey, aber die Prüfmethode gilt für jede Gateway-Migration.

Kurze Antwort: Was sollte sich ändern?

Für eine sichere OpenAI-Client-Migration sollten Sie diese Einstellungen gemeinsam überprüfen, statt die Base-URL als die gesamte Änderung zu behandeln.

Migrationsbereich Was geprüft werden sollte Sichere Startentscheidung
API-Endpunkt Base-URL und Authentifizierung Über Umgebungsvariablen ändern, nicht über verstreute Literale
Modellauswahl Exakte Modell-IDs und unterstützte Parameter Für den Canary einen bekannten Modellnamen fest verdrahten
SDK-Retries Automatische Retry-Anzahl und retryfähige Statuscodes Entscheiden, ob das SDK oder Ihre Anwendung die Retries verantwortet
Anwendungs-Retries Backoff, Jitter, Versuchslimit und Retry-Budget Nur einen Retry-Verantwortlichen behalten und jeden Versuch protokollieren
RPM-Steuerung Ankunftsrate der Anfragen und Burst-Größe Vor dem Cutover ein Concurrency- oder Queue-Limit hinzufügen
TPM-Steuerung Prompt plus erwartete Ausgabe-Tokens Realistische große Prompts testen, nicht nur einen Smoke-Test mit einer Zeile
Timeouts Verbindungs-, Lese- und gesamte Anfragedauer Explizite Werte für synchrone und Streaming-Aufrufe setzen
Beobachtbarkeit Request-IDs, Versuche, Tokens, Latenz und Endergebnis Client-Logs mit Gateway-Usage-Logs vergleichen

Wenn Sie zuerst die Erklärung auf Akronym-Ebene benötigen, lesen Sie LLM-Rate-Limits erklärt: RPM, TPM und Retries. Dieser Leitfaden setzt dort an, wo diese Erklärung endet: bei der Migrations-Diff und dem Produktions-Testplan.

Warum ein Wechsel der Base-URL notwendig, aber nicht ausreichend ist

Flatkeys Quickstart dokumentiert die minimale Client-Änderung: Behalten Sie das Request-Muster des OpenAI SDK bei und setzen Sie die Base-URL auf https://router.flatkey.ai/v1. Außerdem wird empfohlen, nach der Anfrage die Usage Logs zu prüfen, damit Sie Modell, Token-Anzahl, Latenz und Kosten verifizieren können.

Das ist der richtige Smoke-Test. Eine produktive OpenAI-Client-Migration braucht vier zusätzliche Fragen:

  1. Retryt das SDK 429-, Timeout- oder Serverfehler automatisch?
  2. Versucht auch eine andere Schicht dieselbe fehlgeschlagene Operation erneut?
  3. Wird die Parallelität durch Anforderungsrate, Tokenrate oder beides begrenzt?
  4. Können Sie eine logische Operation von ihren einzelnen Versuchen unterscheiden?

Die offizielle Dokumentation der OpenAI Python- und Node-SDKs sagt derzeit, dass ausgewählte Fehler standardmäßig zweimal erneut versucht werden, einschließlich 429-Antworten, Verbindungsfehlern, Timeouts und einigen Serverfehlern. Beide SDKs bieten Konfigurationsoptionen für Retries und Timeouts. Dieses Standardverhalten ist praktisch für eine direkte Integration, kann aber zu einer unsichtbaren Verstärkung werden, wenn Ihr eigener Code bereits Backoff implementiert.

Das Migrationsziel lautet nicht: „Jeden Retry deaktivieren.“ Das Ziel lautet: „Wissen, welche Schicht für den Retry verantwortlich ist.“

Schritt 1: Alle Retry-Schichten inventarisieren, bevor Sie den Code ändern

Beginnen Sie damit, den tatsächlichen Aufrufpfad zu zeichnen.

Benutzeraktion oder Job
  -> Retry-Wrapper der Anwendung
  -> Retry der Warteschlangen-Zustellung
  -> OpenAI-SDK-Retry
  -> Gateway
  -> Provider

Erfassen Sie für jede Schicht:

  • Welche Fehler einen weiteren Versuch auslösen.
  • Die maximale Anzahl an Versuchen.
  • Ob die Verzögerung feste Wartezeiten, exponentielles Backoff oder Jitter verwendet.
  • Ob ein vom Server bereitgestellter Wert Retry-After berücksichtigt wird.
  • Ob dieselbe Operations-ID über die Versuche hinweg beibehalten wird.
  • Ob bei einem Timeout angenommen wird, dass die Anfrage fehlgeschlagen ist, bevor irgendeine Arbeit ausgeführt wurde.

Die letzte Annahme ist riskant. Ein Client-Timeout sagt nur aus, dass der Client nicht mehr gewartet hat. Das Upstream-System hat die Anfrage möglicherweise dennoch angenommen oder abgeschlossen. Bei generierten Inhalten kann ein Retry daher ein weiteres Ergebnis und eine weitere abrechenbare Anfrage erzeugen, selbst wenn Ihre Anwendung nur eine logische Aufgabe beobachtet hat.

Worst-Case-Verstärkung abschätzen

Angenommen, eine Warteschlange kann einen Job dreimal zustellen, der Anwendungs-Wrapper erlaubt drei Versuche, und das SDK führt den ersten Aufruf plus zwei Retries aus. Im schlimmsten Fall kann ein logischer Job Folgendes auslösen:

3 Warteschlangen-Zustellungen × 3 Anwendungsversuche × 3 SDK-Versuche = 27 HTTP-Versuche

Sie werden diesen Höchstwert möglicherweise nie erreichen, aber die Multiplikation erklärt, warum ein kurzes 429 in eine Retry-Sturm eskalieren kann. Schreiben Sie die Zahl in die Migrationsprüfung. So werden versteckte Standardwerte sichtbar.

Schritt 2: Endpunkt-Einstellungen in die Konfiguration verschieben

Halten Sie den Migrations-Diff reversibel. Ersetzen Sie Endpunkt-Strings nicht überall im Codebase.

Python vorher und nachher

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["LLM_API_KEY"],
    base_url=os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1"),
    max_retries=0,
    timeout=45.0,
)

Für den Flatkey-Canary konfigurieren Sie:

export LLM_API_KEY="$FLATKEY_API_KEY"
export LLM_BASE_URL="https://router.flatkey.ai/v1"

TypeScript vorher und nachher

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.LLM_API_KEY,
  baseURL: process.env.LLM_BASE_URL ?? "https://api.openai.com/v1",
  maxRetries: 0,
  timeout: 45_000,
});

Diese Beispiele setzen SDK-Wiederholungsversuche auf null, weil der nächste Abschnitt der Anwendung die explizite Verantwortung für Retries überträgt. Wenn Ihre Anwendung keine Retry-Schicht hat, können Sie stattdessen begrenzte SDK-Retries beibehalten. Behalten Sie nicht aus Versehen beides bei.

Für die breitere Kompatibilitäts-Checkliste siehe OpenAI Compatible API Gateway: Migration Checklist for Minimal Code Changes.

Schritt 3: Einer Schicht die explizite Retry-Verantwortung geben

Eine nützliche Retry-Strategie hat fünf Teile:

  1. Eine kurze Liste retry-fähiger Fehler.
  2. Eine strikte Obergrenze für Versuche.
  3. Eine maximale gesamte Retry-Zeit.
  4. Exponentielles Backoff mit Jitter.
  5. Strukturierte Logs für jeden Versuch.

Hier ist ein kleiner Python-Wrapper für einen synchronen Chat-Aufruf:

import random
import time
from openai import APITimeoutError, APIConnectionError, APIStatusError, RateLimitError

RETRYABLE_STATUS_CODES = {408, 409, 429, 500, 502, 503, 504}


def create_chat_with_retry(client, *, model, messages, max_attempts=4):
    started_at = time.monotonic()

    for attempt in range(1, max_attempts + 1):
        try:
            return client.chat.completions.create(
                model=model,
                messages=messages,
            )
        except (RateLimitError, APITimeoutError, APIConnectionError) as error:
            retryable = True
            caught_error = error
        except APIStatusError as error:
            retryable = error.status_code in RETRYABLE_STATUS_CODES
            caught_error = error

        if not retryable or attempt == max_attempts:
            raise caught_error

        exponential_delay = min(2 ** (attempt - 1), 16)
        jitter = random.uniform(0, 0.5 * exponential_delay)
        sleep_seconds = exponential_delay + jitter

        print({
            "event": "llm_retry",
            "attempt": attempt,
            "next_delay_seconds": round(sleep_seconds, 2),
            "elapsed_seconds": round(time.monotonic() - started_at, 2),
            "error_type": type(caught_error).__name__,
        })
        time.sleep(sleep_seconds)

    raise RuntimeError("unreachable")

Betrachten Sie dies als überprüfbaren Ausgangspunkt, nicht als universelle Richtlinie. In der Produktion sollten Sie einen gültigen Antwort-Header Retry-After parsen und berücksichtigen, bevor Sie auf die lokal berechnete Verzögerung zurückfallen. Fügen Sie ein Budget für die gesamte verstrichene Zeit hinzu, damit Retries die Latenz, die Ihr Produkt tolerieren kann, nicht überschreiten.

Nicht jeden Fehler erneut versuchen

Fehler Standardaktion Warum
400 ungültige Anfrage Unverändert nicht erneut versuchen Die Nutzlast muss geändert werden
401 Authentifizierung Unverändert nicht erneut versuchen Der Schlüssel oder Header muss geändert werden
404 Modell nicht gefunden Unverändert nicht erneut versuchen Die Modellkennung oder der Zugriff muss geändert werden
429 Ratenlimit Mit Verzögerung und Jitter erneut versuchen Kapazität kann verfügbar werden
500 oder 503 Innerhalb eines kleinen Budgets erneut versuchen Der Fehler kann vorübergehend sein
Client-Timeout Vorsichtig erneut versuchen Die vorgelagerte Anfrage wurde möglicherweise bereits ausgeführt

Flatkeys Schnellstart gibt für 429 dieselbe allgemeine Empfehlung: mit exponentiellem Backoff und Jitter erneut versuchen. Die migrationsspezifische Ergänzung besteht darin, sicherzustellen, dass nur eine Schicht diese Policy ausführt.

Schritt 4: Parallelität für RPM und TPM auslegen

Eine OpenAI-Client-Migration kann die Anfrage-Syntax beibehalten und dennoch das Kapazitätsprofil verändern. RPM und TPM begrenzen unterschiedliche Workloads:

  • RPM wird zum Engpass, wenn Sie viele kleine Anfragen senden.
  • TPM wird zum Engpass, wenn Prompts, Ausgaben oder parallele Auswertungen groß sind.

Verwenden Sie beobachteten Traffic statt eines einzelnen Durchschnitts. Erfassen Sie mindestens:

  • Anfragen pro Minute im Median und am Peak.
  • Eingabe-Tokens bei p50, p95 und Maximum.
  • Ausgabe-Tokens bei p50 und p95.
  • Median und p95 der Anfragedauer.
  • Anzahl gleichzeitiger Streams.

Eine grobe Obergrenze für die Parallelität kann aus jedem Limit geschätzt werden:

RPM-basierte Parallelität ≈ (RPM / 60) × durchschnittliche Anfragedauer in Sekunden

TPM-basierte Parallelität ≈ (TPM / durchschnittliche Tokens pro Anfrage / 60)
                        × durchschnittliche Anfragedauer in Sekunden

Verwenden Sie das niedrigere Ergebnis als anfängliche Obergrenze und lassen Sie dann Spielraum für Spitzen und Wiederholungen.

Beispiel: Angenommen, ein Pfad erlaubt 600 RPM und 300.000 TPM, die durchschnittliche Anfrage verwendet insgesamt 1.500 Tokens und die durchschnittliche Dauer beträgt 3 Sekunden.

RPM-Obergrenze: (600 / 60) × 3 = 30 gleichzeitige Anfragen
TPM-Obergrenze: (300,000 / 1,500 / 60) × 3 = 10 gleichzeitige Anfragen

TPM ist in diesem Beispiel die engere Begrenzung. Mit 30 gleichzeitigen Anfragen zu starten, nur weil RPM großzügig aussieht, würde vermeidbare 429-Antworten verursachen.

Diese Berechnung ist richtungsweisend, keine Garantie des Anbieters. Anbieter können rollierende Fenster, Token-Buckets, getrennte Eingabe- und Ausgabe-Token-Limits, modellspezifische Pools oder Beschleunigungskontrollen verwenden. Der Testplan muss das tatsächliche Verhalten für das ausgewählte Modell und Konto verifizieren.

Schritt 5: Streaming- und Timeout-Verhalten separat testen

Behandeln Sie einen erfolgreichen Non-Streaming-Aufruf nicht als Beweis dafür, dass Streaming sicher ist.

Testen Sie bei Streaming-Anfragen:

  • Zeit bis zum ersten Token.
  • Maximales stilles Intervall zwischen Chunks.
  • Client-Lese-Timeout.
  • Verhalten, wenn der Consumer die Verbindung trennt.
  • Ob Ihr Retry-Wrap versehentlich einen zweiten Stream starten kann.
  • Ob Teilausgaben beibehalten, verworfen oder dem Benutzer angezeigt werden.

Ein Stream, der nach einer Teilausgabe fehlschlägt, ist nicht gleichbedeutend mit einer Anfrage, die fehlschlug, bevor irgendeine Ausgabe erzeugt wurde. Ein automatisches Wiederholen kann doppelten Text anzeigen oder eine andere Fortsetzung erzeugen. Entscheiden Sie, ob das Produkt erneut versuchen, den Benutzer fragen oder das Teilergebnis anzeigen soll.

Denken Sie auch daran, dass SDK-Timeouts und Infrastruktur-Timeouts unterschiedlich sein können. Ein Reverse Proxy, eine Serverless-Plattform, ein Job-Worker oder eine Browserverbindung kann beendet werden, bevor die Client-Bibliothek ihr eigenes Timeout erreicht. Während der OpenAI-Client-Migration sollten Sie das kleinste Timeout im kompletten Anfragepfad erfassen.

Schritt 6: Vor breitflächigem Traffic eine Canary-Matrix ausführen

Verwenden Sie ein fest gepinntes Modell und einen kleinen Prozentsatz des Traffics. Der erste Canary sollte beantworten, ob die neue Route das Verhalten beibehält, nicht ob jedes Modell funktioniert.

Testfall Eingabe Erwarteter Nachweis
Authentifizierung Gültige und ungültige Schlüssel Erfolg plus ein nicht erneut versuchtes 401
Modellvalidierung Gültige und falsch geschriebene Modell-IDs Erfolg plus ein nicht erneut versuchter Modellfehler
Kleiner Anforderungs-Burst Viele kurze Prompts Kontrollierte Queueing ohne Retry-Spike
Großer Prompt-Burst Weniger Prompts mit vielen Tokens TPM-Druck ist sichtbar und begrenzt
Erzwungenes 429 Canary-Limit vorübergehend überschreiten Ein Retry-Verantwortlicher, jitterte Verzögerungen, begrenzte Versuche
Erzwungener Timeout Einen absichtlich kurzen Client-Timeout setzen Protokollierter Timeout ohne unbegrenztes Wiederholen
Streaming-Unterbrechung Während eines Streams trennen Explizites Verhalten für teilweise Ausgaben
Serverfehler 503 injizieren oder simulieren Begrenzte Retries und abschließende Fehlerberichterstattung
Rollback Die vorherige Base-URL wiederherstellen Rollback nur per Konfiguration gelingt

Für jede logische Operation protokollieren:

operation_id
attempt_number
base_url_name
model_requested
http_status
input_tokens
output_tokens
latency_ms
retry_delay_ms
final_outcome

Vergleichen Sie dann die Anwendungslogs mit den Flatkey Usage Logs. Die Zählungen sollten zusammen Sinn ergeben. Wenn eine Anwendungsoperation auf mehrere Gateway-Anfragen abgebildet wird, sollte Ihre Retry-Instrumentierung erklären, warum.

Schritt 7: Rollout- und Rollback-Schwellen definieren

Eine OpenAI-Client-Migration sollte numerische Stoppbedingungen haben, bevor der erste Canary startet.

Beispielschwellen:

  • Rollback, wenn die finale Fehlerrate um mehr als einen vereinbarten Prozentpunkt steigt.
  • Pause, wenn die Versuche pro Operation das erwartete Retry-Budget überschreiten.
  • Pause, wenn die p95-Latenz das Timeout-Budget des Produkts überschreitet.
  • Pause, wenn sich der Tokenverbrauch pro erfolgreicher Operation unerwartet ändert.
  • Traffic erst ausweiten, nachdem sowohl Streaming- als auch Nicht-Streaming-Pfade bestanden haben.

Vermeiden Sie den Vergleich nur roher 429-Zahlen. Eine gute Queue kann finale Fehler reduzieren, während sie vorübergehend die Zahl verzögerter Anfragen erhöht. Verfolgen Sie sowohl Ergebnisse auf Versuchsebene als auch auf Operationsebene.

Checkliste für den Migrations-Pull-Request

Kopieren Sie diese Checkliste in den Implementierungs-PR.

  • Base-URL und Schlüssel stammen aus Umgebungsvariablen.
  • Der Canary verwendet eine exakte, verifizierte Modellkennung.
  • Eine Ebene ist für Retries verantwortlich.
  • SDK-Standardwerte für Retries sind im PR dokumentiert.
  • 429, Timeout- und 5xx-Verhalten haben begrenzte Versuche.
  • Backoff enthält Jitter und respektiert Retry-After, wenn vorhanden.
  • RPM- und TPM-Grenzen werden aus dem beobachteten Traffic geschätzt.
  • Streaming hat einen separaten Fehler-Test.
  • Jeder Versuch teilt sich eine gemeinsame logische operation_id.
  • Usage Logs und Anwendungslogs werden verglichen.
  • Rollout- und Rollback-Schwellen sind vor dem Start festgelegt.
  • Der vorherige Endpoint kann ohne weitere Codeänderung wiederhergestellt werden.

Häufige Migrationsfehler

SDK-Retries und Anwendungs-Retries beibehalten, ohne die Gesamtsumme zu berechnen

Dies ist der wichtigste Befund der Überprüfung. Standardwerte sind weiterhin Verhalten, selbst wenn sie in der lokalen Funktion nicht sichtbar sind.

Nur einen winzigen Prompt testen

Eine einzeilige Anfrage belegt Anmeldedaten und Antwortkompatibilität. Sie sagt fast nichts über TPM-Druck, Ausgabegrenzen, lange Streams oder p95-Latenz aus.

Authentifizierungs- und Validierungsfehler erneut versuchen

Backoff kann einen ungültigen Schlüssel, einen nicht unterstützten Parameter oder ein falsch geschriebenes Modell nicht reparieren. Unveränderte Payloads erneut zu versuchen verschwendet Kapazität und verdeckt den eigentlichen Defekt.

Ein Timeout als Beweis dafür behandeln, dass keine Anfrage ausgeführt wurde

Der Client kann aufhören zu warten, nachdem der Upstream den Aufruf angenommen hat. Entwerfen Sie Wiederholungen und Abrechnung mit dieser Unklarheit im Hinterkopf.

Endpoint, Modelle, Prompts und Retry-Policy in einem Release ändern

Das macht Fehler schwer zuzuordnen. Migrieren Sie zuerst eine bekannte Request-Form, und erweitern Sie dann die Modellauswahl, nachdem die Route beobachtbar ist.

Eine sicherere Definition von „OpenAI-kompatibel“

Für die Migrationsplanung sollte „OpenAI-kompatibel“ bedeuten, dass das Interaktionsmuster vertraut genug ist, um Codeänderungen zu reduzieren. Es sollte nicht als Versprechen verstanden werden, dass jeder Anbieter identische Kontingente, Token-Zählung, Fehlersemantik, Latenz, Streaming-Verhalten oder Parameterunterstützung bietet.

Diese Unterscheidung macht eine OpenAI-Client-Migration einfacher zu prüfen. Behalten Sie die stabile Schnittstelle dort bei, wo es hilft, aber testen Sie den operativen Vertrag dort, wo Anbieter und Routen sich unterscheiden können.

Flatkey zentralisiert Zugriff und Abrechnung hinter einer einzigen OpenAI-kompatiblen Base-URL, was den Client-Diff und spätere Modellerweiterungen vereinfachen kann. Die technische Arbeit besteht weiterhin darin, Retries, Durchsatz und Beobachtbarkeit vor dem Wechsel des Produktivverkehrs explizit zu machen.

Das ist der Standard, den eine produktive OpenAI-Client-Migration erfüllen sollte: eine kleine Schnittstellenänderung, gestützt durch explizite operative Nachweise.

Sehen Sie sich die Flatkey-Preisseite an, wenn Sie die Modelle für Ihren Canary auswählen, und genehmigen Sie die Migration erst, nachdem die Checkliste im Code Review bestanden hat und das Routenverhalten in den Logs sichtbar ist.

Häufig gestellte Fragen

Sollte ich OpenAI-SDK-Retries während der Migration deaktivieren?

Deaktivieren Sie sie, wenn Ihre Anwendung oder Warteschlange bereits Retries übernimmt. Wenn keine andere Schicht erneut versucht, können begrenzte SDK-Retries angemessen sein. Die wichtige Regel ist, mehrere unabhängige Retry-Verantwortliche zu vermeiden.

Was ist der Unterschied zwischen RPM und TPM während einer Migration?

RPM begrenzt die Anfragefrequenz, während TPM den Token-Durchsatz begrenzt. Kleine, häufige Aufrufe können zuerst an RPM stoßen; weniger große Prompts oder Ausgaben können zuerst an TPM stoßen. Testen Sie beide Workload-Formen.

Soll ein 429 immer erneut versucht werden?

Nur innerhalb eines begrenzten Retry- und Latenzbudgets. Beachten Sie Retry-After, wenn verfügbar, andernfalls verwenden Sie exponentielles Backoff mit Jitter. Stoppen Sie, wenn der Vorgang das Latenzziel des Produkts nicht mehr einhalten kann.

Kann ich eine zeitüberschrittene Generierung sicher erneut versuchen?

Nicht mit Sicherheit. Die Upstream-Anfrage kann ausgeführt worden sein, obwohl der Client ein Timeout hatte. Behandeln Sie den Retry als mögliche Doppelanfrage und protokollieren Sie den Zusammenhang zwischen den Versuchen.

Was ist der minimale sichere Canary?

Verwenden Sie ein fest gepinntes Modell, eine Anforderungsform, eine explizite Zuständigkeit für Retries, ein Limit für die Parallelität und Tests für 429, Timeout, Streaming-Unterbrechung und Rollback. Vergleichen Sie clientseitige Versuche mit den Nutzungsprotokollen des Gateways, bevor Sie den Traffic ausweiten.

Sources