Warum KI-Agenten nach der OpenAI Agents API noch mehr JSON brauchen: Harness, Tool Calling, JSON Schema

Stand 18. September 2026: Die Agents-API-Public-Beta hostet das Codex-Harness. Wer die Schleife nicht mehr selbst schreibt, hält fast nur noch JSON: Tool-Schema, arguments, tool_result, MCP, Session-Events. Ein lockerer Vertrag lässt die gehostete Schleife schlechte Parameter nur schneller laufen.

Vorab: Die Agents API hostet den Loop. Den Vertrag hostet sie nicht. Am 10. September 2026 hat OpenAI das Agent Harness, das Codex antreibt, als Public Beta vor Entwickler gestellt. Modell-Scheduling, Kontext-Compaction, Subagents und Sandbox-Lebensdauer sind aus Ihrem Prozess nach beta.agents.sessions gewandert. Was Sie weiter halten, ist fast alles JSON: das JSON Schema an jedem Function-Tool, arguments, der String in tool_result, MCP inputSchema und der Session-Event-Stream. Ein gehostetes Harness, das den Loop fährt, ist nicht dasselbe wie jemand anderes, der Ihre Felder validiert. Lockern Sie den Vertrag, und der gehostete Loop fährt schlechte Parameter nur öfter.

Stand 18. September 2026. Diese Seite hat bereits warum Agenten nicht ohne JSON auskommen, warum Tool Calling von JSON Schema abhängt, ob JSON Schema der Standardvertrag wird, MCP / Skills / Tools / Subagents und was MCP ist. Dieser Text beantwortet nur, warum JSON nach der Agents API wichtiger wird — nicht unwichtiger.

Was am 10. September tatsächlich erschienen ist

OpenAIs Formulierung: dasselbe Harness und dieselbe Infrastruktur, die Codex betreiben, als gehosteter Cloud-Agent für Entwickler. Die öffentlichen Docs legen es unter den Namespace beta.agents; Requests tragen OpenAI-Beta: agents=v1. Das Harness hat keine eigene Gebühr. Sie zahlen für Modell-Tokens, Tools und Sandbox-Zeit.

Eine Session zu erzeugen heißt, ein JSON-Dokument einzureichen: Modell, Instructions, Tool-Liste, Environment, Input. Offizielle Samples nutzen gpt-6-astra. Tools können MCP, eigene Functions oder eingebautes Retrieval sein. Das Environment kann none, openai_hosted oder eine Sandbox sein, die Sie mitbringen — Blaxel, Cloudflare, Daytona, E2B, Modal, Vercel und vergleichbare. Multi-Agent ist ein Flag: multi_agent.enabled plus max_concurrent_subagents.

Das ist kein weiterer Chat-Endpunkt, der „bitte JSON ausgeben“ sagt. Die Responses API ist weiter da. Das Agents SDK ist weiter da. Was die Agents API übernimmt, ist der Loop selbst: wer den nächsten Hop wählt, wann Kontext komprimiert wird, wann ein Subagent gestartet wird. Feldnamen können in der Beta noch wandern. Die Trennung ist schon stabil: OpenAI betreibt das Harness; Sie liefern den Tool-Vertrag und das Geschäftsergebnis.

Drei Einstiege: Responses, Agents SDK, Agents API

Stand September 2026 lässt OpenAI drei Wege, einen Agenten zu bauen, nebeneinander. Bevor Sie sie mischen, fragen Sie, wo der Loop läuft:

EinstiegWo der Loop läuftWo der State liegtWas Sie weiter schreiben
Responses APIIhre AppHistory, die Sie zusammenbauen / ConversationsModellaufrufe, Tool-Rückgaben, den ganzen Loop
Agents SDKIhr ProzessSDK-Sessions plus Ihr StorageFreigaben, Deploy, und Sie können den Loop weiter ändern
Agents APIOpenAIs gehostetes Codex-HarnessSession / turn / item serverseitigTool-Definitionen, Function-Ergebnisse, Environment-Wahl; den Loop ändern Sie nicht

Einmal-Completion gehört weiter auf Responses. Wenn Sie Freigaben und Persistenz selbst halten wollen, das SDK. Wenn Sie mehrtägige Arbeit, Compaction, Subagents und eine Sandbox wollen, die für Sie betrieben wird, die Agents API. Alle drei beschreiben Tool-Parameter weiter mit JSON Schema. Der Unterschied: die ersten zwei lassen Sie den Loop noch patchen; die dritte nur den Vertrag und die Rückgabe-Payload.

Was ein Agent Harness ist — und was es nicht unterschreibt

