Les formats de données structurées comme JSON et YAML sont essentiels pour construire des applications qui consomment les sorties d'IA de manière programmatique. Ce chapitre couvre les techniques pour une génération fiable de sorties structurées.

<Callout type="info" title="Du Texte aux Données">
JSON et YAML transforment les sorties d'IA de texte libre en données structurées et typées que le code peut consommer directement.
</Callout>

## Pourquoi les Formats Structurés ?

<JsonYamlDemo />

## Bases du Prompting JSON

JSON (JavaScript Object Notation) est le format le plus courant pour les sorties programmatiques d'IA. Sa syntaxe stricte le rend facile à analyser, mais signifie aussi que de petites erreurs peuvent casser votre pipeline entier.

### À Faire et À Éviter : Demander du JSON

<Compare 
  before={{ label: "❌ À Éviter : Demande vague", content: "Donne-moi les infos utilisateur en JSON." }}
  after={{ label: "✓ À Faire : Montrer le schéma", content: "Extrais les infos utilisateur en JSON correspondant à ce schéma :\n\n{\n  \"nom\": \"string\",\n  \"age\": number,\n  \"email\": \"string\"\n}\n\nRetourne UNIQUEMENT du JSON valide, pas de markdown." }}
/>

### Sortie JSON Simple

Commencez avec un schéma montrant la structure attendue. Le modèle remplira les valeurs basées sur le texte d'entrée.

```
Extrais les informations suivantes en JSON :

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

Texte : "Contactez Jean Dupont, 34 ans, à jean@exemple.com"
```

Sortie :
```json
{
  "nom": "Jean Dupont",
  "age": 34,
  "email": "jean@exemple.com"
}
```

### Structures JSON Imbriquées

Les données du monde réel ont souvent des relations imbriquées. Définissez clairement chaque niveau de votre schéma, surtout pour les tableaux d'objets.

```
Parse cette commande en JSON :

{
  "id_commande": "string",
  "client": {
    "nom": "string",
    "email": "string"
  },
  "articles": [
    {
      "produit": "string",
      "quantite": number,
      "prix": number
    }
  ],
  "total": number
}

Commande : "Commande #12345 pour Marie Martin (marie@email.com) : 2x Widget (10€ chacun), 
1x Gadget (25€). Total : 45€"
```

### Assurer un JSON Valide

<Callout type="warning" title="Point d'Échec Courant">
Les modèles enveloppent souvent le JSON dans des blocs de code markdown ou ajoutent du texte explicatif. Soyez explicite sur le fait de vouloir uniquement du JSON brut.
</Callout>

Ajoutez des instructions explicites :

```
CRITIQUE : Retourne UNIQUEMENT du JSON valide. Pas de markdown, pas d'explication, 
pas de texte additionnel avant ou après l'objet JSON.

Si un champ ne peut pas être déterminé, utilise null.
Assure-toi que toutes les chaînes sont correctement entre guillemets et échappées.
Les nombres ne doivent pas être entre guillemets.
```

## Bases du Prompting YAML

YAML est plus lisible que JSON et supporte les commentaires. C'est le standard pour les fichiers de configuration, surtout en DevOps (Docker, Kubernetes, GitHub Actions).

### Sortie YAML Simple

YAML utilise l'indentation au lieu des accolades. Fournissez un template montrant la structure attendue.

```
Génère un fichier de configuration en format YAML :

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

Exigences : Serveur de production sur port 443 avec SSL, base de données PostgreSQL
```

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

### Structures YAML Complexes

Pour les configurations complexes, soyez spécifique sur les exigences. Le modèle connaît les patterns courants pour des outils comme GitHub Actions, Docker Compose et Kubernetes.

```
Génère un workflow GitHub Actions en YAML :

Exigences :
- Déclencher sur push vers main et pull requests
- Exécuter sur Ubuntu latest
- Étapes : checkout, setup Node 18, installer dépendances, lancer tests
- Mettre en cache les dépendances npm
```

## Définitions de Types dans les Prompts

Les définitions de types donnent au modèle un contrat précis pour la structure de sortie.

### Utiliser des Types Style TypeScript

Les interfaces TypeScript sont familières aux développeurs et décrivent précisément les champs optionnels, types union et tableaux.

<TryIt 
  title="Extraction Interface TypeScript"
  description="Utilisez une interface TypeScript pour extraire des données structurées."
  prompt={`Extrais les données selon cette définition de type :

interface PersonaChat {
    nom?: string;
    role?: string;
    ton?: "professionnel" | "decontracte" | "amical" | "technique";
    expertise?: string[];
    personnalite?: string[];
    contexte?: string;
}

Retourne en JSON correspondant à cette interface.

Description : "Un ingénieur logiciel senior nommé Alex qui révise du code. Il est analytique et minutieux, avec expertise en systèmes backend et bases de données. Ton professionnel mais accessible."`}
/>

