Gestructureerde dataformaten zoals JSON en YAML zijn essentieel voor het bouwen van applicaties die AI-outputs programmatisch verwerken. Dit hoofdstuk behandelt technieken voor betrouwbare gestructureerde outputgeneratie.

<Callout type="info" title="Van Tekst naar Data">
JSON en YAML transformeren AI-outputs van vrije tekst naar gestructureerde, type-veilige data die code direct kan gebruiken.
</Callout>

## Waarom Gestructureerde Formaten?

<JsonYamlDemo />

## JSON Prompting Basis

JSON (JavaScript Object Notation) is het meest gebruikte formaat voor programmatische AI-outputs. De strikte syntax maakt het gemakkelijk te parsen, maar betekent ook dat kleine fouten je hele pipeline kunnen breken.

### Do's en Don'ts: JSON Opvragen

<Compare 
  before={{ label: "❌ Niet doen: Vaag verzoek", content: "Give me the user info as JSON." }}
  after={{ label: "✓ Wel doen: Toon het schema", content: "Extract user info as JSON matching this schema:\n\n{\n  \"name\": \"string\",\n  \"age\": number,\n  \"email\": \"string\"\n}\n\nReturn ONLY valid JSON, no markdown." }}
/>

### Eenvoudige JSON Output

Begin met een schema dat de verwachte structuur toont. Het model vult waarden in op basis van de invoertekst.

```
Extract the following information as JSON:

{
  "name": "string",
  "age": number,
  "email": "string"
}

Text: "Contact John Smith, 34 years old, at john@example.com"
```

Output:
```json
{
  "name": "John Smith",
  "age": 34,
  "email": "john@example.com"
}
```

### Geneste JSON Structuren

Echte data heeft vaak geneste relaties. Definieer elk niveau van je schema duidelijk, vooral voor arrays van objecten.

```
Parse this order into JSON:

{
  "order_id": "string",
  "customer": {
    "name": "string",
    "email": "string"
  },
  "items": [
    {
      "product": "string",
      "quantity": number,
      "price": number
    }
  ],
  "total": number
}

Order: "Order #12345 for Jane Doe (jane@email.com): 2x Widget ($10 each), 
1x Gadget ($25). Total: $45"
```

### Geldige JSON Garanderen

<Callout type="warning" title="Veelvoorkomend Faalmoment">
Modellen verpakken JSON vaak in markdown codeblokken of voegen verklarende tekst toe. Wees expliciet dat je alleen ruwe JSON wilt.
</Callout>

Voeg expliciete instructies toe:

```
CRITICAL: Return ONLY valid JSON. No markdown, no explanation, 
no additional text before or after the JSON object.

If a field cannot be determined, use null.
Ensure all strings are properly quoted and escaped.
Numbers should not be quoted.
```

## YAML Prompting Basis

YAML is leesbaarder voor mensen dan JSON en ondersteunt commentaar. Het is de standaard voor configuratiebestanden, vooral in DevOps (Docker, Kubernetes, GitHub Actions).

### Eenvoudige YAML Output

YAML gebruikt inspringing in plaats van accolades. Geef een template die de verwachte structuur toont.

```
Generate a configuration file in YAML format:

server:
  host: string
  port: number
  ssl: boolean
database:
  type: string
  connection_string: string

Requirements: Production server on port 443 with SSL, PostgreSQL database
```

Output:
```yaml
server:
  host: "0.0.0.0"
  port: 443
  ssl: true
database:
  type: "postgresql"
  connection_string: "postgresql://user:pass@localhost:5432/prod"
```

### Complexe YAML Structuren

Voor complexe configuraties, wees specifiek over de vereisten. Het model kent gangbare patronen voor tools zoals GitHub Actions, Docker Compose en Kubernetes.

```
Generate a GitHub Actions workflow in YAML:

Requirements:
- Trigger on push to main and pull requests
- Run on Ubuntu latest
- Steps: checkout, setup Node 18, install dependencies, run tests
- Cache npm dependencies
```

## Type Definities in Prompts

Type definities geven het model een precies contract voor outputstructuur. Ze zijn explicieter dan voorbeelden en gemakkelijker programmatisch te valideren.

### TypeScript-achtige Types Gebruiken

TypeScript interfaces zijn bekend bij ontwikkelaars en beschrijven optionele velden, union types en arrays nauwkeurig. Het prompts.chat platform gebruikt deze aanpak voor gestructureerde prompts.

