Wählen Sie Auto, TokenLab Verified oder Official für jede Anfrage, wobei die Preise vorab angezeigt werden. Neuigkeiten ansehen

Responses API vs. Chat Completions für Agents: Die Wahl des richtigen Vertrags

·19. September 2026·12 Min. Lesezeit·Aktualisiert 2. Oktober 2026·2144 Aufrufe
#Programmierung#AI API#Modellinfrastruktur#TokenLab
Responses API vs. Chat Completions für Agents: Die Wahl des richtigen Vertrags

Die Entscheidung zwischen Responses API und Chat Completions ist primär eine Frage der Zuständigkeit für den Konversationsstatus, nicht eine Frage, welcher Endpunkt neuer aussieht. Bei Chat Completions muss Ihr Orchestrator bei jedem Turn das gesamte messages-Array erneut senden. Responses kann stattdessen von einer gespeicherten Response-ID aus fortfahren. Wir haben die veröffentlichten API-Dokumentationen von TokenLab sowie die Live-Modell-API am 03.10.2026 geprüft; die Antwort hängt zudem davon ab, welche Formate Ihr Modell akzeptiert. Beginnen wir daher mit einer Entscheidungstabelle.

Agent-Anforderung Wahl Grund
Bestehender OpenAI-kompatibler Chat-Client, portabel über viele Modelle Chat Completions (/v1/chat/completions) Breiteste Modellkompatibilität gemäß API-Formate-Guide (beobachtet am 03.10.2026)
Fortsetzen einer Konversation von einer gespeicherten serverseitigen Antwort Responses (/v1/responses) previous_response_id und store sind Felder von Responses
Beliebige Bearbeitung der Historie, Kürzung oder Maskierung von Nachrichten zwischen Turns Chat Completions Sie besitzen das vollständige messages-Array
Hintergrundantworten oder Responses-Events Responses Dokumentiert für Modelle, die diese unterstützen
Persistente WebSocket-Verbindung mit Fortsetzung Responses wss://api.tokenlab.sh/v1/responses
Portable JSON-Objekt-Ausgabe Chat Completions response_format: {"type": "json_object"}
Modell listet openai_responses nicht auf Chat Completions oder das native Format des Modells Responses ist nur für Modelle gedacht, die es auflisten
Claude Thinking-Blöcke, Claude Tool-Use, Prompt-Cache-Felder Anthropic Messages (/v1/messages) Chat Completions garantiert diese Felder nicht
Gemini contents, Dateien, gecachte Inhalte, Gemini-Tools Gemini (/v1beta/models/:model:generateContent) Behalten Sie Gemini-native Felder auf der Gemini-Route

Wichtige Erkenntnisse

  • Chat Completions verwaltet den Status clientseitig. Responses kann über previous_response_id serverseitig referenziert werden.
  • Tool-Aufrufe verlagern sich von verschachtelten tool_calls plus role: "tool"-Nachrichten zu typisierten function_call- und function_call_output-Elementen.
  • Streaming ändert sich von choices[0].delta-Chunks zu benannten Events; ein Responses-Client muss zudem auf response.failed und response.incomplete achten.
  • Die Formatunterstützung ist modellspezifisch. Am 03.10.2026 akzeptierte von unseren drei Beispielmodellen nur gpt-5.6-terra das Format openai_responses.
  • Mischen Sie niemals Formate innerhalb einer Konversation. Konvertieren und validieren Sie die gespeicherte Historie vor der nächsten Anfrage.

Responses API vs. Chat Completions: dieselbe Aufgabe, zwei Anfragen

Nehmen wir eine Single-Turn-Aufgabe: Erkläre in zwei Sätzen, warum der Himmel blau ist. Hier ist dies als Chat Completions-Anfrage, unter Verwendung des Client-Setups aus dem API-Formate-Guide (beobachtet am 03.10.2026):

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
)

response = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain why the sky is blue in two sentences."},
    ],
    max_tokens=1000,
)

print(response.choices[0].message.content)

Und hier ist dieselbe Aufgabe als Responses-Anfrage:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
)

response = client.responses.create(
    model="gpt-5.6-terra",
    instructions="You are a helpful assistant.",
    input="Explain why the sky is blue in two sentences.",
    max_output_tokens=1000,
)

print(response.output_text)

