Arrêtez d'utiliser des "Chatbots" pour formater du JSON : L'avènement des SLMs spécialisés
DEV Community

Arrêtez d'utiliser des "Chatbots" pour formater du JSON : L'avènement des SLMs spécialisés

Après avoir sécurisé nos agents avec du Human-in-the-Loop la semaine dernière, il reste un ennemi intime du développeur IA : le parsing.

Si vous avez déjà mis un LLM en production, vous la connaissez. L'angoisse de la "ligne 42". Vous avez passé des heures à peaufiner votre prompt : "Tu dois absolument répondre au format JSON strict. N'ajoute pas de texte avant ou après." En dev, tout marche à merveille. Vous déployez.

Le lendemain, votre serveur Node.js crashe avec cette insulte suprême :

SyntaxError: Unexpected token 'V', "Voici votr"... is not valid JSON

Parce que le modèle, dans son infinie politesse, a décidé de commencer sa réponse par "Voici votre objet JSON :". C'est le problème fondamental des modèles conversationnels (comme Llama 3 ou ChatGPT) : ils sont entraînés pour discuter, pas pour être des machines déterministes. Utiliser un modèle de chat pour extraire des variables, c'est utiliser un poète pour faire de la comptabilité.

La solution ne réside pas dans des prompts plus agressifs. La solution, ce sont les modèles spécialisés comme FunctionGemma.

Les rustines habituelles (et pourquoi elles craquent)

Avant d'arriver à la vraie solution, l'industrie a bricolé des rustines :

  • Le JSON Mode de l'API : On force l'API (OpenAI, Ollama) à n'accepter que du JSON. Pratique, mais le modèle "veut" toujours discuter et peut halluciner ses propres clés.
  • Le "Prefill" ( { ) : On pré-remplit la réponse de l'assistant avec une accolade ouvrante pour le forcer à démarrer un objet.
  • Le XML : On supplie le modèle de cracher du XML entre des balises <output> parce qu'il a avalé tellement de code HTML à l'entraînement qu'il y est plus obéissant.
  • L'intercepteur JS (L'extracteur) : On laisse le LLM bavarder ("Voici le JSON :"), mais on code une fonction JavaScript qui vient découper la chaîne (du premier { au dernier }) avec un try/catch brutal avant d'appeler JSON.parse() (J'ai documenté ce cas pratique dans cet article).

Toutes ces astuces relèvent du "Prompt Engineering". C'est de la prière, pas de l'ingénierie.

Le standard moderne : Le "Structured Outputs" (Décodage Contraint)

Aujourd'hui, l'industrie a enfin trouvé une solution native. Les grands fournisseurs (OpenAI, Anthropic) et les moteurs locaux (Ollama) supportent ce qu'on appelle le Décodage Contraint (Structured Outputs).

Au lieu de supplier le modèle, vous lui passez un schéma strict (ex: Zod). Le moteur d'inférence va alors bloquer mathématiquement tous les mots (tokens) qui ne respectent pas ce schéma lors de la génération. S'il doit ouvrir un objet, la probabilité du token { est forcée à 100%. Le crash JSON devient littéralement impossible.

Le piège ? Si vous forcez un énorme modèle conversationnel (comme Llama 3 70B) à respecter une grammaire JSON complexe, toute son "attention" (calcul) est absorbée par le respect de la structure. Résultat : le JSON est valide, mais le modèle se trompe sur l'extraction des données. En le forçant à faire du JSON, vous le rendez "bête". C'est là qu'intervient la véritable architecture SOTA (State of the Art).

La fin du bricolage : Les SLMs spécialisés

L'industrie réalise enfin que nous n'avons pas besoin d'un modèle omniscient de 70 milliards de paramètres (qui coûte une fortune en inférence) pour lire une facture et extraire un "Montant" et une "Date".

C'est là qu'entrent en jeu les SLM (Small Language Models) entraînés spécifiquement pour le Tool Calling et le formatage JSON. Prenez FunctionGemma (par Google) ou Hermes 2 Pro. Si vous leur dites "Bonjour", ils ne vous répondront pas "Salut, comment puis-je vous aider ?". Ils crasheront, ou généreront un JSON vide. Et c'est exactement ce qu'on leur demande.

Leur réseau neuronal a été "fine-tuné" massivement sur des paires de :

[Signature de Fonction] + [Texte utilisateur] -> [Paramètres JSON stricts]

Implémentation TypeScript : Zod, Vercel AI SDK et FunctionGemma

La vraie puissance se révèle quand on couple ces modèles spécialisés avec une validation forte côté code. Dans un environnement TypeScript, on ne fait plus confiance au texte brut. On utilise le Vercel AI SDK en mode generateObject, couplé à Zod (pour le typage mathématique) et on route vers notre modèle local spécialisé via Ollama.

import { generateObject } from 'ai';
import { z } from 'zod';
import { createOpenAI } from '@ai-sdk/openai';

// Astuce SOTA : On utilise le provider OpenAI pour cibler l'API locale d'Ollama
const ollama = createOpenAI({
  baseURL: 'http://127.0.0.1:11434/v1',
  apiKey: 'ollama'
});

// 1. Le bouclier mathématique (Zod)
const InvoiceSchema = z.object({
  totalAmount: z.number().describe("Le montant TTC de la facture"),
  vendorName: z.string(),
  isPaid: z.boolean()
});

// 2. L'appel au "Spécialiste" local
const { object } = await generateObject({
  model: ollama('functiongemma'), // Le modèle dédié aux fonctions
  schema: InvoiceSchema,
  prompt: "Texte brut de la facture scannée de chez AWS pour 145.20$, payée hier."
});

// À ce stade, 'object' est 100% typé et garanti sans hallucinations de texte.
console.log(object.totalAmount); // 145.20

L'impact réel sur votre architecture

  • La vitesse (Latence) : FunctionGemma pèse à peine quelques Gigaoctets. Il s'exécute instantanément sur un petit CPU de serveur, là où un Llama 3 70B mettrait des secondes à démarrer.
  • Le coût : Zéro. L'extraction de données tourne en local (Ollama). Vous ne payez plus de tokens API à chaque fois que vous voulez parser un document.
  • Le déterminisme : Le modèle ne fera jamais de bavardage. Il crache du JSON pur, validé instantanément par Zod.

En ingénierie IA, l'avenir n'est pas au modèle unique omniscient. L'avenir est aux "Swarm d'Agents" (des essaims d'agents) où un modèle conversationnel délègue les tâches de formatage à des petits modèles locaux ultra-spécialisés.

Cette série d'articles est directement tirée des architectures que nous construisons dans la plateforme AI Quest. Mon objectif ici est de vous partager gratuitement la logique d'ingénierie derrière ces systèmes, pour vous aider à passer de Développeur Web à AI Engineer. (L'implémentation de ces "Swarm d'Agents" spécialisés et de Zod est d'ailleurs explorée en détail dans nos Side Quests).

🍁 Fièrement codé depuis la Beauce (Québec).

Quel est votre pire souvenir de crash en production à cause d'un JSON "imaginatif" généré par une IA ? Avez-vous déjà testé des modèles dédiés au Tool Calling comme Hermes ou FunctionGemma ? 👇

Comments

No comments yet. Start the discussion.