<TryIt 
  title="TypeScript Interface Extractie"
  description="Gebruik een TypeScript interface om gestructureerde data te extraheren."
  prompt={`Extract data according to this type definition:

interface ChatPersona {
    name?: string;
    role?: string;
    tone?: "professional" | "casual" | "friendly" | "technical";
    expertise?: string[];
    personality?: string[];
    background?: string;
}

Return as JSON matching this interface.

Description: "A senior software engineer named Alex who reviews code. They're analytical and thorough, with expertise in backend systems and databases. Professional but approachable tone."`}
/>

### JSON Schema Definitie

<Callout type="info" title="Industriestandaard">
JSON Schema is een formele specificatie voor het beschrijven van JSON structuur. Het wordt ondersteund door veel validatiebibliotheken en API-tools.
</Callout>

JSON Schema biedt beperkingen zoals min/max waarden, verplichte velden en regex patronen:

```
Extract data according to this JSON Schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["title", "author", "year"],
  "properties": {
    "title": { "type": "string" },
    "author": { "type": "string" },
    "year": { "type": "integer", "minimum": 1000, "maximum": 2100 },
    "genres": { 
      "type": "array", 
      "items": { "type": "string" }
    },
    "rating": { 
      "type": "number", 
      "minimum": 0, 
      "maximum": 5 
    }
  }
}

Book: "1984 by George Orwell (1949) - A dystopian masterpiece. 
Genres: Science Fiction, Political Fiction. Rated 4.8/5"
```

## Omgaan met Arrays

Arrays vereisen speciale aandacht. Specificeer of je een vast aantal items nodig hebt of een lijst met variabele lengte, en hoe lege gevallen behandeld moeten worden.

### Arrays met Vaste Lengte

Wanneer je exact N items nodig hebt, vermeld dit expliciet. Het model zorgt ervoor dat de array de juiste lengte heeft.

```
Extract exactly 3 key points as JSON:

{
  "key_points": [
    "string (first point)",
    "string (second point)", 
    "string (third point)"
  ]
}

Article: [article text]
```

### Arrays met Variabele Lengte

Voor arrays met variabele lengte, specificeer wat te doen wanneer er nul items zijn. Het toevoegen van een count-veld helpt de volledigheid van extractie te verifiëren.

```
Extract all mentioned people as JSON:

{
  "people": [
    {
      "name": "string",
      "role": "string or null if not mentioned"
    }
  ],
  "count": number
}

If no people are mentioned, return empty array.

Text: [text]
```

## Enum Waarden en Beperkingen

Enums beperken waarden tot een voorgedefinieerde set. Dit is cruciaal voor classificatietaken en overal waar je consistente, voorspelbare outputs nodig hebt.

### Do's en Don'ts: Enum Waarden

<Compare 
  before={{ label: "❌ Niet doen: Open categorieën", content: "Classify this text into a category.\n\n{\n  \"category\": \"string\"\n}" }}
  after={{ label: "✓ Wel doen: Beperk tot geldige waarden", content: "Classify this text. Category MUST be exactly one of:\n- \"technical\"\n- \"business\"\n- \"creative\"\n- \"personal\"\n\n{\n  \"category\": \"one of the values above\"\n}" }}
/>

### String Enums

Vermeld toegestane waarden expliciet. Gebruik "MUST be one of" taal om strikte matching af te dwingen.

```
Classify this text. The category MUST be one of these exact values:
- "technical"
- "business" 
- "creative"
- "personal"

Return JSON:
{
  "text": "original text (truncated to 50 chars)",
  "category": "one of the enum values above",
  "confidence": number between 0 and 1
}

Text: [text to classify]
```

### Gevalideerde Getallen

Numerieke beperkingen voorkomen waarden buiten bereik. Specificeer het type (integer vs float) en het geldige bereik.

```
Rate these aspects. Each score MUST be an integer from 1 to 5.

{
  "quality": 1-5,
  "value": 1-5,
  "service": 1-5,
  "overall": 1-5
}

Review: [review text]
```

## Omgaan met Ontbrekende Data

Echte tekst mist vaak bepaalde informatie. Definieer hoe het model ontbrekende data moet behandelen om gehallucineerde waarden te voorkomen.

### Do's en Don'ts: Ontbrekende Informatie

