OpenAI-kompatible API: Wechsel in drei Zeilen
Was OpenAI-kompatibel wirklich heißt, die drei Zeilen, die deine App auf eine europäische API umziehen, und eine ehrliche Liste dessen, was nicht mitkommt.
Drei Zeilen. Du richtest die base_url des Clients auf den neuen Anbieter, tauschst den API-Schlüssel aus und ersetzt den Modellnamen durch einen Stufennamen. Alles andere in einem Chat-Completions-Aufruf, das Messages-Array, Streaming, Tools, JSON-Schemas, bleibt genau, wie es ist. Denn OpenAI-kompatibel heißt, denselben HTTP-Vertrag umzusetzen, nicht bloß so ähnlich auszusehen.
Das Spannende an einer Migration ist nicht der Code. Es ist das, was nicht mitkommt: die Endpunkte, die es noch nicht gibt, das Modellverhalten, das sich beim selben Prompt verschiebt, und der eine Fehlercode, den du wahrscheinlich noch nie behandelt hast.

Was „OpenAI-kompatibel“ wirklich bedeutet
Es bedeutet den Vertrag eines einzigen Endpunkts: POST /v1/chat/completions, mit demselben Request-Body und derselben Form der Antwort, einschließlich des Server-Sent-Events-Formats fürs Streaming. Dieser Vertrag ist zur Standardschnittstelle der Branche geworden, so wie die API von S3 zum Standard für Objektspeicher wurde, und aus demselben Grund: Alles war schon dagegen geschrieben.
Die offiziellen SDKs sind dünne Clients über diesem Vertrag. In OpenAIs Python-Bibliothek ist die Base-URL ein Konstruktor-Argument, sie woanders hinzurichten, ist also eine unterstützte Operation und kein Hack. Deine Retry-Logik, dein Streaming-Handler und deine Typdefinitionen funktionieren weiter.
Was es nicht bedeutet: denselben Funktionsumfang auf der ganzen Plattform. Kompatible Dienste setzen den Chat-Endpunkt gut um und gehen danach eigene Wege. Deshalb ist die ehrliche Fassung dieses Beitrags vor allem eine Liste von Abweichungen.
from openai import OpenAIclient = OpenAI(api_key=os.environ["UNION_API_KEY"],base_url="https://api.europeanailab.eu/v1",)response = client.chat.completions.create(model="eu-standard",messages=[{"role": "user", "content": prompt}],stream=True,)
3 Zeilen unterscheiden sich: der Schlüssel, die Base-URL und ein Stufenname statt eines Modellnamens.
Alles andere im Aufruf ist derselbe Vertrag: Messages, Streaming, Tools, JSON-Schemas. Es ändert sich nicht die Form der Anfrage, sondern welches Modell die Antwort schreibt. Deshalb geht es in der Checkliste weiter unten um Evaluation und nicht um Code.
Die drei Zeilen in der Praxis
Hier ist die ganze Änderung in Python. Die SDKs für Node, Go und .NET nehmen dieselben zwei Argumente unter anderen Namen.
from openai import OpenAI
client = OpenAI(
api_key=os.environ["UNION_API_KEY"],
base_url="https://api.europeanailab.eu/v1",
)
response = client.chat.completions.create(
model="eu-standard",
messages=[{"role": "user", "content": prompt}],
stream=True,
)
Liest dein Code die Base-URL schon aus einer Umgebungsvariable, was sich vor jeder Migration lohnt, ist das eine Konfigurationsänderung und kein Deploy von neuem Code. Damit hast du auch den billigsten Rollback überhaupt: zurückstellen.
Was mitkommt, was sich ändert, was fehlt
Die Tabelle, die du wirklich brauchst, bevor du die Arbeit planst.
| Funktion | Status | Was zu tun ist |
|---|---|---|
| Chat Completions | Funktioniert unverändert | Nichts |
| Streaming (SSE) | Funktioniert unverändert | Den Verbrauch im Stream anfordern, damit die Abrechnung exakt bleibt |
| Function Calling und Tools | Gleiche Formen | Neu testen, welches Tool das Modell wählt, nicht ob es das kann |
| Structured Output (JSON-Schema) | Gleiche Formen | Auf deiner Seite weiter validieren, immer |
| System-Prompts | Funktionieren | Mit Nachjustieren der Formulierung rechnen, nicht der Struktur |
| Modellnamen | Ändern sich | Eine Stufe nutzen: eu-lite, eu-standard, eu-long, eu-pro |
| Verbrauch und Kosten | Ändern sich | Die Response-Header lesen statt eines Dashboards |
| Embeddings, Bilder, Sprache | Fehlen | Dafür deinen bisherigen Anbieter behalten |
| Batch-API | Fehlt | Auf der Roadmap, nicht ausgeliefert |
| Zustandsbehaftete API im Stil der Assistants | Fehlt | Nicht geplant; den Zustand auf deiner Seite halten |
Drei dieser Zeilen sind Lücken. Wir veröffentlichen sie als Liste auf der Startseite, statt dich mitten in der Migration darauf stoßen zu lassen. Denn „kompatibel“ ist ein Wort, das von Diensten überdehnt wurde, die den halben Vertrag umsetzen und das dann fertig nennen.
Warum aus Modellnamen Stufennamen werden
Du kaufst eine Stufe, kein Modell. eu-standard ist das Arbeitspferd, eu-long nimmt eine Million Tokens Kontext, eu-pro ist der starke Denker, und jede Stufe entspricht einem benannten Open-Weight-Modell, das mit seiner Lizenz auf der Seite zur KI-Transparenz steht.
Der Grund ist der ständige Wechsel. Open-Weight-Modelle werden alle paar Monate abgelöst, und wer den heutigen Modellnamen fest in seine Anwendung schreibt, muss bei jeder Bewegung im Feld neu deployen. Eine Stufe ist ein Versprechen zu Leistung und Preis, das den Austausch des Modells darunter übersteht. Und wenn wir es austauschen, sagen wir das, statt stillschweigend zu ändern, was dein Code tut.
Auch die Lizenzen zählen, und sie sind kurz genug, um sie zu lesen. Das meiste, was wir betreiben, steht unter Apache 2.0 oder MIT. Nur deshalb dürfen dieselben Gewichte überhaupt legal von europäischer Hardware ausgeliefert werden.