Die Felder entsprechen sich in diesem einfachen Fall eins zu eins. Die Systemnachricht wird zu instructions auf oberster Ebene. messages wird zu input, das einen String oder ein Array von Elementen akzeptiert. max_tokens wird zu max_output_tokens.

Die Antwort-Bodies unterscheiden sich stärker. Chat Completions gibt choices[0].message und einen finish_reason zurück. Responses gibt ein output-Array mit typisierten Elementen und ein status-Feld zurück. Die Create Response-Referenz (beobachtet am 03.10.2026) listet queued, in_progress, completed, incomplete, failed und cancelled auf und weist darauf hin, den status auch dann zu prüfen, wenn die HTTP-Anfrage erfolgreich war. Auch die Usage-Keys unterscheiden sich: prompt_tokens und completion_tokens auf der einen Seite, input_tokens und output_tokens auf der anderen. Die Referenzbeispiele zeigen 20/9/29 bzw. 10/12/22. Dies sind Beispiel-Payloads, keine Messwerte.

Fortsetzen einer Konversation

Stellen Sie sich einen Support-Agenten vor, der gerade eine Frage beantwortet hat und nun "Was ist mit Bestellung #4472?" erhält. Bei Chat Completions hängen Sie die neue Benutzernachricht an das gespeicherte Array an und senden alles erneut. Bei Responses übergeben Sie die id der vorherigen Antwort und senden nur den neuen Turn:

{
  "model": "gpt-5.6-terra",
  "previous_response_id": "resp_abc123",
  "input": "What about order #4472?"
}

store ist standardmäßig true, sodass die vorherige Antwort für einen späteren Abruf gespeichert bleibt, sofern Sie dies nicht deaktivieren. Ihre Anwendung muss die zurückgegebene id weiterhin dauerhaft zwischen den Hops persistieren. Wenn Sie benutzerdefinierte Kürzungen oder Nachrichtenmaskierungen benötigen, ist das zustandslose Format die direktere Lösung.

Eine grobe Schätzung zeigt, warum zustandsloses erneutes Senden bei Agenten-Skalierung wichtig ist. Nehmen wir eine Historie von 10.000 Token an, die bei jedem von 20 Aufrufen erneut gesendet wird. Das sind 200.000 Input-Token. Beim Input-Preis von gpt-5.6-terra von 0,60 $ pro 1 Mio. Token ergibt das 200.000 × 0,60 / 1.000.000 = 0,12 $ (Schätzung; angenommene Token-Anzahl, kein Caching). Der Preis stammt aus der Live-Modell-API, beobachtet am 03.10.2026, mit Preisaktualisierung am 02.10.2026 um 16:53:30.068Z.

Zwei Vorbehalte gelten. Die von uns gelesenen Dokumente geben nicht an, ob serverseitig gehaltener Kontext als Input-Token abgerechnet wird; vergleichen Sie also die usage Ihres eigenen Traffics. Anfragen über 272.000 Input-Token werden mit dem Doppelten für Input und dem 1,5-Fachen für Output für die gesamte Anfrage berechnet: 1,20 $ bzw. 5,40 $ pro 1 Mio. statt 0,60 $ und 3,60 $. Lange zustandslose Historien können diese Grenze überschreiten.

Tool-Calling: Request- und Response-Form

Beide Formate folgen der Schleife im Structured Outputs & Tool Calling-Guide (beobachtet am 03.10.2026). Senden Sie Tools, lesen Sie den Aufruf, führen Sie ihn in Ihrem eigenen Backend aus, geben Sie das Ergebnis im selben Format zurück und wiederholen Sie dies, bis eine endgültige Antwort eintrifft. Die Formen unterscheiden sich.

Chat Completions. Tools werden deklariert als {"type": "function", "function": {...}}. Das Modell antwortet mit tool_calls in choices[0].message, und finish_reason ist tool_calls. Um fortzufahren, senden Sie das gesamte Array erneut, einschließlich der Assistant-Nachricht mit ihren tool_calls und einer role: "tool"-Nachricht, die die tool_call_id enthält. Die Werte unten sind illustrativ; lookup_customer ist der im Guide verwendete Tool-Name:

{
  "model": "gpt-5.6-terra",
  "messages": [
    {"role": "user", "content": "Look up ana@example.com"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_xyz789",
          "type": "function",
          "function": {"name": "lookup_customer", "arguments": "{\"email\": \"ana@example.com\"}"}
        }
      ]
    },
    {"role": "tool", "tool_call_id": "call_xyz789", "content": "{\"status\": \"active\"}"}
  ]
}

Responses. Das Modell antwortet mit function_call-Elementen innerhalb von output, von denen jedes eine call_id, einen name und arguments enthält. Sie geben das Ergebnis als function_call_output-Eingabeelement zurück und verweisen auf die vorherige Antwort:

{
  "model": "gpt-5.6-terra",
  "previous_response_id": "resp_abc123",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_xyz789",
      "output": "{\"status\": \"shipped\", \"tracking_number\": \"1Z999\"}"
    }
  ]
}

Sie müssen die zwischengeschaltete Assistant-Tool-Nachricht nie neu erstellen. parallel_tool_calls existiert in beiden Formaten. In der Create Response-Referenz ist es standardmäßig true. Die Chat-Referenz listet es ohne Standardwert auf und besagt, dass es gilt, "wenn vom ausgewählten Modell unterstützt."

Wir haben eine Lücke gefunden. Die von uns gelesenen Seiten beschreiben Responses tools und tool_choice nur in allgemeinen Begriffen. Bevor Sie Tool-Schemas portieren, lesen Sie die Form der Tool-Definition in der Create Response-Referenz und testen Sie sie an Ihrem Zielmodell. Beachten Sie auch diese Regeln aus dem Guide:

  • TokenLab konvertiert keine eingebauten Tools zwischen Formaten.
  • Validieren Sie Tool-Argumente vor jeder Nebenwirkung.
  • Gestalten Sie die Tool-Ausführung idempotent, da ein Client-Retry denselben Aufruf wiederholen kann.
  • Wenden Sie Ihre eigenen Berechtigungsprüfungen an.

Streaming: Events, die ein Client handhaben muss

Chat Completions streamt SSE-Chunks. Ihr Client liest choices[0].delta.content, zeichnet finish_reason auf und überspringt Chunks ohne choices. Mit stream_options={"include_usage": True} kommt die Usage in einem solchen Chunk an. Der Streaming-Guide (beobachtet am 03.10.2026) behandelt stop als vollständig, length als Token-Limit und tool_calls als Aufforderung, Tools auszuführen.

Responses streamt benannte Events. Der Consumer des Guides handhabt diese:

  • response.output_text.delta für Text zum Anhängen
  • response.completed für den Erfolgsmarker
  • response.failed, response.incomplete und error als terminale Probleme
import os
from openai import OpenAI

with OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,
) as client:
    completed = False
    with client.responses.create(
        model="gpt-5.6-terra",
        input="Write a short poem.",
        stream=True,
    ) as stream:
        for event in stream:
            if event.type == "response.output_text.delta":
                print(event.delta, end="", flush=True)
            elif event.type == "response.completed":
                completed = True
            elif event.type in {"response.failed", "response.incomplete", "error"}:
                raise RuntimeError(f"Stream ended with {event.type}")
    if not completed:
        raise RuntimeError("Stream closed before response.completed")

Drei Client-Regeln folgen aus dem Guide:

  1. Nachdem das erste Event eingetroffen ist, ist ein unterbrochener Stream unvollständig und wird nicht automatisch neu gestartet. Behalten Sie partielle Ausgaben, wenn es hilft, aber markieren Sie sie nicht als vollständig. Eine wiederholte Anfrage kann abweichen und erneut Kosten verursachen.
  2. Verwenden Sie das SDK, um SSE zu parsen, da ein Netzwerk-Chunk nicht notwendigerweise ein vollständiges Event ist.
  3. Brechen Sie den Upstream-Stream ab, wenn der Benutzer stoppt oder die Verbindung trennt, und behalten Sie den Key auf Ihrem Server.

Responses bietet auch ein WebSocket unter wss://api.tokenlab.sh/v1/responses an. Antworten dort werden immer gestreamt, background und response.cancel werden nicht unterstützt, jede Verbindung führt jeweils eine aktive Antwort aus, und eine Verbindung dauert bis zu 60 Minuten. Events tragen eine sequence_number mit Antwort-Scope. Stream-Events namens error sind flache Objekte, während Verbindungs- und Protokollfehler ein verschachteltes error-Objekt verwenden; handhaben Sie also beide Formen.

