watch·ia
AccueilActusTutosGlossaireCette semaineTendancesSources
/
ACTUS
1 aoûtUn juge américain valide l'interdiction des applications 'nudify' au Minnesota malgré xAI·1 aoûtReddit envisage de rompre son accord avec Google pour ses AI Overviews·31 juil.OpenAI et Google renforcent les alertes sur les risques des outils IA autonomes·31 juil.Reddit maintient un procès DMCA contre un scraper malgré l'échec de Google·31 juil.L'Inde dépasse 345 millions de dollars de revenus applicatifs au T2 2026·31 juil.Anthropic révèle que son IA Claude a accédé à trois réseaux sans autorisation·31 juil.Google Earth retire en un jour un outil d'édition d'images par IA après des détournements·31 juil.Google Earth ajoute un générateur d'images IA avec filigrane SynthID·31 juil.Snapchat modifie ses algorithmes pour limiter les récompenses aux contenus Spotlight 100 % générés par IA·31 juil.Les majors musicales veulent exclure les morceaux 100 % générés par IA des classements·1 aoûtUn juge américain valide l'interdiction des applications 'nudify' au Minnesota malgré xAI·1 aoûtReddit envisage de rompre son accord avec Google pour ses AI Overviews·31 juil.OpenAI et Google renforcent les alertes sur les risques des outils IA autonomes·31 juil.Reddit maintient un procès DMCA contre un scraper malgré l'échec de Google·31 juil.L'Inde dépasse 345 millions de dollars de revenus applicatifs au T2 2026·31 juil.Anthropic révèle que son IA Claude a accédé à trois réseaux sans autorisation·31 juil.Google Earth retire en un jour un outil d'édition d'images par IA après des détournements·31 juil.Google Earth ajoute un générateur d'images IA avec filigrane SynthID·31 juil.Snapchat modifie ses algorithmes pour limiter les récompenses aux contenus Spotlight 100 % générés par IA·31 juil.Les majors musicales veulent exclure les morceaux 100 % générés par IA des classements·1 aoûtUn juge américain valide l'interdiction des applications 'nudify' au Minnesota malgré xAI·1 aoûtReddit envisage de rompre son accord avec Google pour ses AI Overviews·31 juil.OpenAI et Google renforcent les alertes sur les risques des outils IA autonomes·31 juil.Reddit maintient un procès DMCA contre un scraper malgré l'échec de Google·31 juil.L'Inde dépasse 345 millions de dollars de revenus applicatifs au T2 2026·31 juil.Anthropic révèle que son IA Claude a accédé à trois réseaux sans autorisation·31 juil.Google Earth retire en un jour un outil d'édition d'images par IA après des détournements·31 juil.Google Earth ajoute un générateur d'images IA avec filigrane SynthID·31 juil.Snapchat modifie ses algorithmes pour limiter les récompenses aux contenus Spotlight 100 % générés par IA·31 juil.Les majors musicales veulent exclure les morceaux 100 % générés par IA des classements·1 aoûtUn juge américain valide l'interdiction des applications 'nudify' au Minnesota malgré xAI·1 aoûtReddit envisage de rompre son accord avec Google pour ses AI Overviews·31 juil.OpenAI et Google renforcent les alertes sur les risques des outils IA autonomes·31 juil.Reddit maintient un procès DMCA contre un scraper malgré l'échec de Google·31 juil.L'Inde dépasse 345 millions de dollars de revenus applicatifs au T2 2026·31 juil.Anthropic révèle que son IA Claude a accédé à trois réseaux sans autorisation·31 juil.Google Earth retire en un jour un outil d'édition d'images par IA après des détournements·31 juil.Google Earth ajoute un générateur d'images IA avec filigrane SynthID·31 juil.Snapchat modifie ses algorithmes pour limiter les récompenses aux contenus Spotlight 100 % générés par IA·31 juil.Les majors musicales veulent exclure les morceaux 100 % générés par IA des classements·

Obtenir du JSON fiable d'un LLM : structured outputs et validation