Ein Harness ist die Runtime zwischen Modell und Seiteneffekten: Events lesen, Tools wählen, Ergebnisse füttern, Kontext komprimieren, einen langen Job am Leben halten. Das Codex-Harness ist Open Source. Die Agents API ist OpenAI, das dieselbe Logik betreibt und mit den Modellen versioniert. Die Launch-Note nennt automatische Compaction, Tool search, Programmatic Tool Calling und parallele Subagents.

Es unterschreibt keines davon:

  • ob eine customer_id existieren muss, oder eine UUID sein muss;
  • ob Ihre Function Extra-Keys akzeptieren darf;
  • ob das inputSchema eines MCP Servers eng oder locker ist;
  • ob das output, das Sie zurückschicken, ein Objekt, ein String oder ein Chat-Absatz ist.

Das bleibt JSON Schema plus eine Prüfung, die Sie selbst fahren. Ein gehostetes Harness hebt, wie lange ein Loop laufen und wie weit er parallelisieren kann. Es hebt nicht, ob die Parameter dieses Hops legal sind. Beides gleichzusetzen ist die erste Verwechslung, die dieser Text auseinanderzieht.

Warum ein gehosteter Loop mehr JSON-Hops bedeutet

Wenn Sie den Loop selbst schreiben, stirbt schlechtes JSON meist auf Ihrer Seite: Parse scheitert, Felder passen nicht, Sie stoppen. Ist der Loop gehostet, wird der Fehler verzögert, kopiert und über mehr Kanäle geschickt:

HopPayloadWer erzeugt esWer muss validieren
Session erzeugenagent / tools / environment JSONIhre AppSie, vor dem Submit
Function-DefinitionJSON Schema (parameters)Ihre AppSie: required / additionalProperties anziehen
Modell startet einen Aufrufarguments-ObjektGehostetes Harness + ModellSie: vor der Ausführung erneut validieren
Ergebnis zurückgebentool_result.output-StringIhre AppSie: einen legalen Wert stringify
MCPJSON-RPC + inputSchemaServer / HarnessDer Server und Ihre Allow-Liste
Event-Streamagent.session.*-JSON-EventsDer gehostete DienstSie: nach type verzweigen; nicht als Chat-Prosa parsen

Dazu Tool search, das Definitionen on demand lädt, Programmatic Tool Calling, das Aufrufe im Code kettet, und Subagents mit jeweils eigenem Kontext — eine Nutzeraufgabe macht jetzt mehr JSON-Roundtrips als ein einzelner Function-Calling-Hop. Hosting versteckt diese Hops. Versteckt heißt nicht optional zu validieren. Die Hop-für-Hop-Karte steht in von Tool Calling zu MCP.

Tool Calling: Function-Tools sind weiter JSON Schema

Function-Tools auf der Agents API nutzen dieselbe Form wie die Responses API. Was Sie auf agent.tools legen, ist kein Absatz. Es ist ein Name, eine Description und ein JSON Schema:

{
  "type": "function",
  "name": "get_customer",
  "description": "Look up a customer by ID.",
  "parameters": {
    "type": "object",
    "properties": { "customer_id": { "type": "string" } },
    "required": ["customer_id"],
    "additionalProperties": false
  }
}

Das offizielle Sample füllt required und setzt additionalProperties auf false. Das ist keine Formatierungsgewohnheit. Darf der Agent einen Extra-Key setzen, kann dieser Key ein Pfad, ein SQL-Fragment oder ein Delete werden. Das Schema ist der Vertrag, den das Modell beim Decodieren sieht — und der Vertrag, den Sie vor der Ausführung erneut fahren sollten. Strict Mode, ajv und eine zweite Prüf-Pipeline: warum Tool Calling von JSON Schema abhängt.

Die Description hilft dem Modell weiter, ein Tool zu wählen. Sie ersetzt keine Typen, Enums und Pflichtfelder. Je klüger das Harness, desto bereitwilliger greift es aus einer langen Liste ein „nah genug“. Nah genug ist, was das Schema ablehnen soll.

requires_action und tool_result: der Rückweg ist ebenfalls JSON

Wenn das Modell Ihre Function braucht, hält die Session bei agent.session.requires_action. Ausstehende Arbeit liegt in required_actions. Ein function_call-Item in der History reicht allein nicht. Ein typischer Pending-Aufruf sieht so aus:

{
  "type": "function_call",
  "turn_id": "turn_123",
  "call_id": "call_123",
  "name": "get_customer",
  "arguments": { "customer_id": "123" }
}

