Kurs
Die Verwaltung mehrerer APIs von KI-Anbietern kann schnell echt nervig werden. Jeder Anbieter hat seine eigenen Authentifizierungsmethoden, Preise und API-Spezifikationen. Entwickler verschwenden jede Menge Zeit damit, zwischen OpenAI, Anthropic, Google und anderen Plattformen hin und her zu springen, nur um an verschiedene Modelle zu kommen.
OpenRouter macht das Ganze einfacher, indem es eine einheitliche API bietet, die dich mit über 400 Modellen von vielen Anbietern verbindet. Du kannst auf GPT-5, Claude 4, Gemini 2.5 Pround hunderte andere Modelle mit einem einzigen API-Schlüssel und einer einheitlichen Schnittstelle. Die Plattform kümmert sich im Hintergrund um automatische Fallbacks, Kostenmanagement und die Weiterleitung an den richtigen Anbieter.
In diesem Tutorial erkläre ich dir alles, was du über OpenRouter wissen musst, von der Einrichtung deines ersten API-Aufrufs bis hin zur Implementierung fortgeschrittener Funktionen wie strukturierte Ausgaben. Am Ende weißt du, wie du zuverlässige Anwendungen entwickelst, die nicht an einen einzigen Anbieter gebunden sind.
Was ist OpenRouter?
OpenRouter ist eine einheitliche API-Plattform, mit der du über einen einzigen Endpunkt auf über 400 KI-Modelle von vielen Anbietern zugreifen kannst. Anstatt mit verschiedenen API-Schlüsseln für OpenAI, Anthropic, Google, Meta und andere rumzuspielen, brauchst du nur einen einzigen Schlüssel, um auf den ganzen Modellkatalog zugreifen zu können.
Die Plattform ist wie ein schlauer Router, der deine Anfragen an den richtigen Anbieter schickt und sich dabei um die Authentifizierung, Abrechnung und Fehlerbehandlung kümmert. Dieser Ansatz löst einige Probleme, die bei der Nutzung mehrerer KI-Anbieter auftreten.
Probleme, die OpenRouter löst
Mit mehreren KI-Anbietern zu arbeiten, kann schnell chaotisch werden. Jeder hat sein eigenes API-Format, seinen eigenen Anmeldeprozess und sein eigenes Abrechnungssystem. Am Ende musst du für jeden Dienst einen eigenen Code pflegen, was die Entwicklung verlangsamt und das Testen neuer Modelle ziemlich nervig macht.
Es wird noch schlimmer, wenn Anbieter ausfallen oder dich mit Ratenbeschränkungen nerven. Deine App funktioniert nicht mehr und du kannst nichts anderes machen, als abzuwarten. Außerdem musst du, um herauszufinden, welcher Anbieter den besten Preis für ähnliche Modelle hat, die Kosten auf verschiedenen Plattformen manuell verfolgen.
Das größte Problem ist, dass man an einen Anbieter gebunden ist. Wenn du alles um ihre spezielle API herum aufbaust, wird der Wechsel zu besseren Modellen oder günstigeren Optionen später zu einem großen Projekt.
Wie OpenRouter das Problem behebt
OpenRouter löst diese Probleme mit einer Reihe von verbundenen Funktionen:
- Ein API-Schlüssel funktioniert mit über 400 Modellen von allen großen Anbietern.
- Automatisch auf andere Anbieter umgeschaltet, wenn der erste nicht klappt
- Alle Preise für alle Modelle nebeneinander, damit du die Kosten sofort vergleichen kannst.
- Funktioniert mit dem vorhandenen OpenAI-Code – einfach die Endpunkt-URL ändern
- Echtzeit-Überwachung, die Anfragen an den schnellsten verfügbaren Anbieter weiterleitet
Diese Teile sorgen zusammen dafür, dass die KI-Entwicklung reibungsloser und zuverlässiger läuft.
Wer sollte OpenRouter nutzen?
Verschiedene Nutzer profitieren von diesem einheitlichen Ansatz:
- Entwickler können neue Modelle ausprobieren, ohne überall Konten einzurichten, was das Experimentieren beschleunigt.
- Unternehmen können sich auf die Verfügbarkeit verlassen, weil automatische Backups machen, falls die Anbieter mal ausfallen.
- Preisbewusste Nutzer können die günstigste Option für ihre Bedürfnisse finden, ohne lange Tabellen zu berechnen.
- Forscher können sofort auf die neuesten Modelle zugreifen, ohne erst einen Account anlegen zu müssen.
Jetzt, wo du weißt, was OpenRouter so drauf hat, lass uns deinen ersten API-Aufruf einrichten.
Was du schon wissen solltest
Bevor du dich mit OpenRouter beschäftigst, musst du ein paar Sachen auf deinem Rechner einrichten. Dieses Tutorial geht davon aus, dass du mit den Grundlagen der Python-Programmierung vertraut bist und schon mal mit APIs gearbeitet hast. Du musst kein Experte sein, solltest aber Sachen wie HTTP-Anfragen und den Umgang mit JSON-Antworten verstehen.
Du brauchst Python 3.7 oder höher auf deinem System installiert. Wir werden das Python-Paket „ openai “ verwenden, um mit der API von OpenRouter zu interagieren, sowie „ python-dotenv “, um Umgebungsvariablen sicher zu verarbeiten. Du kannst beides mit folgendem Befehl installieren:
pip install requests openai python-dotenv
Du brauchst außerdem ein OpenRouter-Konto und einen API-Schlüssel. Geh auf openrouter.ai und leg dir einen kostenlosen Account an – du bekommst ein kleines Guthaben, um alles auszuprobieren. Wenn du eingeloggt bist, geh in deinen Kontoeinstellungen zum Bereich „API-Schlüssel“ und erstelle einen neuen Schlüssel.
Nachdem du deinen API-Schlüssel hast, leg in deinem Projektverzeichnis eine Datei namens „ .env “ an und füge deinen Schlüssel so ein:
OPENROUTER_API_KEY=your_api_key_here
So bleibt dein API-Schlüssel sicher und kommt nicht in deinen Code. Wenn du vorhast, OpenRouter über die Testphase hinaus zu nutzen, musst du über die Seite „Credits“ Credits zu deinem Konto hinzufügen.
Mit diesen Grundlagen bist du bereit, deinen ersten API-Aufruf über OpenRouter zu machen.
Deinen ersten API-Aufruf in OpenRouter machen
Wenn du schon mal mit dem OpenAI SDK gearbeitet hast, ist der Einstieg in OpenRouter echt einfach. Du änderst einfach eine Zeile Code und schon hast du Zugriff auf hunderte Modelle von verschiedenen Anbietern.
Deine erste Anfrage und Einrichtung
Lass uns gleich mit einem Beispiel starten, das zeigt, wie OpenRouter funktioniert:
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
)
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "Write a haiku about debugging code at 2 AM"
}
]
)
print(response.choices[0].message.content)
Night hum, coffee cooled
cursor blinks, bug hides somewhere
I chase ghosts 'til dawn
Die Magie passiert an zwei Orten. Zuerst leitet der Parameter „ base_url “ deine Anfragen an die Server von OpenRouter statt an die von OpenAI weiter. Zweitens folgt der Modellname dem Format „ provider/model-name “ – also „ openai/gpt-5-mini “ statt nur „ gpt-5-mini “. Dadurch weiß OpenRouter, welche Version du haben willst, und die gewohnte Oberfläche bleibt erhalten. Hier sind ein paar gängige Modelle, die du ohne Probleme in das obige Beispiel einsetzen kannst:
- google/gemini-2.0-flash-001
- google/gemini-2.5-pro
- mistralai/mistral-nemo
- deepseek/deepseek-r1-distill-qwen-32b
Jetzt, wo du gesehen hast, wie einfach es ist, mit verschiedenen Modellen zu arbeiten, fragst du dich vielleicht: Was passiert, wenn das von dir gewählte Modell nicht verfügbar ist? Wie macht man Apps, die auch dann noch gut funktionieren, wenn die Anbieter Probleme haben? Hier kommen die Routing- und Ausfallsicherheitsfunktionen von OpenRouter ins Spiel.
Modell-Routing für Ausfallsicherheit
Um zuverlässige KI-Anwendungen zu entwickeln, muss man auf alles vorbereitet sein. Anbieter haben manchmal Ausfälle, Modelle erreichen ihre Hit-Limits und manchmal blockiert die Inhaltsmoderation deine Anfragen. Modell-Routing ist die Lösung von OpenRouter – es wechselt automatisch zwischen verschiedenen Modellen, damit deine Anwendung reibungslos läuft.
Manuelle Fallbacks einrichten
Der einfachste Weg, die Ausfallsicherheit zu erhöhen, ist die Festlegung von Backup-Modellen. Wenn deine erste Wahl nicht klappt, probiert OpenRouter die Alternativen der Reihe nach aus. Der Parameter „ extra_body “ gibt diese Routing-Anweisungen an die API von OpenRouter weiter, da das SDK „OpenAI SDK“ nicht über eine API verfügt. OpenAI SDK diese Funktion nicht von Haus aus unterstützt:
response = client.chat.completions.create(
model="moonshotai/kimi-k2", # Primary choice
messages=[
{"role": "user", "content": "Explain quantum computing in simple terms"}
],
extra_body={
"models": ["anthropic/claude-sonnet-4", "deepseek/deepseek-r1"]
}
)
print(f"Response from: {response.model}")
print(response.choices[0].message.content)
Response from: moonshotai/kimi-k2
Imagine a normal computer bit as a tiny light-switch that can only be OFF (0) or ON (1)...
OpenRouter probiert zuerst Kimi-K2 aus. Wenn es nicht verfügbar, ratenbegrenzt oder gesperrt ist, wird automatisch Claude Sonnet 4 und dann DeepSeek R1 ausprobiert. Das Feld „ response.model “ zeigt an, welches Modell tatsächlich geantwortet hat.
Automatische Wegeleitung für maximalen Komfort
Sobald du manuelle Fallbacks verstanden hast, wird der Auto-Router richtig interessant. Die Modellauswahl und Fallbacks werden automatisch erledigt, dank NotDiamonds Bewertungssystem:
response = client.chat.completions.create(
model="openrouter/auto",
messages=[
{"role": "user", "content": "Debug this Python code in 3 sentences: def factorial(n): return n * factorial(n-1)"}
]
)
print(f"Auto router selected: {response.model}")
print(response.choices[0].message.content)
Auto router selected: openai/chatgpt-4o-latest
The given code is missing a base case, which causes infinite recursion and eventually a RecursionError. To fix it, add a base case like `if n == 0: return 1` before the recursive call. Here's the corrected version:
\```python
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
\```
Der Auto-Router schaut sich deine Eingabe an und sucht das beste verfügbare Modell. Wenn deine erste Wahl nicht verfügbar ist, gibt es eingebaute Alternativen. Du bekommst Ausfallsicherheit ohne irgendwas einzurichten. Sei aber vorsichtig mit dem Auto-Router, wenn es um heikle oder wichtige Sachen geht, weil er die Komplexität deines Problems oft unterschätzt und dann ein Modell mit weniger Kapazität wählt.
Effektive Ausweichstrategien entwickeln
Nicht alle Modelle sind gut als Ersatz für einander geeignet. Ausfälle bei einem Anbieter können alle Modelle dieses Unternehmens betreffen. Wähle daher Ausweichlösungen von verschiedenen Anbietern. Die Ratenbeschränkungen und Kosten können ganz unterschiedlich sein, also kombiniere teure Modelle mit günstigeren Alternativen:
# Good fallback chain: different providers, decreasing cost
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[
{"role": "user", "content": "Your prompt here"}
],
extra_body={
"models": [
"x-ai/grok-4", # Close performance
"moonshotai/kimi-k2", # Cheaper
"deepseek/deepseek-r1:free" # Free backup
]
}
)
So kriegst du erstklassige Qualität, wenn sie verfügbar ist, zuverlässige Leistung als Backup und garantierte Verfügbarkeit als letzte Option. Die Richtlinien zur Moderation von Inhalten sind auch bei den Anbietern unterschiedlich, sodass du mit einer diversifizierten Kette sensible Themen besser abdecken kannst.
Modelle für deine Fallback-Kette finden
Auf der Seite „Modelle“ kannst du nach Anbieter und Funktionen filtern, um deine Kette zusammenzustellen. Viele leistungsstarke Modelle wie DeepSeek R1 und Kimi-K2 sind kostenlos, weil sie Open Source sind, und eignen sich daher super als Ersatz. Kostenlose Modelle haben eine Begrenzung von 50 Anfragen pro Tag für neue Nutzer oder 1000 Anfragen pro Tag, wenn du 10 Credits gekauft hast.
Für dynamische Anwendungen kannst du Modelle programmgesteuert finden:
def get_provider_models(api_key: str, provider: str) -> list[str]:
r = requests.get(
"https://openrouter.ai/api/v1/models",
headers={"Authorization": f"Bearer {api_key}"}
)
return [m["id"] for m in r.json()["data"] if m["id"].startswith(provider)]
# Build fallbacks across providers
openai_models = get_provider_models(api_key, "openai/")
anthropic_models = get_provider_models(api_key, "anthropic/")
Mit diesem Ansatz kannst du robuste Fallback-Ketten aufbauen, die sich anpassen, wenn neue Modelle verfügbar werden.
Streaming für Echtzeit-Antworten
Bei der Arbeit mit KI-Modellen, vor allem bei längeren Antworten, wollen die Nutzer, dass die Ausgabe nach und nach angezeigt wird, anstatt auf die komplette Antwort zu warten. Streaming löst das, indem es Antwortteile sendet, sobald sie generiert werden, und so ein interaktiveres Erlebnis schafft, ähnlich wie bei der ChatGPT-Oberfläche.
Grundlegende Streaming-Einrichtung
Um Streaming in OpenRouter einzurichten, füge „ stream=True “ zu deiner Anfrage hinzu. Die Antwort wird zu einem Iterator, der Teile ausgibt, sobald das Modell sie generiert:
response = client.chat.completions.create(
model="openai/gpt-5",
messages=[
{"role": "user", "content": "Write a detailed explanation of how neural networks learn"}
],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")
Jeder Chunk hat ein kleines Stück der Antwort. Das Feld „ delta.content “ enthält das neue Textfragment, das wir sofort ohne Zeilenumbruch ausgeben, um den Streaming-Effekt zu erzielen. Der Parameter „ end="" “ verhindert, dass print neue Zeilen zwischen den Blöcken einfügt.
Einen besseren Streaming-Handler erstellen
Für Produktionsanwendungen brauchst du mehr Kontrolle über den Streaming-Prozess. Hier ist ein umfassenderer Handler, der die ganze Antwort abwickelt:
def stream_response(model, messages, show_progress=True):
response = client.chat.completions.create(
model=model,
messages=messages,
stream=True
)
complete_response = ""
for chunk in response:
if chunk.choices[0].delta.content is not None:
content = chunk.choices[0].delta.content
complete_response += content
if show_progress:
print(content, end="", flush=True)
if show_progress:
print() # Add final newline
return complete_response
# Use it with different models
result = stream_response(
"anthropic/claude-sonnet-4",
[{"role": "user", "content": "Explain quantum entanglement like I'm 12 years old"}]
)
Dieser Handler fängt die ganze Antwort ab, während er den Fortschritt anzeigt, gibt dir sowohl das Streaming-Erlebnis als auch den endgültigen Text und sorgt für die richtige Ausgabeformatierung.
Streaming verändert die Nutzererfahrung von „Warten und Hoffen“ zu „Beobachten, wie es vorangeht“. Dadurch fühlen sich deine KI-Anwendungen für die Nutzer viel reaktionsschneller und ansprechender an.
Umgang mit Argumentationstoken in OpenRouter
Einige KI-Modelle können dir ihren „Denkprozess“ zeigen, bevor sie ihre endgültige Antwort geben. Diese Argumentationstoken zeigen ganz klar, wie das Modell komplexe Probleme angeht, und zeigen Schritt für Schritt, wie es zu seinen Schlussfolgerungen kommt. Wenn du diese interne Logik verstehst, kannst du Antworten besser überprüfen, Probleme im Modellverhalten beheben und zuverlässigere Anwendungen erstellen.
Was sind Argumentationstoken?
Begründungstoken werden in einem separaten Feld „ reasoning “ in der Antwort angezeigt, das sich vom Hauptinhalt unterscheidet. Verschiedene Modelle unterstützen das Schlussfolgern auf unterschiedliche Weise – manche nutzen Aufwandstufen, andere Token-Budgets.
Hier ist ein einfaches Beispiel, das zeigt, wie das funktioniert:
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[
{"role": "user", "content": "How many 'r's are in the word 'strrawberry'?"}
],
max_tokens=2048,
extra_body={
"reasoning": {
"max_tokens": 512
}
}
)
print("Final answer:")
print(response.choices[0].message.content)
print("\nReasoning process:")
print(response.choices[0].message.reasoning)
Final answer:
To count the 'r's in 'strrawberry', I'll go through each letter:
...
There are **4** 'r's in the word 'strrawberry'.
Reasoning process:
...
Das Modell zeigt sowohl die endgültige Antwort als auch die inneren Gedankengänge, die zu dieser Schlussfolgerung geführt haben. Mit dieser doppelten Ausgabe kannst du besser verstehen, ob das Modell das Problem richtig angegangen ist.
Kontrolle der Intensität des Denkens
Du kannst mit zwei Methoden steuern, wie viel Denkaufwand die Modelle in ihre Antworten stecken. Der Parameter „ effort “ funktioniert mit Modellen wie der o-Serie von OpenAI und nutzt Stufen, die bestimmten Token-Prozentsätzen entsprechen, basierend auf deiner Einstellung „ max_tokens “:
- Hoher Aufwand: Verwendet ungefähr 80 % von „
max_tokens“ für die Argumentation. - Mittlere Anstrengung: Verwendet ungefähr 50 % von „
max_tokens“ für die Argumentation. - Einfacher „ ”: Verwendet ungefähr 20 % von „
max_tokens“ für die Argumentation.
# High effort reasoning for complex problems
response = client.chat.completions.create(
model="deepseek/deepseek-r1",
messages=[
{"role": "user", "content": "Solve this step by step: If a train travels 240 miles in 3 hours, then speeds up by 20 mph for the next 2 hours, how far does it travel total?"}
],
max_tokens=4000, # High effort will use ~3200 tokens for reasoning
extra_body={
"reasoning": {
"effort": "high"
}
}
)
print("Problem solution:")
print(response.choices[0].message.content)
print("\nStep-by-step reasoning:")
print(response.choices[0].message.reasoning)
Bei Modellen, die die direkte Token-Zuweisung unterstützen, wie die Modelle von Anthropic, kannst du genaue Reasoning-Budgets festlegen:
def get_reasoning_response(question, reasoning_budget=2000):
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[{"role": "user", "content": question}],
max_tokens=10000,
extra_body={
"reasoning": {
"max_tokens": reasoning_budget # Exact token allocation
}
}
)
return response
# Compare different reasoning budgets
response = get_reasoning_response(
"What's bigger: 9.9 or 9.11? Explain your reasoning carefully.",
reasoning_budget=3000
)
print("Answer:", response.choices[0].message.content)
print("Detailed reasoning:", response.choices[0].message.reasoning)
Mehr Geld für Token führt normalerweise zu gründlicherem Nachdenken, während weniger Geld schnellere, aber weniger detaillierte Denkprozesse bringt.
Das Erhalten von Argumentationen in Gesprächen
Wenn du längere Unterhaltungen aufbaust, musst du sowohl die Argumentation als auch die endgültige Antwort im Auge behalten, damit der Kontext klar bleibt. Das ist besonders wichtig bei komplizierten Diskussionen, wo der Denkprozess des Modells die nächsten Antworten beeinflusst:
# First message with reasoning
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[
{"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."}
],
extra_body={
"reasoning": {
"max_tokens": 3000
}
}
)
# Build conversation history with reasoning preserved
messages = [
{"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."},
{
"role": "assistant",
"content": response.choices[0].message.content,
"reasoning_details": response.choices[0].message.reasoning_details # Preserve reasoning
},
{"role": "user", "content": "What about solar energy specifically? How does that change your analysis?"}
]
# Continue conversation with reasoning context
follow_up = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=messages,
extra_body={
"reasoning": {
"max_tokens": 2000
}
}
)
print("Follow-up answer:")
print(follow_up.choices[0].message.content)
print("\nContinued reasoning:")
print(follow_up.choices[0].message.reasoning)
Das Feld „ reasoning_details “ speichert die ganze Argumentationskette, sodass das Modell bei der Beantwortung von Folgefragen auf der vorherigen Analyse aufbauen kann. Dadurch werden Gespräche kohärenter und kontextbezogener.
Überlegungen zu Kosten und Abrechnung
Reasoning-Token werden wie normale Token abgerechnet, also erhöhen sie deine Kosten. Oft verbessern sie aber die Antwortqualität so sehr, dass sich die Kosten lohnen, vor allem bei komplizierten Aufgaben, bei denen Genauigkeit wichtiger ist als Geschwindigkeit. Laut der Dokumentation von OpenRouterkönnen Reasoning-Tokens die Leistung von Modellen bei schwierigen Problemen verbessern und gleichzeitig den Entscheidungsprozess transparenter machen.
Für Anwendungen, bei denen es auf die Kosten ankommt, kannst du die Qualität der Schlussfolgerungen gegen die Kosten abwägen, indem du den Aufwand oder das Token-Budget je nach Komplexität der Aufgabe anpasst. Einfache Fragen brauchen vielleicht gar keine Begründung, während komplexe Probleme von einer gründlichen Begründung profitieren.
Arbeiten mit multimodalen Modellen in OpenRouter
Bisher hast du mit Text gearbeitet, aber was ist, wenn du Bilder oder Dokumente analysieren musst? Vielleicht möchtest du Fragen zu einem Diagramm stellen, Infos aus einem PDF herausholen oder beschreiben, was auf einem Foto zu sehen ist. Hier kommt multimodale Modelle ins Spiel – sie können sowohl Text als auch visuelle Inhalte in derselben Anfrage verstehen.
Multimodale Funktionen verstehen
Anstatt ein Bild mit Worten zu beschreiben, kannst du einfach das Bild schicken und direkt Fragen dazu stellen. Dadurch werden deine Anwendungen viel intuitiver, da das Modell genau sieht, womit du gerade arbeitest. Du musst nicht raten, ob deine Textbeschreibung alle wichtigen Details enthält.
Du kannst multimodale Modelle über dieselbe Oberfläche nutzen, die du schon kennst, nur mit einem zusätzlichen Parameter „ attachments “, um deine visuellen Inhalte einzubinden. Dateianhänge funktionieren bei allen Modellen auf OpenRouter. Selbst wenn ein Modell PDFs oder Bilder nicht direkt unterstützt, analysiert OpenRouter diese Dateien intern und gibt den Inhalt an das Modell weiter.
Arbeiten mit Bildern
Du kannst Bilder über URLs oder Base64-Kodierung in deine Anfragen einfügen. Wenn dein Bild schon online ist, ist es mit der URL einfacher:
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "What's happening in this image? Describe the scene in detail."
}
],
extra_body={
"attachments": [
{
"type": "image/jpeg",
"url": "https://example.com/photo.jpg"
}
]
}
)
print(response.choices[0].message.content)
Für lokale Bilder kannst du die Kodierung „ base64 “ verwenden:
import base64
def encode_image_to_base64(image_path):
with open(image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
return encoded_string
# Analyze a local screenshot
encoded_image = encode_image_to_base64("screenshot.png")
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "This is a screenshot of a data dashboard. What insights can you extract from the charts and metrics shown?"
}
],
extra_body={
"attachments": [
{
"type": "image/png",
"data": encoded_image
}
]
}
)
print(response.choices[0].message.content)
Das Modell schaut sich das Bild an und gibt dir genaue Infos darüber, was es sieht, nicht nur irgendwelche allgemeinen Antworten.
PDF-Dokumente bearbeiten
Die PDF-Bearbeitung funktioniert genauso, ermöglicht aber zusätzlich eine Analyse des Dokuments. Du kannst Fragen zu Berichten stellen, Formulare analysieren oder Infos aus komplizierten Dokumenten rausholen:
def encode_pdf_to_base64(pdf_path):
with open(pdf_path, "rb") as pdf_file:
encoded_string = base64.b64encode(pdf_file.read()).decode('utf-8')
return encoded_string
# Analyze a research paper
encoded_pdf = encode_pdf_to_base64("research_paper.pdf")
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "Summarize the key findings from this research paper. What are the main conclusions and methodology used?"
}
],
extra_body={
"attachments": [
{
"type": "application/pdf",
"data": encoded_pdf
}
]
}
)
print(response.choices[0].message.content)
Das ist super für Finanzberichte, wissenschaftliche Arbeiten, Verträge oder alle PDFs, bei denen du eine KI-Analyse des Inhalts brauchst. Du kannst auch mehrere Anhänge in einer Anfrage mitschicken, wenn du Bilder vergleichen oder mehrere Dokumente zusammen analysieren musst.
Kosten und Modellauswahl
Multimodale Anfragen kosten mehr als reine Textanfragen, weil du zusätzliche Datentypen verarbeitest. Bilder und PDFs brauchen mehr Rechenleistung, was sich in den Preisen zeigt. Die spezifischen Preise für die verschiedenen Modelle mit mehreren Optionen findest du auf der Modellseite.
Verschiedene Modelle haben unterschiedliche Stärken bei visuellen Inhalten. Einige sind besser in der detaillierten Bildanalyse, während andere beim Verstehen von Dokumenten richtig gut sind. Probier einfach verschiedene Modelle aus, um das beste für deine Bedürfnisse und dein Budget zu finden.
Strukturierte Ausgaben nutzen
Wenn du echte Anwendungen entwickelst, brauchst du Datenformate, die du vorhersagen kannst und die dein Code zuverlässig lesen kann. Freiformtextantworten sind super für Chat-Schnittstellen, aber echt nervig für Anwendungen, die bestimmte Infos brauchen. Statt unvorhersehbare Texte zurückzubekommen, die du mit Regex analysieren musst oder auf die richtige Formatierung durch das Modell hoffen musst, sorgen strukturierte Ausgaben dafür, dass Modelle garantiert JSON mit genau den Feldern und Datentypen zurückgeben, die du brauchst. Dadurch werden Parsing-Fehler vermieden und dein Anwendungscode wird viel einfacher.
Aufbau von strukturierten Ausgabeanfragen
Strukturierte Ausgaben verwenden einen Parameter „ response_format “ mit dieser grundlegenden Struktur:
"response_format": {
"type": "json_schema", # Always this for structured outputs
"json_schema": {
"name": "your_schema_name", # Name for your schema
"strict": True, # Enforce strict compliance
"schema": {
# Your actual JSON schema definition goes here
}
}
}
Beispiel für eine Stimmungsanalyse
Schauen wir uns mal ein komplettes Beispiel an, wo die Stimmung aus einem Text rausgeholt wird. Das zeigt, wie strukturierte Ausgaben in der Praxis funktionieren:
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{"role": "user", "content": "Analyze the sentiment: 'This movie was absolutely terrible!'"}
],
extra_body={
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "sentiment_analysis",
"strict": True,
"schema": {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"confidence": {"type": "number"}
},
"required": ["sentiment", "confidence"]
}
}
}
}
)
import json
result = json.loads(response.choices[0].message.content)
print(result)
{'sentiment': 'negative', 'confidence': 0.98}
Hier ist, was in diesem Schema passiert:
sentiment: Ein Zeichenfolgenfeld, das mit „enum“ auf drei bestimmte Werte beschränkt ist. Das Modell kann nichts anderes als „positiv“, „negativ“ oder „neutral“ zurückgeben.confidence: Ein Zahlenfeld für den Vertrauenswert des Modellsrequired: Beide Felder müssen in der Antwort da sein – das Modell kann sie nicht überspringen.strict: True: Sorgt dafür, dass die Schemastruktur strikt eingehalten wird.
Ohne strukturierte Ergebnisse bekommst du vielleicht Antworten wie „Die Stimmung ist sehr negativ mit hoher Zuverlässigkeit“ oder „Negativ (95 % sicher)“. Mit dem Schema bekommst du immer JSON, das du sofort in deinem Code verwenden kannst.
Wenn du „ strict: True “ aktivierst, wird das Schema streng eingehalten – das Modell kann nicht von deiner Struktur abweichen. Das Array „ required “ sagt, welche Felder da sein müssen. Du kannst „ enum “ verwenden, um Werte auf bestimmte Optionen zu beschränken, „ array “ für Listen und verschachtelte „ object “-Typen für komplexe Daten.
Modellkompatibilität
Nicht alle Modelle können strukturierte Ausgaben, aber die meisten modernen schon. Du kannst die Modellseite. Wenn ein Modell strukturierte Ausgaben nicht von Haus aus unterstützt, kümmert sich OpenRouter oft intern um die Formatierung.
Strukturierte Ausgaben machen KI-Antworten aus unvorhersehbaren Texten zu zuverlässigen Daten, auf die sich deine Anwendungen verlassen können. Für jeden Produktionsfall, in dem du konsistente Datenextraktion brauchst, ist diese Funktion unverzichtbar.
Fazit
Wir haben gelernt, wie man über die einheitliche API von OpenRouter auf Hunderte von KI-Modellen zugreifen kann, von der ersten Anfrage bis zur Implementierung von Funktionen wie Streaming, Reasoning-Tokens und strukturierten Ausgaben.
Dank der automatischen Ausweichmechanismen und dem Modell-Routing der Plattform bleiben deine Anwendungen auch dann zuverlässig, wenn einzelne Anbieter Probleme haben. Mit denselben Codemustern können wir Modelle vergleichen, Anbieter wechseln und die perfekte Lösung für jede Aufgabe finden, ohne mehrere API-Schlüssel verwalten zu müssen.
Probier's einfach mal mit einfachen Anfragen aus und probier nach und nach mehr Funktionen aus, wenn du mehr brauchst. Probier verschiedene Modelle für unterschiedliche Aufgaben aus – manche funktionieren besser für kreatives Schreiben, andere sind besser bei Datenanalyse oder logischen Problemen.
Mit dem Wissen, das du hier bekommen hast, kannst du KI-Anwendungen entwickeln, die nicht an einen bestimmten Anbieter gebunden sind. So kannst du dich ganz flexibel anpassen, wenn neue Modelle und Funktionen verfügbar werden.

Ich bin ein Data Science Content Creator mit über 2 Jahren Erfahrung und einem der größten Follower auf Medium. Ich schreibe gerne ausführliche Artikel über KI und ML mit einem etwas sarkastischen Stil, denn man muss etwas tun, damit sie nicht so langweilig sind. Ich habe mehr als 130 Artikel verfasst und einen DataCamp-Kurs gemacht, ein weiterer ist in Vorbereitung. Meine Inhalte wurden von über 5 Millionen Augenpaaren gesehen, von denen 20.000 zu Followern auf Medium und LinkedIn wurden.
