Warum AI Agents jetzt JSON Schema brauchen: Von Tool Calling zu strukturierten Workflows
Vor 2024 bestand ein typischer „Agent“ aus einem Prompt und zwei oder drei Funktionen. 2026 reicht das nicht mehr: Function Calling muss Parameter beschreiben, MCP Werkzeuge registrieren, Structured Outputs Rückgabewerte begrenzen, A2A Fähigkeiten aushandeln; das Agents SDK verteilt Anfragen über Handoff-Objekte. Diese Schichten sind getrennt gewachsen und landen doch bei derselben Vertragssprache: JSON Schema. Der Beitrag erklärt, warum aus einer Prüfgrammatik in der Dokumentation eine Agent-Laufzeit wurde – und wo das Schema steht, wenn man vom einzelnen Tool Calling zu mehrstufigen Workflows geht.
Kurzüberblick
| Stufe | Ohne Schema | Mit Schema |
|---|---|---|
| Einzelnes Tool Calling | Parameter sind Zeichenketten, Typen Glückssache, Extrafelder laufen mit | parameters / inputSchema fangen vor dem Aufruf ab |
| Mehrstufiger Agent | Die nächste Stufe zerlegt Fließtext, das Handoff hängt an „billing kommt vor“ | Handoff-Objekt mit output_type, Weiterleitung ist prüfbar |
| Über Protokolle hinweg | Function Calling, MCP und A2A je eine Kopie, die auseinanderlaufen | Ein Schema im Git, drei Adapter daraus |
Vorab das Fazit: JSON Schema ist keine Dokumentation für das Modell, sondern der Prüfer, den der Agent-Host vor jedem Schritt, beim Handoff und bei der Bewertung ausführt.
Warum gilt das „jetzt“, nicht „schon immer“?
Frühes Tool Calling hielt, weil die Kette kurz war: Das Modell liefert einen Funktionsnamen und Parameter, der Host führt aus, das Ergebnis landet im Gespräch. Bei Fehlern wird wiederholt, der Nutzer sieht es. Ein Schema stand höchstens in der README – schön, wenn vorhanden.
2025–2026 wurde die Kette länger. Ein Ticket-Agent klassifiziert zuerst, sucht die Bestellung, entscheidet über Erstattung oder Mensch und übergibt das Objekt an den nächsten Agent. Ist ein Zwischenschritt nur „sieht aus wie JSON“, nimmt die nächste Stufe den Fehler als Tatsache. Das Schema wird zur Laufzeitschranke: ohne gültige Prüfung geht es nicht weiter.
Druck kommt auch von der Protokollebene. In MCP Tool Schema vs Function Calling haben wir geschrieben: Anbieter-APIs nutzen parameters, MCP nutzt inputSchema. A2A Extensions schreiben Fähigkeiten in die Agent Card. Die drei Protokolle teilen keine Laufzeit, erkennen aber einen JSON-Schema-Teil. Wer das Schema nicht zuerst festlegt, pflegt drei „fast gleiche“ Definitionen – und findet in Woche drei, dass order_id mal string, mal number ist.
Die DevDay-2026-Prognose sagt dasselbe klarer: Structured Outputs, Function Calling und die Agent-Laufzeit wachsen zu einem JSON-Rohr zusammen. Das Schema ist der Durchmesser dieses Rohrs. Ist der Durchmesser unklar, leckt jedes Protokoll, das man anschließt.
Tool Calling wirkt schon strukturiert – wo bleibt die Lücke?
In tools[] von Function Calling liegt schon ein schemaähnliches parameters. Viele Teams schließen daraus: wir sind strukturiert. In der Produktion knallt es meist in vier Mustern.
Erstens: arguments bleibt eine Zeichenkette. Das Modell liefert:
{
"tool_calls": [{
"id": "call_8f2a",
"type": "function",
"function": {
"name": "create_refund",
"arguments": "{\"order_id\":\"A-1042\",\"amount\":\"99.00\",\"reason\":\"late\"}"
}
}]
}
Der Host muss ein zweites JSON.parse aufrufen. Ob amount Zeichenkette oder Zahl ist, ob reason im Enum liegt, ob ein zusätzliches note ins Buchhaltungssystem darf – ohne Durchsetzung von parameters auf der Hostseite hängt das von der Tagesform des Modells ab. Ein geschriebenes Schema gilt nicht von allein; strict: true bindet nur die Modellseite, der Host prüft weiter selbst.
Zweitens: das Werkzeugergebnis hat kein Schema. role: tool ist meist Freitext. Die nächste Modellstufe „versteht“ den Text erneut. Abfrage erfolgreich, Bestand 0, fehlende Rechte – unterscheiden sich die Formen, biegt ein mehrstufiger Workflow am dritten Schritt falsch ab.
Drittens: Typen sind so weit, dass sie nichts mehr filtern. Ein priority nur mit type: string darf "urgent!!!" werden. Ein Schema ohne enum, required und additionalProperties: false ist nur ein Kommentar.
Viertens: ein einzelner Erfolg verdeckt den Workflow-Bruch. lookup_order liefert zusätzlich status: "ok", der Erstattungs-Agent liest status als Bestellstatus. Der lokale Erfolgspfad sieht das nicht, die Regressionsmenge explodiert. Hier liegt der Wert des Schemas: „dieses Objekt darf zur nächsten Stufe“ wird ein prüfbarer Test, kein Gesprächsprotokoll.
Beim Prüfen solchen geschachtelten JSON zuerst lokal formatieren und syntaktisch prüfen, dann gegen die Definition der letzten Woche einen Diff ziehen. Tool-Antworten mit Nutzerdaten oder Geheimnissen nicht auf öffentliche JSON-Seiten kleben.
JSON Schema hat in Agents vier Rollen
Wer das Schema nur als „Parameteranleitung für Werkzeuge“ sieht, verpasst die drei Schichten, die 2026 wirklich wachsen. Das volle Bild:
- Werkzeugeingabe.
parametersbei Function Calling,inputSchemabei MCP. Bestimmt, was das Modell „anfordern darf“. - Werkzeugausgabe. Rückgabeobjekte von Abfrage, Schreibvorgang, externer API. Bestimmt, was die nächste Stufe „glauben darf“. Diese Schicht fehlt heute am häufigsten.
- Agent-Übergabe (handoff). Klassifikation, Absicht, Konfidenz, Ziel. Im Agents SDK ist das die Grundlage der Weiterleitung, keine Chat-Zusammenfassung.
- Workflow-Zustand und Bewertung. Prüfpunkte, Schrittspuren, Eval-Testdaten. Lange Aufgaben müssen sich aus JSON wiederherstellen lassen, nicht aus dem Gesprächsverlauf.
Beispiel für ein Eingabeschema (Erstattungswerkzeug):
{
"$id": "https://example.com/schemas/tools/create_refund.json",
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^A-[0-9]{4,}$" },
"amount": { "type": "number", "exclusiveMinimum": 0 },
"reason": { "type": "string", "enum": ["late", "damaged", "duplicate", "other"] }
},
"required": ["order_id", "amount", "reason"],
"additionalProperties": false
}
Beispiel für ein Handoff-Schema (Triage → Buchhaltung):
{
"$id": "https://example.com/schemas/handoffs/triage_to_billing.json",
"type": "object",
"properties": {
"intent": { "type": "string", "enum": ["refund", "exchange", "human"] },
"order_id": { "type": "string" },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"from": { "const": "triage" },
"to": { "const": "billing_agent" }
},
"required": ["intent", "order_id", "confidence", "from", "to"],
"additionalProperties": false
}
Die Gemeinsamkeiten wiegen schwerer als die Unterschiede: beides Objekte, beides mit Enums, beides ohne Extrafelder, beides ins Git, beides in CI mit ajv (oder einem vergleichbaren Prüfer). Wechselt das Modell den Snapshot oder das Protokoll zwischen MCP und Function Calling – der Prüfer bleibt. Zu den Schlüsselwörtern siehe das JSON-Schema-Tutorial.
Vom einzelnen Aufruf zum strukturierten Workflow: wo das Schema die Türen stellt
Einzelnes Tool Calling hat eine Tür: Parameter gültig oder nicht. Ein strukturierter Agent-Workflow hat mindestens vier.
Tür 1: vor der Werkzeugwahl. Ab mehr als zehn Werkzeugen ist das ganze Schema in einer Anfrage teuer und fehleranfällig. Wird zuerst gesucht und dann aufgerufen, muss das Suchergebnis selbst eine schemafähige Kurzliste sein – keine vom Modell geschriebene Werkzeugbeschreibung.
Tür 2: vor der Ausführung. Einlesen → prüfen → ausführen. Scheitert die Prüfung, kommt ein strukturierter Fehler zurück (fehlendes Feld, falscher Typ, Wert außerhalb des Enum) – keine Rohzeichenkette an die nächste Stufe. Derselbe Schritt hält Extra-Schlüssel aus Prompt-Injection ab.
Tür 3: vor der Übergabe. Die Triage muss ein Objekt liefern, das zum Handoff-Schema passt, sonst läuft die Buchhaltung nicht an. Die Weiterleitungsregel lautet intent === "refund" && confidence >= 0.8, nicht „im Text steht Erstattung“.
Tür 4: Wiederherstellung und Bewertung. Lange Aufgaben schreiben Prüfpunkte als gültiges JSON:
{
"run_id": "run_20260903_014",
"step": "await_refund_ack",
"state": {
"order_id": "A-1042",
"intent": "refund",
"amount": 99.0
},
"schema": "https://example.com/schemas/state/refund_flow.json"
}
Die Bewertungsmenge ist dieselbe Objektklasse: gegebene Eingabe, Ausgabe muss das Schema passieren, Schlüsselfelder gleich. Wird der Agent „dummer“, zuerst Schema und Testdaten dieser und der letzten Woche vergleichen, dann das Modell verdächtigen. Oft war es ein zusätzliches required oder ein fehlender enum-Wert.
Ein Schema für Function Calling, MCP und A2A
Die Protokollebene nicht je einmal schreiben. Die Richtung: eine Normdatei, drei Projektionen:
| Protokoll | Schema-Feld | Export aus derselben Datei |
|---|---|---|
| Function Calling | function.parameters |
type/properties/required kopieren, strict einschalten |
| MCP | inputSchema |
dasselbe Objekt als Teil von tools/list |
| Structured Outputs | text.format.json_schema |
dieselbe Objektdefinition für Handoff und Endantwort |
| A2A | Agent Card / Extension metadata | Fähigkeitserklärung verweist auf dieselbe $id |
Beim Projizieren auf Teilmengen achten: Der strict-Modus der Anbieter verlangt oft, dass jedes Feld aus properties in required steht, und sperrt Teile von oneOf / $ref. Die Normdatei darf vollständiger sein; das Exportskript schneidet auf das Ziel zu und zieht in CI einen Struktur-Diff „Norm gegen Projektion“, damit niemand eine Seite von Hand ändert.
MCP liefert Werkzeuge, Function Calling drückt aus, wie das Modell die Aufrufabsicht formuliert, A2A regelt, wie Agents einander finden und verhandeln. Das Schema ersetzt diese drei Schichten nicht; es ist das gemeinsame Feldwörterbuch. Das folgt den beiden vorigen Beiträgen – nur wird das Wörterbuch zur Datei im Repository.
Umsetzung: JSON Schema als einzige Quelle der Wahrheit
Sofort machbar, unabhängig von jeder Keynote:
- Im Repository
schemas/tools/,schemas/handoffs/,schemas/state/anlegen. Jede Datei mit stabilem$idund Version. - Per Skript drei Ableitungen für Function Calling / MCP / Structured Outputs exportieren. Felder in den abgeleiteten Dateien nicht von Hand ändern.
- CI prüft mit ajv (oder vergleichbar): Beispielobjekte, historische Testdaten, anonymisierte Produktionsstichproben müssen das aktuelle Schema passieren.
- Neue Werkzeuge standardmäßig mit
additionalProperties: falseund explizitemenum. Offene Erweiterung nur über ein eigenesmetadata-Objekt, nicht durch ein weites Wurzelobjekt. - Ab mehr als zehn Werkzeugen Routing oder Suche; den ganzen Katalog nicht in eine Anfrage kippen.
- Der Host akzeptiert
argumentsals Zeichenkette oder Objekt, damit ein Typwechsel beim Anbieter nicht die ganze Seite alarmiert. - Nutzdaten mit Geheimnissen oder Nutzerbezug nur lokal im Browser: formatieren, Diff, kein Upload.
Das Verzeichnis darf dünn sein. Wichtig: zuerst die Datei, dann der Prompt. „Bitte JSON zurückgeben“ im Prompt kann in CI nicht scheitern; ein Schema schon.
Häufige Fehlannahmen
- Das Schema in den Systemprompt schreiben und fertig sein. Bindung auf der Modellseite und Prüfung auf der Hostseite sind zwei Dinge. Ohne Hostprüfung verschwindet der Vertrag, sobald
strictaus ist oder der Snapshot wechselt. - Nur Eingaben prüfen, nicht Ausgaben und Handoffs. Bei mehrstufigen Agents knallt es häufiger, weil „die vorige Stufe eine unerwartete Form lieferte“.
- Pro Protokoll ein „fast gleiches“ Schema von Hand. In Woche drei laufen sie auseinander. Exportieren, nicht kopieren.
- Mit einem weiten
type: objectdie Gestaltung umgehen. Ein offenes Objekt ist keine Tür. Echte Erweiterung über Versionsnummer oder explizitesmetadata. - Das Schema als Trainingsstoff für das Modell behandeln. Zuerst läuft es für Prüfer und Tests. Klare Beschreibungen helfen bei der Werkzeugwahl, ersetzen aber weder
enumnochrequired. - Felder in der visuellen Orchestrierung ändern, ohne nach Git zurückzuschreiben. Knoten auf der Leinwand sind keine Quelle der Wahrheit. Zuerst das Schema exportieren, dann die Leinwand die Datei lesen lassen.
FAQ
Geht Tool Calling ohne Schema in Produktion?
Im Prototyp ja. Bei festen Werkzeugen, weniger als drei Schritten und für Menschen sichtbaren Fehlern reichen Zeichenketten oft. Sobald Verzweigung, automatische Wiederholung oder ein zweiter Agent dazukommen, wandern Fehler ohne Schema still weiter.
Ersetzen Structured Outputs oder MCP das JSON Schema?
Nein. Sie sind Schichten, die Schema verbrauchen, kein zweites Typsystem. 2026 zitieren mehr Protokolle dieselbe Schema-Datei, statt eine neue Feldsprache zu erfinden.
draft-07 oder 2020-12?
Dem Prüfer und dem Anbieter-Teil folgen. Agents nutzen vor allem type, properties, required, enum, additionalProperties. Ein Teil, der CI und Modell-API zusammenhält, zählt mehr als der neueste Entwurf.
Braucht eine interne API MCP und A2A?
Nicht zwingend. Ein interner Kreis kommt mit Function Calling plus Schema aus. Liegt dasselbe Schema im Repository, ist ein späteres Protokoll nur ein weiteres Exportskript – ohne neue Felder.
Wie prüfe ich fehlgeschlagenes Tool- oder Handoff-JSON?
Im Browser lokal formatieren, gegen das Schema prüfen, welches required fehlt, dann gegen die Vorversion einen Diff ziehen. JSONSort lädt nichts hoch. Antworten mit Geheimnissen nicht auf öffentliche Seiten kleben.
Fazit
AI Agents „brauchen jetzt“ JSON Schema nicht, weil Modelle plötzlich keine natürliche Sprache mehr lesen – sondern weil Workflows länger, Protokolle mehr und Fehler auf der Hostseite gestoppt werden müssen. Tool Calling liefert die Aufrufabsicht; Structured Outputs das Endobjekt; MCP und A2A Versorgung und Verhandlung. Was die Schichten verbindet, sind die prüfbaren, vergleichbaren, exportierbaren Schema-Dateien im Repository.
Statt heute einen längeren Prompt zu schreiben: zuerst schemas/tools/create_refund.json. Modelle wechseln, Protokolle ändern sich – der Durchmesser sollte zuerst stehen.
Weiterlesen
- Was ist JSON Schema? Nutzung und Tutorial Schlüsselwörter, required und additionalProperties
- MCP Tool Schema vs Function Calling Protokollgrenze für Werkzeug-JSON
- A2A Extensions und das JSON-Protokoll Dritte Schicht der Multi-Agent-Interop
- OpenAI DevDay 2026: Prognose zu Structured Outputs, Function Calling und AI Agents Wie drei Schichten zu einem JSON-Rohr werden
- JSONSort lokaler Werkzeugkasten Formatieren, prüfen, Diff
- Alle Beiträge Weitere Notizen zu JSON und AI-Entwicklung
Änderung: Erstfassung