### Définition JSON Schema

<Callout type="info" title="Standard de l'Industrie">
JSON Schema est une spécification formelle pour décrire la structure JSON. Elle est supportée par de nombreuses bibliothèques de validation et outils API.
</Callout>

JSON Schema fournit des contraintes comme les valeurs min/max, champs requis et patterns regex :

```
Extrais les données selon ce JSON Schema :

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

Livre : "1984 de George Orwell (1949) - Un chef-d'œuvre dystopique. 
Genres : Science-Fiction, Fiction Politique. Noté 4.8/5"
```

## Gestion des Tableaux

Les tableaux nécessitent une attention particulière. Spécifiez si vous avez besoin d'un nombre fixe d'éléments ou d'une liste de longueur variable.

### Tableaux de Longueur Fixe

```
Extrais exactement 3 points clés en JSON :

{
  "points_cles": [
    "string (premier point)",
    "string (deuxième point)", 
    "string (troisième point)"
  ]
}

Article : [texte de l'article]
```

### Tableaux de Longueur Variable

```
Extrais toutes les personnes mentionnées en JSON :

{
  "personnes": [
    {
      "nom": "string",
      "role": "string ou null si non mentionné"
    }
  ],
  "compte": number
}

Si aucune personne n'est mentionnée, retourne un tableau vide.

Texte : [texte]
```

## Valeurs Enum et Contraintes

Les enums restreignent les valeurs à un ensemble prédéfini. C'est crucial pour les tâches de classification.

### À Faire et À Éviter : Valeurs Enum

<Compare 
  before={{ label: "❌ À Éviter : Catégories ouvertes", content: "Classe ce texte dans une catégorie.\n\n{\n  \"categorie\": \"string\"\n}" }}
  after={{ label: "✓ À Faire : Restreindre aux valeurs valides", content: "Classe ce texte. La catégorie DOIT être exactement une de :\n- \"technique\"\n- \"business\"\n- \"creatif\"\n- \"personnel\"\n\n{\n  \"categorie\": \"une des valeurs ci-dessus\"\n}" }}
/>

### Enums de Chaînes

```
Classe ce texte. La catégorie DOIT être une de ces valeurs exactes :
- "technique"
- "business" 
- "creatif"
- "personnel"

Retourne du JSON :
{
  "texte": "texte original (tronqué à 50 car)",
  "categorie": "une des valeurs enum ci-dessus",
  "confiance": nombre entre 0 et 1
}

Texte : [texte à classer]
```

## Gestion des Données Manquantes

Le texte du monde réel manque souvent certaines informations. Définissez comment le modèle doit gérer les données manquantes.

### À Faire et À Éviter : Information Manquante

<Compare 
  before={{ label: "❌ À Éviter : Laisser l'IA deviner", content: "Extrais tous les détails de l'entreprise en JSON :\n{\n  \"chiffre_affaires\": number,\n  \"employes\": number\n}" }}
  after={{ label: "✓ À Faire : Autoriser explicitement null", content: "Extrais les détails de l'entreprise. Utilise null pour tout champ NON explicitement mentionné. N'INVENTE PAS de valeurs.\n\n{\n  \"chiffre_affaires\": \"number ou null\",\n  \"employes\": \"number ou null\"\n}" }}
/>

### Valeurs Null

```
Extrais les informations. Utilise null pour tout champ qui ne peut pas 
être déterminé du texte. N'INVENTE PAS d'information.

{
  "entreprise": "string ou null",
  "chiffre_affaires": "number ou null",
  "employes": "number ou null",
  "fondee": "number (année) ou null",
  "siege": "string ou null"
}

Texte : "Apple, dont le siège est à Cupertino, a été fondée en 1976."
```

### Valeurs par Défaut

```
Extrais les paramètres avec ces défauts si non spécifiés :

{
  "theme": "clair" (défaut) | "sombre",
  "langue": "fr" (défaut) | autre code ISO,
  "notifications": true (défaut) | false,
  "taillePolicе": 14 (défaut) | number
}

Préférences utilisateur : "Je veux le mode sombre et du texte plus grand (18px)"
```

## Réponses Multi-Objets

### Tableau d'Objets

```
Parse cette liste en tableau JSON :

[
  {
    "tache": "string",
    "priorite": "haute" | "moyenne" | "basse",
    "echeance": "chaîne date ISO ou null"
  }
]

Liste de tâches :
- Finir le rapport (urgent, pour demain)
- Appeler le dentiste (priorité basse)
- Réviser PR #123 (moyen, pour vendredi)
```

