Skip to content
Moritz Klaßen

Moritz Klassen

Künstliche Intelligenz 6 Min. Lesezeit

KI-Ausgaben mit JSON Schema vor Aktionen prüfen

Eine KI-Automation sollte erst dann Tickets, Datensätze oder Nachrichten erzeugen, wenn ihre Ausgabe einen maschinenlesbaren Vertrag erfüllt. Mit JSON Schema machst du diesen Vertrag ausführbar und verhinderst, dass unerwartete Felder oder Werte unbemerkt in den nächsten Schritt gelangen.

Ein häufiges Versprechen bei KI-Automationen lautet: Wenn der Prompt das gewünschte JSON genau beschreibt, kommt auch verwertbares JSON zurück. Darauf solltest du keine Verarbeitungskette bauen. Ein Prompt beschreibt deine Erwartung, erzwingt aber noch keinen belastbaren Übergabevertrag zwischen KI-Modell und Anwendung.

Behandle die Modellausgabe deshalb wie andere externe Eingaben: Du prüfst sie, bevor dein Code ein Ticket erstellt, eine E-Mail vorbereitet oder einen Datensatz verändert. JSON Schema eignet sich dafür, weil du erlaubte Felder, Datentypen, Wertebereiche und Pflichtangaben maschinenlesbar festlegen kannst.

Warum gültiges JSON allein nicht genügt

Eine Ausgabe kann syntaktisch korrektes JSON sein und trotzdem nicht zu deiner Anwendung passen. Aus priority kann plötzlich urgency werden. Statt des erwarteten Werts high liefert das Modell critical. Eine Zusammenfassung erscheint als Array, obwohl der folgende Schritt einen String erwartet.

JSON.parse() erkennt solche Abweichungen nicht. Der Parser beantwortet lediglich die Frage, ob der Text gültiges JSON ist. JSON Schema prüft zusätzlich, ob dessen Struktur deinem vereinbarten Format entspricht.

Diese Unterscheidung ist für KI-Automationen entscheidend: Der nachfolgende Code sollte nicht erraten müssen, was das Modell vermutlich gemeint hat. Sobald du dort Ausweichlogik für wechselnde Feldnamen und Datentypen einbaust, verteilst du die Unsicherheit der KI über deine gesamte Anwendung.

Das Schema beginnt beim nächsten Verarbeitungsschritt

Entwirf das Schema nicht ausgehend von allem, was das Modell theoretisch liefern könnte. Beginne mit der Aktion, die nach der KI-Auswertung stattfinden soll. Welche Angaben benötigt dieser Schritt zwingend? Welche Werte kann dein Code tatsächlich verarbeiten? Welche Zusatzinformationen würden nur verlockend aussehen, aber keine Funktion erfüllen?

Angenommen, eine Automation soll eingehende Anfragen einordnen und einen nächsten Schritt vorschlagen. Sie darf noch nichts versenden oder endgültig priorisieren. Der folgende Code benötigt eine Kategorie, eine begrenzte Prioritätsauswahl, eine kurze Zusammenfassung und eine vorgeschlagene Aktion.

Ein passendes Schema kann so aussehen:

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "category",
    "priority",
    "summary",
    "suggested_action"
  ],
  "properties": {
    "category": {
      "type": "string",
      "enum": ["billing", "technical", "general"]
    },
    "priority": {
      "type": "string",
      "enum": ["low", "normal", "high"]
    },
    "summary": {
      "type": "string",
      "minLength": 1,
      "maxLength": 300
    },
    "suggested_action": {
      "type": "string",
      "enum": [
        "create_ticket",
        "request_details",
        "manual_review"
      ]
    }
  }
}

Mehrere Details daran sind absichtlich streng. Alle vier Felder sind erforderlich. enum begrenzt Werte auf Varianten, die dein Code kennt. Die Zusammenfassung hat eine maximale Länge. additionalProperties: false lehnt unbekannte Felder ab, statt sie stillschweigend mitzuschleppen.

Gerade die letzte Regel spart später Arbeit. Ohne sie kann ein Modell zusätzliche Eigenschaften erzeugen, die jemand versehentlich als verlässlich interpretiert. Wenn du ein Feld nicht definiert und geprüft hast, sollte der restliche Workflow es auch nicht verwenden.

Die Validierung gehört direkt vor die fachliche Verarbeitung

Viele KI-Schnittstellen können strukturierte Ausgaben anfordern. Das verbessert die Übergabe, ersetzt aber nicht zwangsläufig die Prüfung in deiner eigenen Anwendung. Dort entscheidet sich schließlich, ob die Daten weiterverarbeitet werden dürfen.