<Compare 
  before={{ label: "❌ Niet doen: AI laten raden", content: "Extract all company details as JSON:\n{\n  \"revenue\": number,\n  \"employees\": number\n}" }}
  after={{ label: "✓ Wel doen: Expliciet null toestaan", content: "Extract company details. Use null for any field NOT explicitly mentioned. Do NOT invent or estimate values.\n\n{\n  \"revenue\": \"number or null\",\n  \"employees\": \"number or null\"\n}" }}
/>

### Null Waarden

Sta expliciet null toe en instrueer het model om geen informatie te verzinnen. Dit is veiliger dan het model laten raden.

```
Extract information. Use null for any field that cannot be 
determined from the text. Do NOT invent information.

{
  "company": "string or null",
  "revenue": "number or null",
  "employees": "number or null",
  "founded": "number (year) or null",
  "headquarters": "string or null"
}

Text: "Apple, headquartered in Cupertino, was founded in 1976."
```

Output:
```json
{
  "company": "Apple",
  "revenue": null,
  "employees": null,
  "founded": 1976,
  "headquarters": "Cupertino"
}
```

### Standaardwaarden

Wanneer standaardwaarden zinvol zijn, specificeer ze in het schema. Dit is gebruikelijk voor configuratie-extractie.

```
Extract settings with these defaults if not specified:

{
  "theme": "light" (default) | "dark",
  "language": "en" (default) | other ISO code,
  "notifications": true (default) | false,
  "fontSize": 14 (default) | number
}

User preferences: "I want dark mode and larger text (18px)"
```

## Multi-Object Responses

Vaak moet je meerdere items uit één invoer extraheren. Definieer de arraystructuur en eventuele sorteer-/groeperingsvereisten.

### Array van Objecten

Voor lijsten van vergelijkbare items, definieer het objectschema één keer en specificeer dat het een array is.

```
Parse this list into JSON array:

[
  {
    "task": "string",
    "priority": "high" | "medium" | "low",
    "due": "ISO date string or null"
  }
]

Todo list:
- Finish report (urgent, due tomorrow)
- Call dentist (low priority)
- Review PR #123 (medium, due Friday)
```

### Gegroepeerde Objecten

Groeperingstaken vereisen categorisatielogica. Het model sorteert items in de categorieën die je definieert.

```
Categorize these items into JSON:

{
  "fruits": ["string array"],
  "vegetables": ["string array"],
  "other": ["string array"]
}

Items: apple, carrot, bread, banana, broccoli, milk, orange, spinach
```

## YAML voor Configuratiegeneratie

YAML blinkt uit bij DevOps-configuraties. Het model kent standaardpatronen voor gangbare tools en kan productieklare configs genereren.

### Do's en Don'ts: YAML Configs

<Compare 
  before={{ label: "❌ Niet doen: Vage vereisten", content: "Generate a docker-compose file for my app." }}
  after={{ label: "✓ Wel doen: Specificeer componenten en behoeften", content: "Generate docker-compose.yml for:\n- Node.js app (port 3000)\n- PostgreSQL database\n- Redis cache\n\nInclude: health checks, volume persistence, environment from .env file" }}
/>

### Docker Compose

Specificeer de services die je nodig hebt en eventuele speciale vereisten. Het model zorgt voor de YAML-syntax en best practices.

```
Generate a docker-compose.yml for:
- Node.js app on port 3000
- PostgreSQL database
- Redis cache
- Nginx reverse proxy

Include:
- Health checks
- Volume persistence
- Environment variables from .env file
- Network isolation
```

### Kubernetes Manifests

Kubernetes manifests zijn uitgebreid maar volgen voorspelbare patronen. Geef de belangrijkste parameters en het model genereert conforme YAML.

```
Generate Kubernetes deployment YAML:

Deployment:
- Name: api-server
- Image: myapp:v1.2.3
- Replicas: 3
- Resources: 256Mi memory, 250m CPU (requests)
- Health checks: /health endpoint
- Environment from ConfigMap: api-config

Also generate matching Service (ClusterIP, port 8080)
```

## Validatie en Foutafhandeling

Voor productiesystemen, bouw validatie in je prompts. Dit vangt fouten op voordat ze door je pipeline propageren.

### Zelf-Validatie Prompt

Vraag het model om zijn eigen output te valideren tegen regels die je specificeert. Dit vangt formaatfouten en ongeldige waarden op.