Was sich in den Antworten ändert, nicht in der API
Das ist der Teil, der Teams überrascht, also plan Zeit dafür ein. Ein Anbieterwechsel ist ein Modellwechsel, und Modelle unterscheiden sich auf eine Weise, die keine Kompatibilitätsschicht verbergen kann.
Die Formatierung driftet. Ein Prompt, der ein Modell zu sauberem Markdown bringt, erzeugt bei einem anderen vielleicht eine Vorrede. Meist eine Korrektur in einer Zeile, aber eben eine Korrektur.
Das Urteil beim Tool-Calling unterscheidet sich. Die Form eines Funktionsaufrufs ist identisch; die Bereitschaft des Modells, ihn auszuführen, nicht. Es gibt Modelle, die zu eifrig aufrufen, und Modelle, die aus dem Gedächtnis antworten.
Ablehnungen unterscheiden sich. Manche Open-Weight-Modelle weichen sachlichen Fragen zu Politik oder Geschichte aus. Wir behandeln das als Fehler, leiten einmal an ein Modell ohne diesen blinden Fleck um und sagen es dir im Header X-EU-Routed, wenn wir das getan haben. Ausführlich beschrieben ist das auf der Seite zur KI-Transparenz.
Die praktische Antwort ist ein Testset. Halte zwanzig echte Anfragen mit erwarteten Ausgaben bereit, lass sie gegen beide Anbieter laufen und lies die Unterschiede selbst. Zwanzig reichen, um Rückschritte bei Formatierung und Tool-Wahl zu erkennen, und sind wenig genug, dass du es wirklich machst.
Kosten und Abrechnung nach dem Wechsel
Abrechnung pro Token ist überall dieselbe Idee, aber wo du die Zahlen abliest, ändert sich. Jede Antwort trägt mit, was die Anfrage gekostet hat:
X-EU-Tokens-InundX-EU-Tokens-Out, die abgerechneten Tokens.X-EU-Cost-EUR, was für diese Anfrage von deinem Guthaben abgezogen wurde.X-EU-Balance-EUR, was noch übrig ist.X-EU-Model-Tier, welche Stufe sie tatsächlich ausgeführt hat.
Deine eigenen Logs beantworten die Kostenfrage also pro Funktion, pro Kunde, pro Endpunkt, ohne dass du auf eine Monatsrechnung warten musst, die dir widerspricht. Die Preise hinter diesen Zahlen stehen auf der Preisseite, und wie man allgemein über Token-Kosten nachdenkt, auch warum Output teurer ist als Input, erklärt was eine KI-API pro Token kostet.
Eine Gewohnheit, die du mitnehmen solltest: Setz max_tokens bei jedem Aufruf. Das ist die wirksamste Kostenkontrolle bei jeder API mit Abrechnung pro Token, und sie kostet eine Zeile.
Fehler, Limits und der 402, den du nicht behandelst
Deine Fehlerbehandlung deckt wahrscheinlich 429 und 500 ab. Vorausbezahltes Guthaben bringt einen weiteren Code mit.
- 402, Guthaben reicht nicht. Die Anfrage wird mit einem Link zum Aufladen abgelehnt, hinterher wird nichts in Rechnung gestellt, und dein Guthaben fällt nie unter null. Behandle das wie einen Auth-Fehler: Alarm auslösen, nicht in einer Schleife wiederholen.
- 429, Rate-Limit oder Obergrenze. Halte dich an
Retry-After. Die Obergrenzen legst du selbst fest, pro Schlüssel, in Euro pro Tag und pro Monat. - 502 und 503, Upstream nicht erreichbar. Mit Backoff wiederholen. Was bei einem Ausfall passiert und welche Einschränkung durch den einen Anbieter dahintersteckt, steht auf der Statusseite.
- Gescheiterte Anfragen sind kostenlos. Kam keine brauchbare Antwort zurück, wird nichts von deinem Guthaben abgezogen, und eine Anfrage, die an ein schwächeres Modell umgeleitet wurde, wird zum niedrigeren der beiden Preise abgerechnet.
Die Obergrenze für neue Konten erwischt jeden einmal: 25 € pro Tag in den ersten 48 Stunden, egal wie hoch dein Guthaben ist. Es gibt sie, weil ein geleakter Schlüssel am ersten Tag der teuerste Fehler ist, den eine neue Integration machen kann.
Macht Kompatibilität dich wirklich unabhängig?
Teilweise, und es lohnt sich, genau zu sagen, welcher Teil. Der Vertrag auf der Leitung ist übertragbar: Jeder Dienst, der Chat Completions spricht, lässt sich hinter demselben Client austauschen. Das allein beseitigt die gröbste Form von Lock-in, bei der ein Wechsel bedeutet, deine Integrationsschicht neu zu schreiben.
Nicht übertragbar ist alles, was du auf einem bestimmten Modell aufgebaut hast. Über Monate getunte Prompts, Few-Shot-Beispiele, die für die Eigenheiten eines Modells ausgesucht wurden, Evaluationssets, die am Ausgabestil eines Modells bewertet wurden, und jeder Schwellenwert, den du festgelegt hast, indem du dieses Modell beobachtet hast. Nichts davon wandert sauber mit, und nichts davon ist in einem Architekturdiagramm zu sehen.
Behandle das Modell deshalb als Abhängigkeit mit Versionsnummer, nicht als Konstante. Leg Prompts in Dateien ab, statt sie über den Code zu verstreuen, halte das Testset im Repo und schreib auf, warum ein Schwellenwert so ist, wie er ist. Teams, die das tun, wechseln den Anbieter an einem Nachmittag. Teams, die es nicht tun, verbringen ein Quartal damit herauszufinden, was ihre Prompts ausgeglichen haben.
Eine Checkliste für die Migration
Ein halber Tag für einen kleinen Dienst, ein Sprint für etwas mit echtem Traffic.
- Verschieb die Base-URL in die Konfiguration, falls sie dort noch nicht steht. Alles Weitere wird leichter, sobald das erledigt ist.
- Wähl eine Stufe nach Arbeitslast, nicht nach Namen. Klassifizieren und Extrahieren gehören auf die günstige Stufe; nur Arbeit mit viel Reasoning braucht die teure.
- Bau das Testset. Zwanzig echte Anfragen, erwartete Ausgaben, im Repo committet.
- Lass beide Anbieter parallel laufen, auf einem kleinen Teil des Traffics, und vergleiche die Ergebnisse.
- Bind die Kosten-Header in das ein, was du ohnehin loggst.
- Ergänze den 402-Pfad, und bei der Gelegenheit eine Obergrenze pro Schlüssel.
- Lass den alten Anbieter zwei Wochen konfiguriert. Eine Migration, die du mit einer Konfigurationsänderung rückgängig machen kannst, ist eine Migration, die du an einem Dienstag machen kannst.
Gegen welchen Anbieter du diese Evaluation fährst, ist eine eigene Frage, und die vier realistischen Optionen vergleichen wir in europäische KI-Anbieter im Vergleich. Die ersten zehn Anfragen sind kostenlos und die Mindestaufladung beträgt 10 €, die Evaluation kostet also weniger als das Meeting darüber, ob man sie machen soll. Den vollständigen Vertrag, mit kopierbarem curl und Python, findest du in der API-Dokumentation, und wo diese Anfragen verarbeitet werden, Station für Station, steht in wohin deine Prompts gehen.
Häufige Fragen
Was bedeutet OpenAI-kompatibel?
Es bedeutet, dass der Dienst denselben HTTP-Vertrag umsetzt wie der Chat-Completions-Endpunkt von OpenAI: derselbe Request-Body, dieselbe Form der Antwort, dasselbe Streaming-Format. Weil die offiziellen SDKs dünne Hüllen um diesen Vertrag sind, reicht es meist, eines davon auf eine andere Base-URL zu richten.
Wie wechsle ich von der OpenAI-API zu einem anderen Anbieter?
Tausch den API-Schlüssel aus, setz die base_url des Clients auf den neuen Anbieter und ersetze den Modellnamen. In den OpenAI-SDKs für Python und Node ist die Base-URL ein Konstruktor-Argument, die Änderung umfasst also drei Zeilen: den Schlüssel, die Base-URL und den Modellnamen.
Funktionieren Streaming und Function Calling nach dem Wechsel noch?
Bei Union AI ja. Streaming nutzt dasselbe Server-Sent-Events-Format und kann am Ende des Streams den Token-Verbrauch liefern, und Function Calling sowie Structured Output per JSON-Schema behalten dieselbe Form von Anfrage und Antwort. Anders ist das Urteil des Modells darüber, wann es ein Tool aufruft, und das solltest du testen.
Welche OpenAI-Funktionen fehlen bei kompatiblen APIs?
Das hängt vom Anbieter ab, und die ehrlichen veröffentlichen die Liste. Bei Union AI umfasst Version 1 nur den Chat-Completions-Vertrag: Es gibt keine Endpunkte für Embeddings, Bilder oder Sprache, keine Batch-API und keine zustandsbehaftete API im Stil der Assistants. Diese Lücken stehen auf der Roadmap, statt so zu tun, als gäbe es sie schon. Prüf also jeden kompatiblen Anbieter auf dieselben vier Lücken.
Liefern meine Prompts auf einem Open-Weight-Modell dieselben Antworten?
Nein, und zwei Modelle tun das nie. Formatierungsanweisungen, das Verhalten beim Tool-Calling und die Art, wie abgelehnt wird, verschieben sich. Behandle einen Anbieterwechsel deshalb als Modellwechsel: Halte zwanzig echte Anfragen als Testset bereit und vergleiche die Ausgaben, bevor du umschaltest.
Wie vergleiche ich die Kosten vor dem Wechsel?
Nimm eine Woche echten Traffic, zähle Input- und Output-Tokens getrennt und rechne beide Seiten zu ihren Listenpreisen pro Million Tokens. Output dominiert die meisten Rechnungen, ein Anbieter, der beim Input günstig aussieht, kann bei einer gesprächigen Last also trotzdem teurer sein.
Kann ich das OpenAI-SDK weiter nutzen?
Ja. Die offiziellen OpenAI-SDKs funktionieren unverändert mit jedem Dienst, der denselben Vertrag umsetzt, und genau darum geht es bei der Kompatibilität. Du behältst deine Retry-Logik, dein Streaming-Handling und deine Typen und änderst nur, wohin die Anfragen gehen.