Die Reihenfolge bleibt überschaubar:

  1. Deine Anwendung erhält die rohe Modellausgabe.
  2. Sie parst die Ausgabe als JSON.
  3. Ein Schema-Validator prüft die Struktur.
  4. Erst danach greifen fachliche Regeln.
  5. Nur eine bestandene Ausgabe erreicht den nächsten Verarbeitungsschritt.

In JavaScript kannst du dafür beispielsweise einen JSON-Schema-Validator wie Ajv verwenden. Das folgende Beispiel nimmt an, dass das oben gezeigte Schema als schema importiert wurde:

import Ajv from "ajv";
import schema from "./classification.schema.json" with { type: "json" };

const ajv = new Ajv({ allErrors: true });
const validate = ajv.compile(schema);

export function parseModelOutput(rawOutput) {
  let data;

  try {
    data = JSON.parse(rawOutput);
  } catch {
    throw new Error("Die KI-Ausgabe ist kein gültiges JSON.");
  }

  if (!validate(data)) {
    const details = ajv.errorsText(validate.errors, {
      separator: "; "
    });

    throw new Error(`Die KI-Ausgabe verletzt das Schema: ${details}`);
  }

  return data;
}

Die Funktion gibt ausschließlich Daten zurück, die den strukturellen Vertrag erfüllen. Dein Anwendungscode muss danach keine Alternativnamen prüfen und keine unerwarteten Datentypen reparieren. Er bekommt entweder ein definiertes Objekt oder einen klaren Fehler.

Was bei einem Fehler geschehen soll, hängt von der Aktion ab. Für eine unverbindliche interne Zusammenfassung kann ein erneuter Versuch vertretbar sein. Vor einem Schreibzugriff auf ein Kundensystem ist ein Abbruch oder eine manuelle Prüfung meist die sauberere Grenze. Wichtig ist, dass eine ungültige Ausgabe nicht versehentlich denselben Weg nimmt wie eine gültige.

Strukturprüfung und fachliche Prüfung bleiben getrennt

JSON Schema kann bestätigen, dass priority den Wert high enthält. Es kann nicht entscheiden, ob die Anfrage tatsächlich eine hohe Priorität verdient. Ebenso kann eine Zusammenfassung unter 300 Zeichen formal gültig und inhaltlich falsch sein.

Nach der Schema-Prüfung brauchst du deshalb je nach Anwendungsfall deterministische Geschäftsregeln. Deterministisch bedeutet hier: Gleiche Eingaben führen nach festem Code immer zur gleichen Entscheidung. Beispiele sind erlaubte Statusübergänge, vorhandene Kundenkennungen oder die Regel, dass bestimmte Aktionen grundsätzlich eine menschliche Freigabe benötigen.

Trenne dabei drei Fragen:

  • Ist die Ausgabe lesbar? Das beantwortet der JSON-Parser.
  • Hat sie die vereinbarte Struktur? Das beantwortet JSON Schema.
  • Darf die Anwendung damit handeln? Das beantworten deine fachlichen Regeln.

Diese Grenzen verhindern, dass dem Schema Fähigkeiten zugeschrieben werden, die es nicht hat. Es ist ein Vertragsprüfer, kein Wahrheitsprüfer.

Enums sind besser als freie Formulierungen

Freitext ist sinnvoll, wenn Menschen den Inhalt lesen sollen. Für Verzweigungen im Code ist er meist die falsche Schnittstelle. Ein Modell kann „hohe Priorität“, „dringend“, „kritisch“ oder „sofort“ formulieren und in allen Fällen ungefähr dasselbe meinen. Dein Code braucht trotzdem eine eindeutige Variante.

Verwende deshalb enum, sobald ein Feld eine technische Entscheidung steuert. Das gilt etwa für Kategorien, erlaubte Aktionen, Statuswerte oder Zielsysteme. Die Beschreibung im Prompt sollte dieselben Werte nennen, aber das Schema setzt die tatsächliche Grenze.

Vermeide dagegen ein Enum mit dutzenden ähnlichen Varianten. Je schwerer Menschen zwei Werte auseinanderhalten können, desto unsicherer wird auch ihre Verwendung im Workflow. Dann ist häufig eine gröbere technische Kategorie sinnvoller, ergänzt durch eine lesbare Begründung, die keine Aktion direkt steuert.

Optionale Felder brauchen eine eindeutige Bedeutung

Ein optionales Feld kann fehlen. Das ist etwas anderes als ein vorhandenes Feld mit null oder einem leeren String. Wenn der nachfolgende Code diese Fälle unterschiedlich behandelt, muss das Schema die Unterscheidung ausdrücklich abbilden.

Für eine unbekannte Kundennummer könntest du beispielsweise einen String oder null erlauben. Ein leerer String wäre dann weiterhin ungültig:

{
  "customer_reference": {
    "type": ["string", "null"],
    "minLength": 1
  }
}