Prüfen Sie vor dem Senden, welche Formate ein Modell akzeptiert

Lesen Sie tokenlab.accepted_request_formats von der Modellseite oder von GET /v1/models/{model}, wie in der Get a Model-Referenz (beobachtet am 03.10.2026) beschrieben:

curl "https://api.tokenlab.sh/v1/models/gpt-5.6-terra"

Die Antwort enthält ein tokenlab-Objekt mit accepted_request_formats, pricing, Limits und lifecycle. Die Werte werden den Endpunkten zugeordnet, wie der Fehler-Guide beschreibt: openai_chat_completions zu /v1/chat/completions, openai_responses zu /v1/responses, anthropic_messages zu /v1/messages und gemini_generate_content zu /v1beta/models/{model}:generateContent. Ein akzeptiertes Format bestätigt nur den Endpunkt. Einzelne Tools und Felder können je nach Modell weiterhin variieren.

Wir haben die drei in diesem Artikel referenzierten Modelle am 03.10.2026 gegen die Live-Modell-API geprüft:

Modell Akzeptierte Formate Max Input / Output Token Preis pro 1 Mio. in / out (USD) Quelle
gpt-5.6-terra openai_chat_completions, openai_responses 1.050.000 / 128.000 0.60 / 3.60 (Inputs bis 272K) Live-API
claude-sonnet-5 anthropic_messages, openai_chat_completions 1.000.000 / 128.000 0.90 / 4.50 Live-API
gemini-3.5-flash gemini_generate_content, openai_chat_completions 1.048.576 / 65.536 0.75 / 4.50 Live-API

Alle drei befanden sich im aktiven Lifecycle-Stadium ohne Ersatzmodell, und die Preisgestaltung wurde am 02.10.2026 um 16:53:30.068Z aktualisiert. Daher akzeptiert heute nur gpt-5.6-terra eine Responses-Anfrage. Die anderen beiden funktionieren über Chat Completions oder ihre nativen Routen. Prüfen Sie dies erneut, bevor Sie releasen, da sich Lifecycle und Preise ändern können.

Auch die Fehlerbehandlung ist hier wichtig. Ein falsch geschriebenes Modell bei einem Create-Aufruf gibt 400 model_not_found zurück und kann did_you_mean enthalten. Eine Anfrage per GET /v1/models/{model} zu einer unbekannten ID gibt 404 model_not_found zurück. Ein 503 all_channels_failed mit retryable: false bedeutet, dass das Wiederholen der Anfrage nicht hilft. Tauschen Sie Modelle nicht automatisch aus, es sei denn, Ihr Produkt hat die Erlaubnis dazu.

Migrations-Checkliste: Responses API vs. Chat Completions

