Abonnement à ma liste de contacts

Etoiles inactivesEtoiles inactivesEtoiles inactivesEtoiles inactivesEtoiles inactives
 

Lorsque l'on développe des applications industrielles ou des agents autonomes basés sur des LLM, le prompt en texte libre atteint rapidement ses limites : hallucinations, dérive du format de sortie, et difficulté de maintenance. Structurer ses prompts en JSON change radicalement la donne.

1. Pourquoi utiliser des prompts en JSON ?

Un prompt structuré en JSON apporte des bénéfices fondamentaux pour l'ingénierie logicielle :

  • Structure claire : Facile à parser, à versionner via Git, et à tester unitairement.
  • Séparation des responsabilités : Délimitation stricte entre les instructions, le contexte, les données dynamiques et les contraintes.
  • Réutilisabilité : Utilisation de templates et d'injection de variables propres.
  • Réduction de l'ambiguïté : Le format tabulaire ou hiérarchique aide le modèle à structurer sa propre attention.
  • Interopérabilité API : Alignement naturel avec les charges utiles (payloads) des API modernes (OpenAI, Anthropic, LangChain, etc.).
👉 Le JSON n'a rien de « magique » pour le LLM en soi, mais il contraint la sémantique, réduit drastiquement les erreurs humaines d'écriture et stabilise les réponses en production.

2. Principe Fondamental : Réduire l'Espace de Liberté

Un LLM « devine » la suite logique tant qu'il dispose de degrés de liberté. Pour obtenir un comportement déterministe, l'objectif est de verrouiller l'espace des possibles à travers 5 axes majeurs :

  1. Un rôle strict et non narratif : Éviter les adjectifs vagues et spécifier un périmètre technique précis.
  2. Des instructions procédurales : Découper la tâche en étapes algorithmiques claires.
  3. Des contraintes négatives explicites : Définir clairement ce que le modèle ne doit pas faire.
  4. Un contrat de sortie formel : Imposer un schéma de type strict (JSON-first).
  5. Un mécanisme d'auto-contrôle (Self-check) : Demander au modèle de valider sa propre sortie avant de la rendre.

3. Structure de Base Recommandée

Voici un modèle générique, robuste et extensible :

{
   "role": {
   "persona": "...",
   "scope": [...]
},
   "task": {
      "objective": "...",
      "context": "..."
    },
"instructions": [
   { 
"step": 1, "action": "...", "details": "..."
} ], "input": {}, "constraints": { "must": [], "must_not": [] }, "output_contract": { "type": "json", "schema": {} } }

4. Bonnes Pratiques Opérationnelles

4.1 Séparer instructions et données

❌ Mauvais : Mélanger la consigne et le contenu directement dans une chaîne de caractères.

✅ Bon : Isoler le corps du texte dans un objet input dédié.

"instructions": ["Résumer en 3 lignes"],
"input": {
   "text": "Le garbage collector de Java fonctionne..."
}

4.2 Verrouiller le contrat de sortie (JSON-first)

Pour s'assurer que la sortie est directement exploitable par votre code aval, spécifiez un schéma de type précis et interdisez les propriétés superflues :

"output_contract": {
   "type": "json",
   "schema": {
      "type": "object",
      "required": ["result", "confidence"],
      "properties": {
         "result": { "type": "string" },
         "confidence": { "type": "number", "minimum": 0, "maximum": 1 }
      },
   "additionalProperties": false
   }
}

L'attribut "additionalProperties": false est crucial si vous utilisez des validateurs de schémas (comme ajv en Node.js) pour rejeter les hallucinations de clés.

4.3 Privilégier les contraintes négatives strictes (must_not)

Les LLM réagissent beaucoup mieux aux interdictions explicites qu'aux recommandations vagues de type « évitez de... ».

"constraints": {
   "must_not": [
      "Ajouter du contexte non demandé",
      "Expliquer les bases conceptuelles",
      "Utiliser des exemples fictifs"
   ]
}

5. Exemple Avancé : Code Reviewer ultra-précis

Voici un exemple complet intégrant l'ensemble de ces patterns pour une tâche de revue de code automatisée :

{
   "role": {
      "persona": "senior_code_reviewer",
      "scope": ["python", "production_code"],
      "exclusions": ["style_guide_basics", "tutorial"]
},
"task": {
"objective": "Identifier les problèmes critiques dans le code fourni"
},
"instructions": [
      { "step": 1, "action": "scan", "details": "Lire l'intégralité du code" },
      { "step": 2, "action": "detect", "details": "Identifier bugs, failles de sécurité, anti-patterns" },
      { "step": 3, "action": "classify", "details": "Classer chaque anomalie par sévérité" },
      { "step": 4, "action": "self_check", "details": "Vérifier la conformité stricte au schéma de sortie" }
],
"input": {
      "language": "python",
      "code": "def validate_email(email):\n    return '@' in email"
},
"constraints": {
      "must_not": [
            "Corriger le code à la place du développeur",
            "Ajouter des suggestions hors scope"
      ]
},
"output_contract": {
      "type": "json",
      "schema": {
            "issues": {
                  "type": "array",
                  "items": {
                        "type": "object",
                        "required": ["type", "severity", "description"],
                        "properties": {
                              "type": { "enum": ["bug", "security", "performance"] },
                              "severity": { "enum": ["low", "medium", "high", "critical"] },
                              "description": { "type": "string" }
                        },
                        "additionalProperties": false
                      }
                  }
            }
      }
}

6. Attention : JSON ≠ Prompt API natif

Attention aux pièges d'intégration : Même si votre prompt est rédigé en JSON, l'API d'un fournisseur (comme OpenAI ou Anthropic) ne l'interprète pas magiquement comme un objet structuré natif si vous l'envoyez en vrac dans une chaîne de caractères unique.

Deux options s'offrent à vous :

  • Option A (Le texte brut) : Vous passez le JSON stringifié au sein d'une consigne textuelle globale demandant au modèle de s'y conformer.
  • Option B (Le mapping API - Recommandé) : Vous mapmez les blocs logiques de votre JSON directement dans les messages système et utilisateur de l'API (ex: system pour le rôle et les contraintes, user pour l'input et le contrat de sortie).

Considérer vos prompts non plus comme de la prose littéraire, mais comme des interfaces logicielles strictes, transforme radicalement la fiabilité de vos intégrations IA. Moins d'ambiguïté, des schémas validables, et une maintenabilité accrue : voilà la clé d'un passage à l'échelle réussi en production.

Article généré et structuré à partir des réflexions sur l'ingénierie des prompts orientée production, écrit par mes soins, recorrigé par IA.

Vous retrouverez ici tous mes articles explicatifs de mes concepts, mes résultats d'analyses techniques m'ayant permi d'aboutir à un fonctionnement de mes applicatifs très fonctionnel

Rapport sondage marche

Voici le rapport statistique du sondage (auquel vous pouvez toujours répondre) que j'ai lancé sur le sujet