Die Docs stellen arguments als Objekt dar. Packen Sie es nicht in eine Chat-Antwort und kratzen Sie es nicht mit JSON.parse heraus — das ist der falsche Kanal, behandelt in warum JSON.parse scheitert. Validieren Sie das Objekt gegen dasselbe Schema, führen Sie die Function aus, dann posten Sie agent.session.input.tool_result an den Session-Events-Endpunkt mit der ursprünglichen turn_id und call_id.

Bei Erfolg success: true und output als String oder unterstütztes Content-Array. Objekte zuerst durch JSON.stringify. Bei Fehler success: false und ein error, den das Modell lesen kann. Keine Stacks, Secrets oder eine ganze Datenbankzeile zurückschicken. Stirbt der Prozess nach der Function, aber bevor das Ergebnis OpenAI erreicht, den Seiteneffekt über session / turn / call schlüsseln und idempotent bleiben: beim Restart zuerst Pending lesen, dann entscheiden, ob Sie erneut fahren.

Function-Handler laufen immer in Ihrer Anwendung, auch wenn die Session eine Sandbox hat. Das Harness führt get_customer nicht für Sie aus. Sind Sie offline, bleibt der Hop blockiert. Das ist einer der wenigen synchronen Punkte in einem gehosteten Loop, der weiter ganz Ihnen gehört — und der Hop, an dem das JSON stimmen muss.

Tool search und Programmatic Tool Calling

Eine große Tool-Liste verbrennt Tokens und bricht den Cache, wenn jedes Schema im Kontext sitzt. Die Agents API lädt Functions standardmäßig eifrig. Seltene können defer_loading: true setzen, mit {"type": "tool_search"} auf agent.tools. Das Modell findet die Definition, dann ruft es sie auf. Das fügt einen Hop hinzu, an dem „die Definition selbst JSON ist“: das Schema, das die Suche liefert, muss zur Function passen, die Sie wirklich implementiert haben. Keinen weiten Vertrag bewerben und einen engen ausführen.

Programmatic Tool Calling lässt unterstützte Modelle ein kurzes Programm schreiben, das zulässige Tools parallel oder in einer Kette fährt und nur gefilterte Ergebnisse in den Kontext zurückbringt. Das senkt die Kosten, bei jedem Hop das Fenster zu füllen. Es hebt die Anforderung, dass das Zwischen-JSON legal ist. Driften Typen in der Mitte, laufen spätere Filter und Merges in einem Harness schief, das Sie nicht sehen. Das SDK hat bereits einen Fix, der strukturierte Fehler als JSON kodiert. Dieser Pfad frisst Schema, nicht Prosa.

MCP und Subagents: mehr Schemas, mehr JSON

Legen Sie einen MCP Server auf agent.tools, und das Harness entdeckt Tools, ruft sie auf und füttert Ergebnisse zurück. Anders als Functions laufen diese Aufrufe nicht durch Ihre Anwendung. HTTP verbindet standardmäßig von OpenAI; Sie können auch aus der Environment verbinden oder stdio in der Sandbox starten. Was Sie weiter steuern, ist allowed_tools, ob ein fehlgeschlagenes Init den Turn scheitern lässt (required: true), und wie eng das inputSchema des Servers selbst ist.

MCP-Nachrichten sind weiter JSON-RPC. Ein lockeres Schema heißt, das gehostete Harness feuert mehr Requests, die Sie nie sehen. Das ist nicht „das Protokoll hat Sie sicher gemacht“. Es ist „der Loop ist weiter weggerückt“. Die Protokollschichten: was MCP ist; die Grenze zu Skills und Subagents: der Agent-Stack 2026.

Jeder Subagent behält eigenen Kontext; der Parent führt zusammen. Parallele Arbeit senkt Latenz und fächert auch viele arguments-Objekte auf. Ist der Merge weiter ein schemafreier Aufsatz, haben Sie „den Chat parsen“ nur auf den letzten Hop verschoben. Schlüsse, die ins Programm eingehen, sollten weiter Structured Output oder ein Ergebnis-Schema nutzen, das Sie definieren — nicht wieder Prosa herauskratzen. Siehe was Structured Output ist.

Vier Dinge, die Sie weiter lokal validieren

Nachdem das Harness gehostet ist, wird die Liste nicht kürzer. Sie wird enger:

  1. Tool-Schemas. required füllen, additionalProperties: false setzen, Enums anziehen. Nicht auf die Description setzen, um Seiteneffekte zu stoppen.
  2. Arguments vor der Ausführung. Auch wenn der Vendor das Schema schon angewendet hat, dasselbe Dokument noch einmal in Ihrem Prozess fahren. Falsche Typen, fehlende Felder, Extra-Keys stoppen hier.
  3. Das output, das Sie zurückschicken. Legales JSON machen, dann stringify. Fehler gehen als success: false raus. Dem Modell keine rohe interne Exception geben.
  4. Events und Chat auf getrennten Kanälen halten. Nach event.type verzweigen. Einen ganzen SSE-Stream nicht als einen JSON-Wert behandeln. Strukturierte Antworten an den Nutzer über Structured Output, nicht JSON.parse auf einem Assistant-Satz.