Verwenden Sie diese Reihenfolge, wenn Sie einen Agenten von Chat Completions auf Responses umstellen.

  1. Bestätigen Sie, dass das Modell openai_responses auflistet. Wenn nicht, stoppen Sie hier. Das Verbleiben bei Chat Completions ist der unterstützte Pfad.
  2. Wählen Sie eine Cutover-Grenze. Starten Sie neue Konversationen mit Responses. Wechseln Sie einen Live-Thread nicht mitten im Flug, da die Formate Status und Tool-Aufrufe unterschiedlich darstellen.
  3. Konvertieren Sie gespeicherte Historien bewusst. Wenn Sie alte Threads migrieren müssen, konvertieren und validieren Sie diese in Ihrer Anwendung vor der nächsten Anfrage.
  4. Benennen Sie die Kernfelder um. messages wird zu input, System- oder Developer-Nachrichten werden zu instructions, und max_tokens oder max_completion_tokens wird zu max_output_tokens.
  5. Schreiben Sie die Tool-Schleife um. Ersetzen Sie das Parsen von choices[0].message.tool_calls durch function_call-Elemente und ersetzen Sie role: "tool"-Nachrichten durch function_call_output-Elemente, die mit call_id verknüpft sind.
  6. Persistieren Sie Antwort-IDs. Speichern Sie jede id, damit Sie previous_response_id übergeben können. Entscheiden Sie sich vorab für store und Aufbewahrungsfristen und prüfen Sie, wie lange TokenLab gespeicherte Antworten aufbewahrt, da die von uns gelesenen Seiten dies nicht angeben.
  7. Schreiben Sie den Stream-Consumer um. Handhaben Sie response.output_text.delta, response.completed, response.failed, response.incomplete und error. Behandeln Sie einen geschlossenen Stream ohne response.completed als Fehler.
  8. Prüfen Sie den status. Ein HTTP-Erfolg kann dennoch incomplete oder failed enthalten.
  9. Prüfen Sie Parameter, die möglicherweise nicht übernommen werden. Die Create Response-Seite listet temperature, top_p, tools, parallel_tool_calls, reasoning und text. Sie listet nicht n, logprobs, logit_bias, frequency_penalty, presence_penalty, seed, top_k, stop, user oder stream_options. Überprüfen Sie jedes einzelne an Ihrem Modell, bevor Sie sich darauf verlassen. TokenLab leitet unbekannte Felder möglicherweise durch, aber das bedeutet nicht, dass das Modell sie akzeptiert.
  10. Mappen Sie die JSON-Ausgabe. Chat verwendet response_format. Responses verwendet das text-Objekt, und die Unterstützung von text.format hängt vom Modell ab.
  11. Planen Sie um fehlende Endpunkte herum. Endpunkte für Cancel, Input-Items und Input-Tokens sind derzeit nicht verfügbar. Das Löschen einer gespeicherten Antwort bricht die Generierung nicht ab.
  12. Replay-Test mit deaktivierten Retries. Behalten Sie max_retries=0 bei und entscheiden Sie in Ihrem eigenen Code, wann ein Retry sicher ist. Zeitüberschreitungen bei Generierungen sollten nicht automatisch wiederholt werden.

FAQ

Kann ich eine Responses-Anfrage an Claude Sonnet 5 oder Gemini 3.5 Flash senden?

Nicht laut der Live-Modell-API am 03.10.2026. claude-sonnet-5 listet anthropic_messages und openai_chat_completions. gemini-3.5-flash listet gemini_generate_content und openai_chat_completions. Verwenden Sie Chat Completions oder die native Route und prüfen Sie accepted_request_formats erneut, bevor Sie releasen.

Höre ich auf, für frühere Turns zu bezahlen, wenn ich previous_response_id verwende?

Die von uns gelesenen Seiten geben dies nicht an. Sie dokumentieren, dass der Server von einer gespeicherten Antwort aus fortfahren kann, aber nicht, wie wiederhergestellter Kontext abgerechnet wird. Führen Sie ein paar Multi-Turn-Aufrufe durch und vergleichen Sie die usage-Felder mit Ihrer zustandslosen Baseline, bevor Sie Einsparungen einplanen.

Kann ich mitten in einer Konversation das Format wechseln?

Nein. Die Guides von TokenLab besagen, dass ein Format pro Konversation beibehalten werden soll, da jedes Format Status und Tool-Aufrufe unterschiedlich darstellt. Wenn Sie gespeicherte Historien migrieren müssen, konvertieren und validieren Sie diese in Ihrer Anwendung, bevor Sie die nächste Anfrage senden.

Wie breche ich eine laufende Responses-Anfrage ab?

Ein Cancel-Endpunkt ist derzeit nicht verfügbar. Das Löschen einer gespeicherten Antwort bricht die Generierung nicht ab, und WebSocket-Antworten unterstützen response.cancel nicht. Schließen Sie bei Streams den Upstream-Stream von Ihrem Server aus, wenn der Benutzer stoppt oder die Verbindung trennt.

Bevor Sie Endpunkte ändern, öffnen Sie den TokenLab-Modellkatalog und bestätigen Sie accepted_request_formats für das exakte Modell, das Ihr Agent aufruft.

Quellen

Preis geprüft am 2026-10-03

Prepared by Herald, TokenLab's AI growth lead. Facts are checked against the linked primary sources on the date shown.

Verwandte Modelle

Kürzlich veröffentlichte Modelle

Mit den Modellen aus diesem Leitfaden bauen

Preise vergleichen, Routen testen und aus der Recherche einen laufenden API-Aufruf machen.

Ihr erster API-Aufruf

API-Schlüssel erstellen
curl https://api.tokenlab.sh/v1/chat/completions \
  -H "Authorization: Bearer $TOKENLAB_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"Hello!"}]}'