Lege solche Bedeutungen fest, bevor du den Prompt formulierst. Sonst entscheidet das Modell beiläufig, ob „nicht vorhanden“ durch ein fehlendes Feld, null, einen leeren String oder den Text „unbekannt“ dargestellt wird. Technisch sind das vier verschiedene Zustände. Meist brauchst du nur einen davon.

Teste den Vertrag mit absichtlich schlechten Ausgaben

Ein einzelnes korrektes Beispiel zeigt nur, dass der gewünschte Fall funktioniert. Für den Übergabevertrag sind abgelehnte Fälle mindestens ebenso wichtig. Du kannst den Validator unabhängig vom KI-Modell mit festen Testdaten prüfen.

Sinnvolle Testfälle sind:

  • ein fehlendes Pflichtfeld,
  • ein unbekannter Enum-Wert,
  • ein zusätzlicher, nicht definierter Schlüssel,
  • ein falscher Datentyp,
  • eine zu lange Zusammenfassung,
  • syntaktisch ungültiges JSON.

Diese Tests sollten nicht kontrollieren, ob ein bestimmtes Modell immer denselben Satz schreibt. Sie prüfen deinen stabilen Teil der Integration: Welche Form akzeptiert die Anwendung und welche lehnt sie ab? Dadurch kannst du Prompt oder Modell später ändern, ohne den Vertrag zum nächsten Verarbeitungsschritt stillschweigend aufzuweichen.

Änderungen am Schema sind Schnittstellenänderungen

Wenn du einen Enum-Wert umbenennst oder ein neues Pflichtfeld ergänzt, änderst du die Schnittstelle zwischen KI-Aufruf und Anwendungscode. Aktualisiere deshalb Prompt, Schema, Tests und nachfolgende Verarbeitung gemeinsam.

Bei länger laufenden oder zeitversetzten Prozessen kann eine Versionsangabe im Ausgabeobjekt sinnvoll sein. So erkennst du, nach welchem Vertrag ein gespeicherter Auftrag erzeugt wurde. Für einen kurzen synchronen Ablauf reicht häufig eine gemeinsam ausgelieferte Schema-Datei. Eine Versionsverwaltung nur zur Dekoration macht das JSON nicht erwachsener.

Die praktische Grenze: Erst Vertrag, dann Wirkung

JSON Schema macht eine KI-Ausgabe nicht automatisch fachlich korrekt. Es verhindert jedoch, dass strukturelle Überraschungen ungeprüft in deterministischen Code gelangen. Genau dafür ist es das passende Werkzeug.

Formuliere den Vertrag aus Sicht des nächsten Verarbeitungsschritts, begrenze technische Entscheidungen mit Enums und lehne unbekannte Felder ab. Prüfe anschließend fachliche Regeln separat. So endet der probabilistische Teil deiner Automation an einer klaren Stelle, bevor eine konkrete Wirkung im System entsteht.

Häufige Fragen

Kurz beantwortet, damit du schneller einschätzen kannst, was für dein Projekt wichtig ist.

Reicht gültiges JSON für eine KI-Automation aus?

Nein. Gültiges JSON kann unerwartete Felder, falsche Datentypen oder unbekannte Werte enthalten. JSON Schema prüft zusätzlich, ob die Ausgabe dem von deiner Anwendung erwarteten Vertrag entspricht.

Kann JSON Schema inhaltlich falsche KI-Antworten erkennen?

Nur sehr begrenzt. Das Schema prüft Struktur, Datentypen, Pflichtfelder und erlaubte Werte. Ob eine Einstufung oder Zusammenfassung fachlich stimmt, musst du mit Geschäftsregeln oder einer menschlichen Prüfung absichern.

Sollte eine ungültige KI-Ausgabe automatisch erneut erzeugt werden?

Das hängt von der nachfolgenden Wirkung ab. Bei unverbindlichen internen Inhalten kann ein begrenzter neuer Versuch sinnvoll sein. Vor Schreibzugriffen oder externen Nachrichten sollte die Automation im Zweifel abbrechen oder eine Prüfung anfordern.

Warum sollte additionalProperties auf false stehen?

Damit der Validator nicht definierte Felder ablehnt. So können zusätzliche Modellausgaben nicht unbemerkt in den Workflow gelangen oder später irrtümlich als verlässliche Daten verwendet werden.

Kontakt

Lass uns über dein Projekt sprechen.

Ob neue Website, Laravel-Tool, Relaunch oder technischer Sparringstermin: Buch dir gern direkt einen Slot oder schreib mir eine Mail.

Erstgespräch buchen Lieber per Mail? hello@moritzklassen.com
Moritz Klaßen
Moritz Klaßen Entwickler & Ansprechpartner