## YAML pour Génération de Configuration

### Docker Compose

```
Génère un docker-compose.yml pour :
- App Node.js sur port 3000
- Base de données PostgreSQL
- Cache Redis
- Proxy inverse Nginx

Inclure :
- Health checks
- Persistance des volumes
- Variables d'environnement depuis fichier .env
- Isolation réseau
```

### Manifestes Kubernetes

```
Génère un YAML de déploiement Kubernetes :

Deployment :
- Nom : api-server
- Image : myapp:v1.2.3
- Replicas : 3
- Ressources : 256Mi mémoire, 250m CPU (requests)
- Health checks : endpoint /health
- Environment depuis ConfigMap : api-config

Générer aussi le Service correspondant (ClusterIP, port 8080)
```

## Validation et Gestion d'Erreurs

### Prompt d'Auto-Validation

```
Extrais les données en JSON, puis valide ta sortie.

Schéma :
{
  "email": "format email valide",
  "telephone": "format E.164 (+33123456789)",
  "date": "format ISO 8601 (AAAA-MM-JJ)"
}

Après avoir généré le JSON, vérifie :
1. L'email contient @ et domaine valide
2. Le téléphone commence par + et contient uniquement des chiffres
3. La date est valide et analysable

Si la validation échoue, corrige les problèmes avant de répondre.
```

### Format de Réponse d'Erreur

```
Tente d'extraire les données. Si l'extraction échoue, retourne le format d'erreur :

Format succès :
{
  "succes": true,
  "donnees": { ... données extraites ... }
}

Format erreur :
{
  "succes": false,
  "erreur": "description de ce qui n'a pas marché",
  "donnees_partielles": { ... données qui ont pu être extraites ... }
}
```

## JSON vs YAML : Quand Utiliser Lequel

<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">Utiliser JSON Quand</div>
    <div className="text-sm space-y-1">
      <p className="m-0!">Parsing programmatique nécessaire</p>
      <p className="m-0!">Réponses API</p>
      <p className="m-0!">Exigences de types stricts</p>
      <p className="m-0!">Intégration JavaScript/Web</p>
      <p className="m-0!">Représentation compacte</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">Utiliser YAML Quand</div>
    <div className="text-sm space-y-1">
      <p className="m-0!">Lisibilité humaine importante</p>
      <p className="m-0!">Fichiers de configuration</p>
      <p className="m-0!">Commentaires nécessaires</p>
      <p className="m-0!">DevOps/Infrastructure</p>
      <p className="m-0!">Structures profondément imbriquées</p>
    </div>
  </div>
</div>

## Pièges Courants

<Callout type="warning" title="Déboguer Ceux-ci en Premier">
Ces trois problèmes causent la plupart des échecs de parsing JSON.
</Callout>

### 1. Blocs de Code Markdown

**Problème :** Le modèle enveloppe le JSON dans des blocs ```json

**Solution :** 
```
Retourne UNIQUEMENT l'objet JSON. Ne pas envelopper dans des blocs de code markdown.
N'inclus pas de marqueurs ```json ou ```.
```

### 2. Virgules Finales

**Problème :** JSON invalide à cause de virgules finales

**Solution :**
```
Assure une syntaxe JSON valide. Pas de virgules finales après le dernier 
élément dans les tableaux ou objets.
```

### 3. Chaînes Non Échappées

**Problème :** Guillemets ou caractères spéciaux cassent le JSON

**Solution :**
```
Échappe correctement les caractères spéciaux dans les chaînes :
- \" pour les guillemets
- \\ pour les backslashes
- \n pour les retours à la ligne
```

## Résumé

<Callout type="tip" title="Techniques Clés">
Définissez les schémas explicitement avec des interfaces TypeScript ou JSON Schema. Spécifiez les types et contraintes, gérez les nulls et défauts, demandez l'auto-validation, et choisissez le bon format pour votre cas d'usage.
</Callout>

<Quiz 
  question="Quand devriez-vous préférer YAML plutôt que JSON pour les sorties d'IA ?"
  options={[
    "Lors de la construction d'APIs REST",
    "Quand la sortie doit être lisible par l'homme et peut inclure des commentaires",
    "Lors du travail avec des applications JavaScript",
    "Quand vous avez besoin de la représentation la plus compacte"
  ]}
  correctIndex={1}
  explanation="YAML est préféré quand la lisibilité humaine compte, comme les fichiers de configuration, manifestes DevOps et documentation. Il supporte aussi les commentaires, contrairement à JSON."
/>

Ceci complète la Partie II sur les techniques. Dans la Partie III, nous explorerons les applications pratiques dans différents domaines.