```
Extract data as JSON, then validate your output.

Schema:
{
  "email": "valid email format",
  "phone": "E.164 format (+1234567890)",
  "date": "ISO 8601 format (YYYY-MM-DD)"
}

After generating JSON, check:
1. Email contains @ and valid domain
2. Phone starts with + and contains only digits
3. Date is valid and parseable

If validation fails, fix the issues before responding.

Text: [contact information]
```

### Fout Response Formaat

Definieer aparte succes- en foutformaten. Dit maakt programmatische afhandeling veel gemakkelijker.

```
Attempt to extract data. If extraction fails, return error format:

Success format:
{
  "success": true,
  "data": { ... extracted data ... }
}

Error format:
{
  "success": false,
  "error": "description of what went wrong",
  "partial_data": { ... any data that could be extracted ... }
}
```

## JSON vs YAML: Wanneer Welke Gebruiken

<div className="my-4 grid md:grid-cols-2 gap-4">
  <div className="p-4 bg-amber-50 dark:bg-amber-950/30 rounded-lg border border-amber-200 dark:border-amber-800">
    <div className="font-semibold text-amber-700 dark:text-amber-300 mb-2">Gebruik JSON Wanneer</div>
    <div className="text-sm space-y-1">
      <p className="m-0!">Programmatisch parsen nodig is</p>
      <p className="m-0!">API responses</p>
      <p className="m-0!">Strikte type-eisen</p>
      <p className="m-0!">JavaScript/Web integratie</p>
      <p className="m-0!">Compacte representatie</p>
    </div>
  </div>
  <div className="p-4 bg-purple-50 dark:bg-purple-950/30 rounded-lg border border-purple-200 dark:border-purple-800">
    <div className="font-semibold text-purple-700 dark:text-purple-300 mb-2">Gebruik YAML Wanneer</div>
    <div className="text-sm space-y-1">
      <p className="m-0!">Leesbaarheid belangrijk is</p>
      <p className="m-0!">Configuratiebestanden</p>
      <p className="m-0!">Commentaar nodig is</p>
      <p className="m-0!">DevOps/Infrastructuur</p>
      <p className="m-0!">Diep geneste structuren</p>
    </div>
  </div>
</div>

## Prompts.chat Gestructureerde Prompts

Op prompts.chat kun je prompts maken met gestructureerde outputformaten:

```
When creating a prompt on prompts.chat, you can specify:

Type: STRUCTURED
Format: JSON or YAML

The platform will:
- Validate outputs against your schema
- Provide syntax highlighting
- Enable easy copying of structured output
- Support template variables in your schema
```

## Veelvoorkomende Valkuilen

<Callout type="warning" title="Debug Deze Eerst">
Deze drie problemen veroorzaken de meeste JSON parsing-fouten. Controleer hierop wanneer je code AI-output niet kan parsen.
</Callout>

### 1. Markdown Codeblokken

**Probleem:** Model verpakt JSON in ```json blokken

**Oplossing:** 
```
Return ONLY the JSON object. Do not wrap in markdown code blocks.
Do not include ```json or ``` markers.
```

### 2. Afsluitende Komma's

**Probleem:** Ongeldige JSON door afsluitende komma's

**Oplossing:**
```
Ensure valid JSON syntax. No trailing commas after the last 
element in arrays or objects.
```

### 3. Niet-geëscapete Strings

**Probleem:** Aanhalingstekens of speciale karakters breken JSON

**Oplossing:**
```
Properly escape special characters in strings:
- \" for quotes
- \\ for backslashes
- \n for newlines
```

## Samenvatting

<Callout type="tip" title="Belangrijkste Technieken">
Definieer schema's expliciet met TypeScript interfaces of JSON Schema. Specificeer types en beperkingen, handel nulls en standaardwaarden af, vraag om zelf-validatie, en kies het juiste formaat voor je use case.
</Callout>

<Quiz 
  question="Wanneer zou je YAML verkiezen boven JSON voor AI-outputs?"
  options={[
    "Bij het bouwen van REST API's",
    "Wanneer de output leesbaar moet zijn voor mensen en commentaar mag bevatten",
    "Bij het werken met JavaScript-applicaties",
    "Wanneer je de meest compacte representatie nodig hebt"
  ]}
  correctIndex={1}
  explanation="YAML heeft de voorkeur wanneer leesbaarheid belangrijk is, zoals bij configuratiebestanden, DevOps manifests en documentatie. Het ondersteunt ook commentaar, in tegenstelling tot JSON."
/>

Dit sluit Deel II over technieken af. In Deel III verkennen we praktische toepassingen in verschillende domeinen.
