
Gestructureerde AI-output: geldig JSON is nog geen geldig schema

Wil je modeloutput betrouwbaar in een applicatie verwerken, geef dan een ondersteund JSON Schema mee aan de gestructureerde uitvoermodus. Controleer daarna eerst of de aanroep een volledig antwoord of een weigering opleverde, en valideer het resultaat opnieuw tegen het contract van je applicatie.
Een JSON-parser kan een antwoord accepteren terwijl je applicatie er niets mee kan: een verplicht veld kan ontbreken of een getal kan als tekst zijn ingevuld. OpenAI’s handleiding voor Structured Outputs onderscheidt daarom JSON-modus, die geldige JSON oplevert, van gestructureerde uitvoer die een opgegeven schema volgt. Een weigering of afgebroken respons vraagt ook in die laatste modus om een eigen foutpad.
Leg eerst het gegevenscontract vast
Begin bij de velden die de volgende stap werkelijk nodig heeft. Voor een voorwaardelijke classificatietaak kun je ‘categorie’ beperken tot bekende waarden en ‘aantal’ definiëren als geheel getal. Het antwoord met ‘aantal’ als tekstwaarde ‘twee’ is dan syntactisch geldige JSON, maar schendt het contract; de waarde 2 voldoet wel aan die type-eis.
Bepaal per veld ook wat ontbrekende informatie betekent. Een model dat uit de invoer geen aantal kan afleiden, moet geen waarde verzinnen om een verplicht veld te vullen. Kies in dat geval bewust een toegestane lege waarde of een afzonderlijke uitkomst voor niet te bepalen informatie, en leg in de instructie vast wanneer die wordt gebruikt. Een formeel correct object is anders nog steeds een onbetrouwbaar antwoord.
Een veld opnemen onder ‘properties’ maakt het niet automatisch verplicht. De JSON-Schema-uitleg over objecten laat zien dat ‘required’ de aanwezigheid regelt en dat ‘additionalProperties: false’ onbekende velden uitsluit. Dat onderscheid doet ertoe wanneer vervolgcode vaste veldnamen verwacht: een extra sleutel kan geldig zijn volgens een ruim schema, maar alsnog buiten het contract van die code vallen.
Beperk het schema tot wat de API ondersteunt
Neem een schema uit je applicatie niet zonder aanpassing over in het API-verzoek. Leveranciers ondersteunen deelverzamelingen van JSON Schema, en hun eisen aan verplichte velden en objecten verschillen. Deze compacte compatibiliteitsmatrix beschrijft gedocumenteerde functies, geen gemeten betrouwbaarheid:
- OpenAI Structured Outputs: gebruik in de Responses API ‘text.format’ met type ‘json_schema’ en ‘strict: true’. Het hoofdschema moet een object zijn. Alle velden moeten onder ‘required’ staan en objecten hebben ‘additionalProperties: false’ nodig. Een inhoudelijk optioneel veld kan verplicht aanwezig zijn met ‘null’ als toegestane waarde. Onder meer ‘allOf’ en ‘if/then/else’ worden niet ondersteund; een niet-ondersteund schema in strikte modus geeft een verzoekfout.
- Gemini structured outputs: configureer voor de Interactions API ‘response_format’ als tekst met ‘mime_type’ ‘application/json’ en geef het schema op onder ‘schema’. De Gemini-handleiding voor gestructureerde uitvoer noemt onder meer ‘properties’, ‘required’, ‘additionalProperties’, enumwaarden en grenzen voor getallen en arrays als ondersteunde onderdelen. Ze waarschuwt ook dat grote of diep geneste schema’s kunnen worden afgewezen en adviseert validatie in de applicatie.
- OpenAI JSON-modus: deze modus is bedoeld voor parseerbare JSON. Hij legt geen specifieke veldnamen, typen of verplichte waarden volgens jouw schema vast; die controle ligt dus volledig bij de applicatie.
De gedeelde basis bestaat uit eenvoudige objecten, arrays, typen, verplichte velden en waar passend enumwaarden. Vereist een bedrijfsregel een schemafunctie die de gekozen API niet ondersteunt, laat die regel dan niet ongemerkt verdwijnen. Dwing tijdens generatie het ondersteunde deel af en controleer de overige voorwaarde lokaal. Een vaste reeks categorieën past bijvoorbeeld in een enum; of een productcode in je eigen database bestaat, vereist een aparte controle.
Geef elke afwijkende respons een eigen foutpad
Verwerk de API-uitkomst in vaste volgorde. Onderscheid eerst een verzoekfout van een ontvangen respons. Controleer vervolgens of de generatie volledig is, of er een weigering staat en of er daadwerkelijk uitvoer beschikbaar is. Probeer pas daarna de inhoud als JSON te parsen. Zo kan een weigering die buiten het schema valt niet per ongeluk als gegevensobject worden behandeld.
Een afgewezen schema is een configuratiefout: pas het schema of de gekozen modus aan. Hetzelfde verzoek automatisch herhalen verandert die incompatibiliteit niet. Een weigering hoort bij een afzonderlijk resultaat voor de gebruiker of de aanroepende dienst. Een onvolledig antwoord kan onder gecontroleerde voorwaarden opnieuw worden opgevraagd, maar mag niet als gedeeltelijk object doorstromen.
Houd deze uitkomsten ook in foutregistratie uit elkaar. Een parsefout, een schemafout en een inhoudelijk onjuiste waarde vragen verschillende ingrepen. Bewaar daarbij het fouttype en de relevante validatiefout; volledige invoer en uitvoer zijn voor die diagnose vaak niet nodig. Vooral bij automatische vervolgacties voorkomt dit dat een mislukte modelaanroep eruitziet als een geslaagde extractie.
Valideer aan de grens van je applicatie
Parse alleen een complete respons en voer daarna lokale schemavalidatie uit voordat de gegevens naar een database, berekening of volgende aanroep gaan. Die controle vangt onder meer een verkeerd ingestelde uitvoermodus, een wijziging in de schemadefinitie en verschillen tussen het verzonden schema en de verwachtingen van je code op. Gebruik bij voorkeur één beheerde definitie waaruit zowel het API-schema als de lokale validator worden afgeleid.
Schemavalidatie beslist of de vorm klopt, niet of de inhoud waar is. Een categorie kan op de toegestane lijst staan en toch verkeerd zijn voor de aangeleverde tekst. Controleer daarom betekenisvolle relaties afzonderlijk: komt een geëxtraheerde verwijzing in de bron voor wanneer dat vereist is, bestaat een genoemde code in het eigen systeem en mag de gevonden waarde de beoogde actie activeren? Laat die actie pas doorgaan wanneer ook deze controles slagen.
Test de grenzen van het contract
Maak een vaste testset met gewone invoer, ontbrekende gegevens, tegenstrijdige gegevens en tekst die niets met de taak te maken heeft. Bepaal vooraf per geval welke uitkomst aanvaardbaar is: een geldig object met een expliciete lege waarde, een weigering of een beheerste fout. Zo wordt zichtbaar of de toepassing ontbrekende feiten herkent of toch een overtuigend ogend object invult.
Voeg ook technische foutgevallen toe: een onbekend veld, een verkeerd type, een waarde buiten de enum en een afgebroken respons. Controleer niet alleen of de validator een fout meldt, maar ook of de applicatie de gegevens tegenhoudt en het juiste foutpad kiest. Herhaal deze set wanneer het schema, de API-modus of het model verandert; daarmee toets je het volledige contract tussen generatie en verwerking.
Lees ook:
Gerelateerde artikelen


Webhook-handtekeningen controleren: parse de JSON pas na verificatie

Gemini zonder gegevensopslag: één zoekfunctie doorbreekt je instelling

Een SBOM maken in GitHub Actions: scan na de installatiestap

Excel breekt een regel van 40 jaar, maar alleen in de bèta

GPT-6 Sol en Luna halveren API-kosten, maar EU-opslag kent een grens
Abonneer je op onze nieuwsbrief
Ontvang het laatste nieuws over Web3, AI en crypto rechtstreeks in je inbox.