Einführung
Mit dem Eintritt in das Jahr 2025 hat die OpenAI API einen wichtigen Wendepunkt erreicht. Im März 2025 wurde die Responses API offiziell veröffentlicht (GA) und konsolidiert die Konversationsfähigkeiten der Chat Completions API und die Tool-Integrationsfunktionen der Assistants API zu einem einzigen Endpunkt. Die Legacy Assistants API ist für die Abschaltung am 26. August 2026 vorgesehen.
Darüber hinaus entfaltet Structured Outputs, das sicherstellt, dass Modellausgaben strikt einem JSON-Schema entsprechen, in Kombination mit der Responses API sein volles Potenzial. Seit seiner Veröffentlichung im August 2024 hat es die Zuverlässigkeit von Agentic Workflows und Datenextraktionspipelines erheblich verbessert.
Dieser Artikel gibt zunächst einen Überblick über die OpenAI API-Landschaft 2025 und taucht dann in die Spezifikationen und Implementierungsdetails dieser beiden Schlüsselthemen ein.
Quellinformationen
Spezifikationen und Performance-Daten in diesem Artikel beziehen sich auf die OpenAI Offizielle Dokumentation (developers.openai.com/api), den Offiziellen Migrationsguide (developers.openai.com/api/docs/guides/migrate-to-responses) und den Offiziellen Blog (openai.com/index/introducing-structured-outputs-in-the-api).
1. API-Übersicht
Die wichtigsten Kategorien der OpenAI API 2025 sind wie folgt organisiert:
| Kategorie | Endpunkt | Positionierung |
|---|---|---|
| Responses API | POST /v1/responses |
Empfohlen für neue Projekte. Einheitliches Interface für Agenten. |
| Chat Completions API | POST /v1/chat/completions |
Weiterhin unterstützt (kein geplantes Deprecation). |
| Realtime API | WebRTC / WebSocket / SIP | Bidirektionale Echtzeit-Sprache und Text. |
| Embeddings | POST /v1/embeddings |
Vektorsuche und RAG. |
| Images | POST /v1/images/generations |
Bildgenerierung und -bearbeitung. |
| Audio | POST /v1/audio/transcriptions |
Spracherkennung und TTS. |
OpenAI hat die Responses API als primäres Ziel für neue Funktionen positioniert, und die Abschaltung der Assistants API am 26. August 2026 ist offiziell bestätigt (Quelle: Offizieller Migrationsguide). Während die Chat Completions API ohne Abschaltungsdatum weiter unterstützt wird, ist die Responses API die aktuelle Empfehlung für neue Projekte.
Structured Outputs ist kein unabhängiger Endpunkt wie jene in der obigen Tabelle, sondern eine Ausgabeformat-Steueroption, die sowohl für die Responses API als auch für die Chat Completions API verfügbar ist. Sie wird mit dem Parameter text.format bei ersterer und dem Parameter response_format bei letzterer angegeben. Dieser Artikel konzentriert sich besonders auf die Kombination mit der Responses API.
2. Responses API
2.1 Übersicht
Die Responses API ist ein neues Primitiv, das die Chat Completions API ablöst und die Funktionen der Assistants API integriert. Sie erreichte im März 2025 die General Availability (GA).
Die bedeutendste Änderung ist die Fähigkeit, Konversationsstatus serverseitig zu persistieren. Im Gegensatz zu herkömmlichen Chat Completions, bei denen die gesamte Konversationsgeschichte in jede Anfrage einbezogen werden musste, ermöglicht die Responses API das Fortsetzen einer Konversation durch einfaches Übergeben einer previous_response_id.
2.2 Grundlegende Anfrage
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-4o",
input: "Tell me the weather in Tokyo.",
});
console.log(response.output_text); // Text direkt mit dem output_text-Helfer abrufen
2.3 Der output_text-Helfer
output_text ist eine vom OpenAI SDK bereitgestellte Convenience-Eigenschaft, kein Teil der API-Spezifikation selbst.
In der rohen Antwort der Responses API ist der Text innerhalb folgender Struktur verschachtelt:
response.output[0].content[0].text
output_text fasst das Traversieren dieses Pfades zusammen. Intern gibt es den Text des ersten Elements im output-Array zurück, das type: "message" und einen content-Block mit type: "output_text" hat.
// Beides ergibt die gleiche Ausgabe
console.log(response.output_text);
console.log(response.output[0].content[0].text);
Es funktioniert jedoch möglicherweise nicht wie erwartet, wenn das erste Element im output-Array keine Textnachricht ist – zum Beispiel wenn ein Tool-Aufruf stattfindet. Für robusten Agentic-Code, der Tools verwendet, ist es besser, das output-Array zu durchlaufen und den type zu prüfen.
for (const item of response.output) {
if (item.type === "message") {
for (const block of item.content) {
if (block.type === "output_text") {
console.log(block.text);
}
}
}
}
2.4 role in Input-Nachrichten
Beim Übergeben eines Arrays an input können Sie für jede Nachricht eine role angeben. Die role teilt dem Modell mit, „wer diese Aussage macht", und es gibt drei Typen.
| role | Bedeutung | Typische Verwendung |
|---|---|---|
system |
Anweisungen vom System (Entwickler) | Definiert das Verhalten, den Ton und die Einschränkungen des Modells. Generell einmal am Anfang einer Konversation platziert. |
user |
Eingabe vom Endbenutzer | Repräsentiert die Aussagen oder Fragen des Benutzers. |
assistant |
Eigene vergangene Aussagen des Modells | In Multi-Turn-Konversationen verwendet, um frühere Antworten als Geschichte bereitzustellen. |
const response = await client.responses.create({
model: "gpt-4o",
input: [
{
role: "system",
content: "You are a helpful Japanese assistant. Please answer concisely.",
},
{
role: "user",
content: "Tell me about JavaScript array methods.",
},
],
});
Wenn Sie einen String direkt an input übergeben (wie im Beispiel in 2.2), wird dieser String als Nachricht mit role: "user" behandelt. Verwenden Sie das Array-Format, wenn Sie eine feinkörnige Kontrolle über das Modellverhalten wünschen oder system-Anweisungen bereitstellen möchten.
2.5 Antwortstruktur
Im Gegensatz zu choices bei Chat Completions werden Ergebnisse in einem output-Array zurückgegeben.
{
"id": "resp_68af4030...",
"object": "response",
"created_at": 1756315696,
"model": "gpt-4o",
"output": [
{
"id": "msg_68af4033...",
"type": "message",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "The weather in Tokyo is sunny."
}
]
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 12,
"total_tokens": 27
}
}
2.6 Multi-Turn-Konversation
Es gibt zwei Möglichkeiten, Multi-Turn-Konversationen mit der Responses API zu realisieren.
1. Verlauf als Array in input übergeben
Dies ist die traditionelle Methode aus der Chat Completions API. Sie verwenden und verwalten die Konversationsgeschichte clientseitig und fügen alle Nachrichten in jede Anfrage ein.
const history = [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Tell me the weather in Tokyo." },
{ role: "assistant", content: "It is sunny in Tokyo today." },
];
const response = await client.responses.create({
model: "gpt-4o",
input: [...history, { role: "user", content: "How about tomorrow?" }],
});
Da kein State auf dem Server gespeichert wird, besteht der Vorteil darin, dass Sie den Verlauf frei bearbeiten können, z. B. bestimmte Nachrichten löschen oder zusammenfassen. Mit zunehmender Konversationslänge steigt jedoch die Anzahl der Input-Tokens, was Kosten und Latenz beeinflusst.
2. previous_response_id übergeben (exklusiv für die Responses API)
Dies ist die serverseitige State-Management-Methode, die neu mit der Responses API eingeführt wurde. Durch einfaches Übergeben der vorherigen Antwort-ID werden die OpenAI-Server die Konversationsgeschichte übertragen.
// Erster Turn
const response1 = await client.responses.create({
model: "gpt-4o",
input: "Tell me the weather in Tokyo.",
});
// Zweiter Turn: Kontext wird nur mit previous_response_id geerbt
const response2 = await client.responses.create({
model: "gpt-4o",
input: "How about tomorrow?",
previous_response_id: response1.id,
});
Der Client muss den gesamten Verlauf nicht verwalten oder senden, was die Anfragegröße klein hält. Darüber hinaus werden bei Reasoning-Modellen wie o1 oder o3 die Thinking-Tokens zwischen Turns persistiert, was ein erheblicher Vorteil ist, da die Genauigkeit für Aufgaben, die kontinuierliches Reasoning erfordern, verbessert wird.
Um diese Methode zu verwenden, muss die Antwort auf dem Server gespeichert werden. Beachten Sie, dass das Setzen von store: false eine Referenzierung per ID unmöglich macht, obwohl der Parameter store standardmäßig auf true steht.
Auswahlkriterien
| Situation | Empfohlene Methode |
|---|---|
| Verlauf auf halbem Weg ändern/bearbeiten müssen (RAG-Injektion, alte Nachrichten löschen usw.) | ① Array-basiert |
| Komplexe Multi-Turn-Probleme mit Reasoning-Modellen lösen (o1, o3 usw.) | ② previous_response_id |
| Einfacher Chat, bei dem manuelle Verlaufsverwaltung vermieden werden soll | ② previous_response_id |
| Chat Completions API verwenden | ① Array-basiert (previous_response_id ist nur für Responses API) |
2.7 Eingebaute Tools
Einer der größten Vorteile der Responses API ist der Satz von eingebauten Tools, die ohne zusätzliche Infrastruktur verfügbar sind.
const response = await client.responses.create({
model: "gpt-4o",
input: "Search for the latest OpenAI news and summarize it.",
tools: [
{ type: "web_search_preview" },
{ type: "file_search" },
{ type: "code_interpreter" },
],
});
| Tool | Zweck |
|---|---|
web_search_preview |
Websuche äquivalent zu ChatGPT. |
file_search |
RAG-Suche über hochgeladene Dateien. |
code_interpreter |
Code-Ausführung und Datenanalyse. |
computer_use |
Computer-Bedienungsagent. |
mcp |
Verbindung mit Drittanbieter-MCP-Servern. |
MCP (Model Context Protocol)-Integration
Connectors sind von OpenAI verwaltete MCP-Wrapper für beliebte Dienste wie Google Workspace oder Dropbox, während Remote MCP Server beliebige Server im öffentlichen Internet sind, die das Remote-MCP-Protokoll implementieren (Quelle: OpenAI Connectors and MCP Guide).
Die Responses API kann mit Remote-MCP-Servern integriert werden, die Streamable HTTP- oder HTTP/SSE-Transportprotokolle unterstützen. Wenn ein Tool angegeben wird, ruft die API zunächst die Liste der verfügbaren Tools vom Server ab (mcp_list_tools), und das Modell ruft dann die notwendigen Tools aus dieser Liste auf.
Grundlegendes Verbindungsbeispiel (Quelle: OpenAI Using tools Guide)
const response = await client.responses.create({
model: "gpt-4o",
input: "Roll 2d6 and tell me the result.",
tools: [
{
type: "mcp",
server_label: "dice_server", // Bezeichner für den Server (beliebig)
server_url: "https://example.com/mcp", // URL des MCP-Servers
require_approval: "never", // Tool-Aufrufe automatisch genehmigen
},
],
});
console.log(response.output_text);
Genehmigungssteuerung mit require_approval
Standardmäßig erfordern alle Tool-Aufrufe die explizite Genehmigung des Entwicklers. Mit require_approval kann dieses Verhalten gesteuert werden (Quelle: OpenAI Connectors and MCP Guide).
require_approval-Wert |
Verhalten |
|---|---|
"never" |
Alle Tool-Aufrufe automatisch genehmigen. |
{ never: { tool_names: [...] } } |
Angegebene Tools automatisch genehmigen; andere erfordern Genehmigung. |
| Weggelassen (Standard) | Alle Tool-Aufrufe erfordern Genehmigung. |
2.8 Wichtige Anfrageparameter
| Parameter | Typ | Beschreibung |
|---|---|---|
model |
string | Modellname (z. B. gpt-4o). |
input |
string / array | Text- oder multimodale Eingabe. |
previous_response_id |
string | Vorherige Antwort-ID für Multi-Turn. |
tools |
array | Definitionen der zu verwendenden Tools. |
text.format |
object | Spezifikation für Structured Outputs (siehe unten). |
stream |
boolean | Streaming aktivieren. |
store |
boolean | Ob die Antwort auf dem Server gespeichert werden soll (Standard: true). |
reasoning_effort |
string | Reasoning-Tiefe anpassen (low / medium / high). |
background |
boolean | Asynchrone Ausführung im Hintergrundmodus. |
2.9 Vergleich mit Chat Completions
| Funktion | Chat Completions | Responses API |
|---|---|---|
| Konversationsstatus | Clientseitig (gesamter Verlauf erforderlich) | Serverseitig (previous_response_id) |
| Websuche | Manuelle Implementierung erforderlich | Eingebaut (web_search_preview) |
| File Search / RAG | Manuelle Implementierung erforderlich | Eingebaut (file_search) |
| Code-Ausführung | Manuelle Implementierung erforderlich | Eingebaut (code_interpreter) |
| MCP-Verbindung | Nicht unterstützt | Native Unterstützung für Remote-MCP |
| Reasoning-Token-Persistenz | Zwischen Turns verworfen | Kann persistiert werden |
output_text-Helfer |
Nein | Ja |
| Format-Spezifikation | response_format |
text.format |
| Neue Funktionslieferung | Begrenzt | Primäres Ziel |
2.10 Reasoning-Modelle (o-Serie)
Distinct von der GPT-Serie bietet OpenAI eine Gruppe von Modellen namens Reasoning-Modelle an. Diese Modelle führen einen internen schrittweisen Denkprozess (Chain-of-Thought) aus, bevor sie eine Antwort generieren. Dieses interne Denken wird als Reasoning-Tokens gezählt, die nicht in der endgültigen Ausgabe enthalten sind.
Sie zeigen deutlich höhere Genauigkeit als GPT-4o für Aufgaben, die mehrstufiges Reasoning erfordern, wie Mathematik, Coding, logischen Schluss und komplexe Analyse. Andererseits sind Latenz und Kosten höher, weil das Denken Zeit braucht.
Wichtige Modelle 2025:
| Modell | Merkmale |
|---|---|
o1 / o1-mini |
Erste Generation Reasoning-Modelle. |
o3 / o3-mini |
Hochpräzise, hochperformante Nachfolge-Serie. |
o4-mini |
Modell ausbalanciert für Kosten und Performance. |
Die Reasoning-Tiefe kann mit dem Parameter reasoning_effort angepasst werden. low ist ein leichtgewichtiges Reasoning, das Latenz und Kosten reduziert, während high ein tiefes Reasoning für maximale Präzision ist.
const response = await client.responses.create({
model: "o3",
input: "Find the general term for this sequence: 1, 1, 2, 3, 5, 8, 13, ...",
reasoning_effort: "high",
});
3. Structured Outputs
3.1 Übersicht und Hintergrund
LLM-Ausgaben zuverlässig in JSON-Format zu zwingen, war eine wichtige Herausforderung für die Anwendungsintegration. OpenAI hat dies schrittweise gelöst:
JSON-Modus (Legacy-Funktion) stellt syntaktisch korrektes JSON sicher, garantiert jedoch keine Schema-Einhaltung. Es bestand das Risiko, dass erforderliche Felder fehlen oder unerwünschte Felder hinzukommen.
Structured Outputs, veröffentlicht im August 2024, garantiert 100% die Einhaltung eines vom Entwickler angegebenen JSON-Schemas (Quelle: OpenAI Offizieller Blog).
Interne Evaluierungen bei OpenAI zeigen, dass gpt-4o-2024-08-06 100% Schema-Konformität bei komplexen JSON-Schemas mit Structured Outputs erreicht, ein massiver Sprung gegenüber den weniger als 40% von gpt-4-0613.
3.2 Funktionsweise
Die OpenAI API erreicht Structured Outputs durch Umwandlung des angegebenen JSON-Schemas in eine Context-Free Grammar (CFG). Diese Grammatik schränkt die Tokens ein, die während des Samplings generiert werden können, und erzwingt so die Schema-Konformität.
3.3 Zwei Verwendungsmöglichkeiten
Structured Outputs wird in zwei Formen über die API bereitgestellt.
Die erste ist über Function Calling (Tools), aktiviert durch Setzen von strict: true innerhalb der Funktionsdefinition. Diese ist für alle Modelle ab gpt-4-0613 aufwärts verfügbar.
Die zweite ist über den response_format / text.format-Parameter, wobei die Angabe eines json_schema geeignet ist, wenn das Modell dem Benutzer in einem strukturierten Format antworten soll.
3.4 Implementierungsbeispiel (Responses API)
In der Responses API wurde der Parameter von response_format zu text.format verschoben (Quelle: Offizieller Migrationsguide).
Schema-Definition mit Zod (Empfohlen)
import OpenAI from "openai";
import { zodResponseFormat } from "openai/helpers/zod";
import { z } from "zod";
const client = new OpenAI();
const Step = z.object({
explanation: z.string().describe("Explanation of what is being done in this calculation step."),
output: z.string().describe("The calculation result for this step (formula or numerical value)."),
});
const MathResponse = z.object({
steps: z.array(Step).describe("A list of steps for the solution."),
final_answer: z.string().describe("The final answer to the equation (e.g., x = -3.75)."),
});
const response = await client.responses.parse({
model: "gpt-4o",
input: [
{ role: "system", content: "You are a math tutor. Explain step-by-step." },
{ role: "user", content: "Solve 8x + 7 = -23" },
],
text: { format: zodResponseFormat(MathResponse, "math_response") },
});
const result = response.output_parsed;
console.log(result.final_answer);
for (const step of result.steps) {
console.log(step.explanation, "->", step.output);
}
JSON-Schema direkt angeben
const response = await client.responses.create({
model: "gpt-4o",
input: [
{ role: "system", content: "You are a math tutor." },
{ role: "user", content: "Solve 8x + 7 = -23" },
],
text: {
format: {
type: "json_schema",
name: "math_response",
strict: true,
schema: {
type: "object",
properties: {
steps: {
type: "array",
items: {
type: "object",
properties: {
explanation: { type: "string" },
output: { type: "string" },
},
required: ["explanation", "output"],
additionalProperties: false,
},
},
final_answer: { type: "string" },
},
required: ["steps", "final_answer"],
additionalProperties: false,
},
},
},
});
3.5 Was Structured Outputs garantiert (und was nicht)
| Element | Status | Ergänzung |
|---|---|---|
| Korrekte JSON-Syntax | ✅ Garantiert | — |
| Einhaltung des angegebenen Schemas | ✅ Garantiert (mit strict: true) |
— |
| Vorhandensein erforderlicher Felder | ✅ Garantiert | — |
| Verwendung von in enum angegebenen Werten | ✅ Garantiert | — |
| Faktische Korrektheit | ❌ Nicht garantiert | Halluzinationen können für schemafremde Eingaben auftreten. |
| Befreiung von Sicherheitsrichtlinien | ❌ Nicht garantiert | Das Modell kann aus Sicherheitsgründen ein refusal zurückgeben. |
3.6 Schema-Einschränkungen im strict-Modus
Im strict: true-Modus sind einige JSON-Schema-Funktionen eingeschränkt:
additionalProperties: falseist erforderlich.- Alle Eigenschaften müssen im
required-Array enthalten sein. - Direkte Verwendung von
anyOfbeim Root-Objekt ist nicht erlaubt.
4. Realtime API
Die Realtime API, die 2025 GA erreichte, ist eine spezialisierte API für latenzarmes bidirektionales Sprach- und Text-Streaming via WebRTC, WebSocket oder SIP. Sie unterscheidet sich klar von der Responses API in ihren Anwendungsfällen. Weitere Details finden Sie im Offiziellen Realtime API Guide.
5. Streaming
Die Responses API unterstützt Streaming im Server-Sent Events (SSE)-Format, das den Empfang langer Antworten schrittweise ermöglicht.
const stream = await client.responses.stream({
model: "gpt-4o",
input: "Tell me in detail about the beginning of the universe.",
});
for await (const event of stream) {
if (
event.type === "response.output_text.delta" &&
event.delta
) {
process.stdout.write(event.delta);
}
}
6. Rate Limits
Rate Limits werden pro Organisation und Projekt angewendet (nicht pro Benutzer).
- RPM (Requests Per Minute): Anzahl der Anfragen pro Minute.
- TPM (Tokens Per Minute): Anzahl der Tokens pro Minute.
Wenn 429 Too Many Requests zurückgegeben wird, wird Retry mit exponentiellem Backoff empfohlen.
import retry from "async-retry";
async function callApiWithBackoff(params) {
return retry(
async () => {
return await client.responses.create(params);
},
{
retries: 6,
minTimeout: 1000,
maxTimeout: 60000,
randomize: true,
}
);
}
Zusammenfassung
| Punkt | Inhalt |
|---|---|
| Neue Projekte | Responses API (POST /v1/responses) verwenden. |
| Chat Completions | Weiterhin unterstützt. Keine sofortige Migration notwendig. |
| Assistants API | Abschaltung am 26. August 2026. Migration zu Responses API empfohlen. |
| Structured Outputs | 100% Schema-Konformität mit strict: true + additionalProperties: false. |
| Responses API-Verwendung | text.format statt response_format verwenden. |
| Echtzeit-Sprache | Realtime API (WebRTC / WebSocket / SIP) verwenden. |
| Rate Limits | Headers überwachen und mit exponentiellem Backoff wiederholen. |
| Modellversionierung | Snapshots pinnen und Evals in der Produktion durchführen. |
Nützliche Links
- Responses API Migrationsguide — Offizieller Migrationsguide.
- Structured Outputs Guide — Offizieller Structured Outputs Guide.
- Introducing Structured Outputs in the API — Offizieller Release-Blog.
- Realtime API Guide — Details zu bidirektionaler Echtzeit-Sprache und Text.
- Rate Limits Guide — Details zu Rate Limits.
- OpenAI Changelog — API-Update-Verlauf.