Auf der Security-Seite: ein String in arguments kann eine Injection sein, nicht „der Typ hat gepasst, also ausführen“. Siehe bösartiges JSON und Prompt Injection. Ob JSON Schema der herstellerübergreifende Vertrag wird, steht im Standard-Contract-Stück — die Agents API schwächt diese These nicht. Sie schiebt sie auf die einzige Schicht, die Sie noch ändern können.

Den Vertrag mit lokalen JSON-Tools prüfen

Bevor Sie Arbeit an eine gehostete Session geben, drei Texte im Browser ansehen: das Tool-Schema, ein Sample-arguments-Objekt und das output, das Sie zurückschicken wollen.

  • JSON-Validator — ist die Grammatik legal; wenn Sie ein Schema haben, Felder, required und Extra-Keys zusammen prüfen.
  • JSON-Formatierer — ein einzeiliges tool_result aufklappen und sehen, ob Sie eine ganze Datenbankzeile serialisiert haben.
  • JSON Diff — die arguments, die das Modell geschickt hat, mit dem kleinsten Objekt vergleichen, das das Schema erlaubt.

Nichts verlässt den Browser. Der richtige Ort, eine fehlgeschlagene required_actions-Payload, ein parameters-Dokument und ein stringified Ergebnis nebeneinander zu legen. Den Vertrag stabilisieren, dann das gehostete Harness Tage laufen lassen.

FAQ

Heißt die Agents API, dass ich kein JSON Schema mehr schreiben muss?

Das Gegenteil. Ist der Loop gehostet, ist das Schema der Hauptvertrag, den Sie weiter halten. Function-parameters, MCP inputSchema und das output, das Sie zurückgeben, sind weiter JSON.

Wie wähle ich zwischen Agents API, Agents SDK und Responses?

Einmal-Aufrufe gehören auf Responses. Wollen Sie Loop, Freigaben und Storage selbst halten, das SDK. Wollen Sie lange Jobs, Compaction, Subagents und eine Sandbox, die OpenAI betreibt, die Agents API. Alle drei nehmen weiter JSON Schema für Tool-Parameter.

Arguments sind schon ein Objekt. Muss ich trotzdem JSON.parse aufrufen?

Den umgebenden Chat nicht noch einmal parsen. Arguments wie in den Docs als Objekt behandeln und mit demselben JSON Schema validieren. Arguments aus Prosa herauszukratzen ist der falsche Kanal.

Warum muss tool_result stringified werden?

Die Docs wollen output als String oder unterstütztes Content-Array. Legales JSON machen, dann stringify — damit Sie eine zweite Kodierung nicht mit „sieht aus wie ein Objekt, ist eigentlich ein String“ mischen.

Laufen MCP-Tools durch meine Anwendung?

Standardmäßig nicht. Das Harness spricht mit dem Server. Was Sie anziehen, ist das inputSchema des Servers selbst, allowed_tools und jede Freigabe für irreversible Aktionen in diesem Server.

Werden Feldnamen in der Beta noch geändert?

Können sie. Dieser Text folgt den öffentlichen Docs vom 18. September 2026. Die Trennung nicht: das Harness fährt den Loop; Sie liefern den JSON-Vertrag. Wird ein Feld umbenannt, bleibt die Pflicht zur Validierung bei Ihnen.

Fazit

Die Agents API senkt den Aufwand für „wie man einen Agenten zu Ende fährt“. Sie hebt das Gewicht von „jeder JSON-Hop muss stimmen“. Was am 10. September kam, ist das Codex-Harness: Sessions, Compaction, Tool search, programmatische Aufrufe, Subagents, Sandboxes. Es prüft nicht, wie eine customer_id aussehen soll, und macht aus Ihrem tool_result kein legales String für Sie.

Einen Agenten 2026 an ein Programm zu verdrahten folgt weiter derselben Reihenfolge: Tools auf JSON Schema, finale Antworten auf Structured Output, Chat-Prosa ist keine API. Geändert hat sich: ist der Loop gehostet, können Sie nur noch den Vertrag patchen. Schema, arguments und Rückgabe-Payload zuerst in einem lokalen Validator prüfen, dann die Arbeit an eine gehostete Session geben. Modelle wechseln. Das Harness bekommt neue Versionen. Ihr Feldvertrag sollte nicht mit ihnen lockern.