vendredi 10 juillet 202613:353 min de lecture
L'essentiel — 3 points
  • 01Active le mode JSON de l'API (response_format) plutôt que d'espérer un JSON propre dans du texte
  • 02Valide toujours la sortie contre un schéma : un JSON syntaxiquement valide peut avoir de mauvais champs
  • 03Prévois un retry : en cas de sortie invalide, renvoie l'erreur au modèle pour qu'il se corrige
API

Tu extrais des données d'un texte avec un LLM et tu galères à parser sa réponse ? Un « Voici le JSON : » de trop, un bloc de code markdown autour, des virgules superflues, du français qui déborde… À la fin de ce tuto, tu auras une extraction JSON fiable : mode structuré côté API, validation par schéma, et retry automatique. Exemples en TypeScript, transposables ailleurs.

Étape 1 — Activer le mode JSON de l'API

La plupart des fournisseurs proposent un response_format qui garantit un objet JSON syntaxiquement valide. Exemple avec l'API Mistral :

const res = await fetch("https://api.mistral.ai/v1/chat/completions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.MISTRAL_API_KEY}`,
  },
  body: JSON.stringify({
    model: "mistral-small-latest",
    messages: [
      { role: "system", content: "Tu extrais des données. Réponds en JSON strict." },
      { role: "user", content: `Extrais nom, email et budget de : "${texte}"` },
    ],
    response_format: { type: "json_object" },
  }),
});
const data = await res.json();
const raw = data.choices[0].message.content; // déjà un objet JSON valide en string

Avec ce mode, le JSON n'est plus entouré d'un bloc de code parasite. Chez les fournisseurs qui l'entourent quand même, garde une sécurité :

function stripFence(text: string): string {
  const t = text.trim();
  return t.startsWith("```")
    ? t.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim()
    : t;
}

Étape 2 — Valider contre un schéma

Un JSON valide n'est pas un JSON correct : le modèle peut renvoyer budget: "beaucoup" au lieu d'un nombre. Valide avec un schéma, ici Zod :

import { z } from "zod";

const Lead = z.object({
  nom: z.string().min(1),
  email: z.string().email(),
  budget: z.number().nullable(),
});

const parsed = Lead.safeParse(JSON.parse(stripFence(raw)));
if (parsed.success) {
  console.log(parsed.data); // typé et garanti conforme
}

safeParse ne jette pas : il renvoie success: false et les erreurs, ce qui te laisse décider quoi faire.

Étape 3 — Retry avec le message d'erreur

Quand la validation échoue, la meilleure correction, c'est de renvoyer l'erreur au modèle :

async function extractLead(texte: string, tries = 2): Promise<z.infer<typeof Lead> | null> {
  let feedback = "";
  for (let i = 0; i < tries; i++) {
    const raw = await callModel(texte, feedback); // reprend l'appel de l'étape 1
    const parsed = Lead.safeParse(JSON.parse(stripFence(raw)));
    if (parsed.success) return parsed.data;
    feedback = `Ta réponse précédente était invalide : ${parsed.error.message}. Corrige et renvoie un JSON conforme.`;
  }
  return null;
}

Deux tentatives suffisent dans l'immense majorité des cas.

Adapter à ton cas

  • Extraction en masse : mets temperature: 0 pour des sorties stables et reproductibles.
  • Schéma complexe : décris le format attendu dans le prompt système en plus du response_format — le modèle suit mieux quand il « voit » la structure.
  • Autre fournisseur : OpenAI propose des structured outputs qui garantissent la conformité au schéma directement (response_format avec un JSON Schema). Claude n'a pas de mode JSON natif : demande le JSON dans le prompt et applique le stripFence + validation ci-dessus.

En cas de souci

  • JSON.parse échoue : c'est presque toujours un bloc markdown ou du texte avant/après. Applique stripFence, et si besoin extrais du premier { au dernier }.
  • Champs corrects mais valeurs fantaisistes : baisse la température et précise dans le prompt « n'invente pas : mets null si l'info est absente ».
  • Le retry boucle sans converger : ton schéma est peut-être trop strict pour ce que contient le texte. Assouplis (champs optionnels) plutôt que de forcer.
  • Coût qui grimpe : un JSON long consomme des tokens. Ne demande que les champs utiles, et évite de renvoyer tout le texte source dans la réponse.
Réagir :
Partager —XLinkedIn