Accueil / Articles / Création de prompts LLM prêts pour la production : un cadre à sept couches

Création de prompts LLM prêts pour la production : un cadre à sept couches

Apprenez un cadre structuré, inspiré des API, composé de sept couches de prompts — instructions, contexte, contraintes, etc. — pour créer des systèmes LLM fiables et adaptés à la production.

3297 mots

21 jours d’ingénierie avancée des prompts

Une progression pratique qui vous guide des bases des prompts à la conception de systèmes d’IA complets.

La plupart des gens pensent qu’un prompt n’est rien de plus qu’une question que l’on adresse à un LLM.

Par exemple :

Classify this customer support ticket.

Et ça fonctionne.

Jusqu’à ce que ça ne fonctionne plus.

Quelques entrées peuvent donner exactement ce que l’on espérait. Puis un cas légèrement différent arrive, et soudain le modèle :

  • choisit la mauvaise catégorie,
  • invente des détails qui n’étaient pas dans l’entrée,
  • renvoie un format que l’on n’a pas demandé,
  • écrit un paragraphe d’explication au lieu de données structurées,
  • ou se comporte de manière incohérente simplement parce que la formulation a changé.

C’est précisément ici que la différence entre un prompt testé de manière informelle et un prompt conçu pour la production devient cruciale.

Dans un système de production, un prompt n’est pas simplement une question.

Il fait partie du contrat entre votre application et le modèle.

Les développeurs savent déjà comment concevoir des API avec des limites bien définies :

Request → Validation → Business Logic → Response

Les systèmes basés sur des prompts nécessitent la même discipline :

Instructions
     ↓
Context
     ↓
Constraints
     ↓
Task
     ↓
Examples
     ↓
Output Contract
     ↓
Validation

Le reste de cet article examine chacun de ces éléments séparément, puis les assemble en un exemple fonctionnel.

1. Le problème avec « Il suffit de demander au modèle »

Imaginez une fonctionnalité alimentée par l’IA pour une plateforme de support client. Chaque ticket reçu doit être orienté vers l’un des quatre catégories :

billing
technical
account
general

Un prompt minimal pourrait ressembler à ceci :

Classify this customer support ticket:
"I was charged twice for my subscription."

Et le modèle pourrait répondre :

Billing

Cela semble correct en apparence.

Mais votre backend a généralement besoin de plus qu’une seule étiquette. Il s’attend probablement à quelque chose de structuré, comme par exemple :

{
  "category": "billing",
  "priority": "high"
}

C’est là que les choses deviennent plus complexes.

Comment la priorité est-elle réellement déterminée ?

Prenons un ticket qui se contente d’écrire :

« Je ne peux pas me connecter. »

Cela relève-t-il de la catégorie account, ou s’agit-il vraiment d’un problème technical ?

Que se passe-t-il si un client aborde à la fois un problème de facturation et un problème de connexion dans le même message ?

Que se passe-t-il si la catégorie est véritablement ambiguë ?

Quel est le comportement de secours attendu dans ce cas ?

Aucune de ces questions ne peut être répondue de manière fiable par un modèle lorsque la demande initiale ne spécifie jamais les règles.

C’est précisément pour cette raison que l’élaboration de prompts destinés à la production commence par la définition d’une spécification, et non par le perfectionnement des formulations.

2. L’anatomie d’un prompt de niveau production

Ces sections n’ont pas besoin d’apparaître littéralement sous forme de titres étiquetés à l’intérieur du texte même du prompt.

Ce qui compte, c’est que vous compreniez la fonction de chaque couche.

Examinons-les une par une.

3. Instructions système — Définir le rôle et le comportement

La première couche définit la portée des responsabilités du modèle.

Pour l’exemple du classificateur de tickets :

You are a customer support classification assistant.
Your job is to classify incoming support tickets
according to the provided category definitions.Return only information supported by the ticket.
Do not invent customer information.

Cela est bien plus utile qu’une formulation générique comme :

You are an intelligent AI assistant.

Pourquoi cette différence est-elle importante ?

Car qualifier le modèle d’« assistant IA intelligent » ne définit aucun comportement concret.

La version plus spécifique précise :

  • quelle tâche le modèle accomplit
  • dans quel domaine il opère
  • quelles informations il est autorisé à utiliser
  • quels comportements sont interdits

On peut considérer les instructions système comme le contrat de comportement pour l’interaction.

4. Contexte — Fournir au modèle ce dont il a besoin

La couche suivante fournit toutes les informations nécessaires pour effectivement accomplir la tâche.

Par exemple :

Available categories:
billing:
Questions about charges, invoices, refunds, or payments.technical:
Problems with product functionality, errors, or system behavior.account:
Login, password, profile, access, or account-management issues.general:
Questions that don't clearly belong to the above categories.

Suivi du contenu réel de la demande :

Customer ticket:
"I was charged twice for my subscription this month."

La distinction ici mérite d’être soulignée explicitement :

Instructions = What to do
Context = Information needed to do it

Si vous changez le contexte tout en laissant les instructions inchangées, le modèle doit encore être capable de traiter correctement la nouvelle entrée.

Préserver leur séparation rend également les modèles de prompts beaucoup plus faciles à maintenir dans le temps.

5. Contraintes — Indiquez au modèle où s’arrêter

Les contraintes sont l’étape où l’ambiguïté est éliminée.

Prenant l’exemple de nouveau :

Rules:
1. Select exactly one category.
2. Use only the four categories provided.
3. Do not create new categories.
4. Do not infer facts that are not present.
5. If the issue is unclear, use "general".
6. Priority must be one of: low, medium, high.
7. Return only the requested JSON.

Ces règles réduisent considérablement l’espace des réponses possibles.

Sans elles, un prompt comme :

Classify the ticket.

pourrait produire quelque chose comme :

This appears to be a billing-related issue because
the customer mentions being charged twice.

C’est une réponse tout à fait raisonnable pour un lecteur humain.

Mais votre API s’attend probablement à du JSON propre, et non à de la prose.

Ajoutez explicitement la contrainte :

Return only the requested JSON.

et le comportement attendu devient sans ambiguïté.

6. Tâche — Définir l’opération exacte

Lorsque les instructions et contraintes sont établies, il faut préciser l’opération concrète que l’on attend de la part du modèle.

Task:
1. Identify the most appropriate category.
2. Determine the priority based on the rules.
3. Provide a short reason.
4. Return the result using the specified JSON structure.

Comparez cela à une directive vague telle que :

Understand this customer issue.

Lorsqu’une tâche est formulée avec une telle précision, on peut vérifier par la suite si le modèle a réellement exécuté ce qui avait été demandé.

Imaginez un pipeline ayant cette forme :

Input
  ↓
Classify
  ↓
Determine priority
  ↓
Generate reason
  ↓
Return JSON

À ce stade, la tâche cesse d’être une supposition pour devenir quelque chose de mesurable et de testable.

7. Exemples — Montrer le comportement souhaité

Les instructions indiquent au modèle ce qu’il doit faire en mots.

Les exemples le démontrent directement.

Prenons celui-ci :

Example 1
Example 1Input:
"I was charged twice for the same subscription."Output:
{
  "category": "billing",
  "priority": "medium",
  "reason": "The customer reports a duplicate subscription charge."
}

Un deuxième exemple peut illustrer un scénario complètement différent, comme un rapport de bug technique :

Example 2Input:
"The application crashes every time I upload an image."Output:
{
  "category": "technical",
  "priority": "high",
  "reason": "The customer reports a repeatable application failure."
}

Les exemples sont particulièrement utiles lorsque le comportement souhaité est difficile à définir uniquement grâce à des règles, car ils permettent au modèle de s’attacher à un schéma concret.

Néanmoins, il y a un bémol à garder en tête.

Plus d’exemples ≠ prompts automatiquement meilleurs

En accumulant exemple après exemple, il y a des coûts réels. Cela entraîne une augmentation de :

  • La taille du prompt
  • La consommation de tokens
  • La latence
  • Des contradictions potentielles

Une stratégie plus intelligente consiste à sélectionner soigneusement un petit ensemble d’exemples.

Privilégiez les exemples qui représentent des situations significativement différentes, en particulier ceux qui sont ambigus ou relevant de cas limites.

Un trio comme :

Clear billing issue
Clear technical issue
Ambiguous issue

généralement surpasse dix exemples de facturation presque identiques empilés les uns sur les autres.

8. Format de sortie — Traitez-le comme un contrat API

Rares sont les éléments aussi importants dans un prompt de niveau production que cette couche.

Si un autre système doit interpréter ce que le modèle renvoie, vous ne pouvez pas laisser la forme de cette réponse au hasard sous forme de prose libre.

Précisez plutôt le schéma.

Par exemple :

{
  "category": "billing | technical | account | general",
  "priority": "low | medium | high",
  "reason": "string"
}

Lorsque ceci est en place, le modèle dispose d’une cible fixe à atteindre, et le code ultérieur peut s’appuyer sur un flux tel que :

LLM
 ↓
JSON
 ↓
Parser
 ↓
Schema validation
 ↓
Business logic

plutôt que quelque chose de bien plus chaotique, comme :

LLM
 ↓
Some paragraph
 ↓
Regex
 ↓
Hope it works

Cette deuxième configuration est un cauchemar à maintenir sur le long terme.

Une sortie structurée bien spécifiée établit une frontière claire entre ce que le LLM produit et ce dont votre application a réellement besoin.

9. Validation — Le modèle n’est pas votre validateur

Voici une erreur qui apparaît constamment dans les systèmes pilotés par l’IA.

Supposons que le modèle renvoie :

{
  "category": "billing",
  "priority": "urgent",
  "reason": "The customer has a billing issue."
}

D’un point de vue syntaxique, ce JSON est correct.

Le problème se trouve ici :

"urgent"

« urgent » n’a jamais fait partie des valeurs autorisées.

Il revient à votre application de détecter cette incohérence, et non au modèle.

Voici à quoi cela ressemble avec Pydantic :

from pydantic import BaseModel
from typing import Literal

class TicketClassification(BaseModel):
    category: Literal[
        "billing",
        "technical",
        "account",
        "general"
    ]
    priority: Literal[
        "low",
        "medium",
        "high"
    ]
    reason: str

Vous appellerez alors :

result = TicketClassification.model_validate(llm_response)

Et si le modèle renvoie quelque chose comme :

{
  "category": "billing",
  "priority": "urgent",
  "reason": "Duplicate charge."
}

l’étape de validation doit le rejeter immédiatement.

C’est précisément l’objectif de ce rejet.

N’acceptez jamais que la sortie du modèle passe sans vérification.

Cela nous amène à une règle à adopter chaque fois que vous concevez un système basé sur un LLM :

L’LLM génère. Votre application valide.

Le modèle peut aider dans les décisions difficiles, mais toute exigence véritablement incontournable doit figurer dans du code d’application déterministe qui l’impose directement.

10. Le prompt complet orienté production

En combinant toutes les couches, on obtient quelque chose comme ceci :

SYSTEM
You are a customer support classification assistant.
Your job is to classify incoming support tickets
according to the provided category definitions.
Return only information supported by the ticket.
Do not invent customer information.

CONTEXT
Available categories:
billing:
Charges, invoices, refunds, or payment-related issues.
technical:
Product functionality, errors, crashes, or system behavior.
account:
Login, password, profile, access, or account-management issues.
general:
Issues that do not clearly belong to another category.

Customer ticket:
{{ticket_text}}

CONSTRAINTS
1. Select exactly one category.
2. Use only the categories provided above.
3. Do not create new categories.
4. Do not infer unsupported facts.
5. If the issue is unclear, use "general".
6. Priority must be "low", "medium", or "high".
7. Return only the requested JSON.

TASK
1. Classify the ticket.
2. Determine the priority.
3. Provide a short reason.
4. Return the result in the required JSON format.

EXAMPLE
Input:
"I was charged twice for the same subscription."
Output:
{
  "category": "billing",
  "priority": "medium",
  "reason": "The customer reports a duplicate subscription charge."
}

OUTPUT FORMAT
{
  "category": "billing | technical | account | general",
  "priority": "low | medium | high",
  "reason": "string"
}

Placez ensuite cela à côté du point de départ de cet exercice :

Classify this customer support ticket.

La différence entre ces deux prompts ne réside pas vraiment dans le nombre de mots.

Ce qui a changé, c’est le degré de spécificité de chaque élément.

Chaque bloc de la version plus longue remplit une fonction précise :

  • La partie relative au système définit comment le modèle doit agir
  • La partie relative au contexte fournit les informations sur lesquelles il travaille
  • La partie relative aux contraintes énonce les règles qu’il ne peut pas enfreindre
  • La partie relative à la tâche précise exactement ce qu’il doit accomplir
  • La section des exemples montre à quoi ressemble réellement une réponse correcte
  • La section des résultats définit la forme que doit prendre la réponse
  • La section de validation détermine si cette réponse peut être considérée comme fiable
  • 11. La conception des prompts est similaire à la conception d’API

    Pour les ingénieurs logiciels, cette comparaison rend la conception de prompts en environnement de production presque immédiatement compréhensible.

    Imaginez un point de terminaison REST typique.

    On spécifierait quelque chose comme ceci :

    POST /tickets/classify
    

    Un corps de demande :

    {
      "ticket": "I was charged twice."
    }
    

    Et un corps de réponse :

    {
      "category": "billing",
      "priority": "medium",
      "reason": "Duplicate charge reported."
    }
    

    Appliquez maintenant la même logique à un prompt pour LLM.

    Le prompt correspond en fait à la logique de mise en œuvre qui se trouve derrière ce point de terminaison.

    API
     ↓
    Input
     ↓
    Prompt Template
     ↓
    LLM
     ↓
    Structured Output
     ↓
    Validation
     ↓
    API Response
    

    C’est pourquoi l’ingénierie des prompts tend de plus en plus à devenir une discipline d’ingénierie logicielle plutôt qu’un exercice de maîtrise des mots.

    Vous ne cherchez pas la formulation parfaite.

    Vous construisez une interface fiable sur un système qui se comporte de manière probabiliste.

    12. Erreurs courantes dans les prompts de production

    1. Être vague

    Analyze the ticket carefully.
    

    Qu’est-ce qui compte comme « avec soin » ici ?

    Décrivez précisément le comportement souhaité au lieu de le laisser à l’interprétation.

    2. Demander des éléments dont on n’a pas besoin

    Indiquez que votre application ne consomme que :

    {
      "category": "billing"
    }
    

    Alors ne demandez pas :

    category
    reason
    summary
    sentiment
    customer mood
    recommended response
    next action
    

    sauf si votre application utilise réellement ces champs ultérieurement.

    Chaque champ supplémentaire demandé représente un risque de dérive ou d’incohérence dans les résultats.

    3. Placer toute la logique métier directement dans le prompt

    Un exemple de cette erreur :

    If the customer has been waiting more than 48 hours,
    has contacted support three times, and is a premium customer,
    set priority to high...
    

    De telles règles appartiennent généralement au code déterministe de votre application, et non à la requête.

    Une séparation plus claire ressemblerait à ceci :

    LLM → classify issue
    
    Application → calculate priority
    

    Separer les éléments de cette manière rend généralement tout le système beaucoup plus facile à tester.

    4. Modifier les requêtes sans évaluation

    Disons que la version 1 fonctionne bien en production.

    Puis quelqu’un modifie :

    Classify the ticket.
    

    en:

    Analyze and intelligently classify the ticket.
    

    Cela semble être un simple reformulage.

    Pourtant, le comportement en production peut changer de manière significative.

    C’est précisément pour cette raison que les requêtes méritent un contrôle de version et une évaluation, la même discipline que celle appliquée au code d’application.

    5. Présumer que le modèle suivra toujours les instructions

    N’oubliez pas que les LLM sont par nature probabilistes.

    Même une requête soigneusement conçue peut encore retourner quelque chose que vous n’avez pas demandé.

    C’est pourquoi un véritable système de production a besoin de plus qu’un bon prompt — il a besoin de :

    Prompt
    +
    Structured output
    +
    Validation
    +
    Monitoring
    +
    Fallback handling
    

    Se fier uniquement à la formulation du prompt n’est pas une stratégie fiable.

    13. L’élaboration de prompts en production nécessite une évaluation

    La principale différence entre des expérimentations occasionnelles avec un LLM et le déploiement d’une fonctionnalité IA réelle réside dans la évaluation.

    Imaginez que vous disposiez de 1 000 tickets de support historiques.

    Vous pourriez en créer un ensemble de test structuré comme suit :

    200 billing
    200 technical
    200 account
    200 general
    100 ambiguous
    100 edge cases
    

    Ensuite, vous exécutez différentes versions de prompts sur cet même ensemble et comparez les résultats.

    Par exemple :

    Prompt V1    Prompt V2
    ----------------------------------------
    Category accuracy    88%         93%
    Schema failures       4%          1%
    Invalid values        3%          0.5%
    Average latency      1.8s        2.1s
    Token usage          650         820
    

    À ce stade, le travail sur les prompts cesse d’être subjectif.

    Vous ne vous demandez plus :

    "Ce prompt semble-il meilleur ?"

    Vous vous demandez plutôt :

    « Cette version obtient-elle de meilleurs résultats pour les cas qui sont vraiment importants pour notre application ? »

    C’est une question bien plus utile à se poser.

    14. Le compromis : plus d’instructions vs plus de complexité

    Aucune règle fixe ne stipule :

    « Un prompt plus long fonctionne toujours mieux. »

    Les prompts peuvent effectivement devenir trop complexes.

    Quelque chose comme :

    30 rules
    +
    20 examples
    +
    multiple exceptions
    +
    long explanations
    +
    repeated instructions
    

    peut se transformer en une charge de maintenance plutôt qu’en un atout.

    Une bonne habitude est de se demander constamment :

    Cette instruction traite-t-elle réellement d’un problème concret que j’ai observé ?

    Si la réponse est non, cette instruction ne devrait probablement pas y figurer.

    Le meilleur prompt pour un usage réel n’est pas celui qui contient le plus de contenu.

    C’est celui qui fournit le contexte adéquat, les contraintes appropriées et le comportement attendu, tout en minimisant au maximum le poids inutile.

    15. Un modèle mental pratique

    Lorsque vous vous mettez à créer une instruction, il est utile de vous poser sept questions directrices.

    1. Qui est le modèle dans ce flux de travail ?

    Instructions système

    2. Que doit savoir le modèle ?

    Contexte

    3. Que ne doit-il absolument pas faire ?

    Contraintes

    4. Quel est exactement l’objectif à atteindre ?

    Tâche

    5. Puis-je montrer le comportement attendu ?

    Exemples

    6. À quoi doit ressembler la réponse ?

    Format de sortie

    7. Comment mon application saura-t-elle que la réponse est acceptable ?

    Vérification

    Collectivement, ces sept questions forment un cadre unique.

    Cet modèle mental vaut bien plus que la mémorisation d’un seul template de prompt.

    16. L’ingénierie des prompts évolue vers la conception de systèmes

    Ce pourrait être l’idée la plus importante de toute cette discussion.

    Débutalement, travailler avec un LLM se résume généralement à une question du type :

    How can I phrase this question better?
    

    Lorsque les systèmes deviennent plus complexes, cette question se transforme complètement :

    What does the model need to know?
    What should it be allowed to do?
    What should it return?
    How do I validate it?
    What happens when it fails?
    How do I evaluate changes?
    

    Il ne s’agit plus de questions de formulation — ce sont des questions d’ingénierie logicielle.

    C’est précisément pourquoi l’ingénierie des prompts de niveau production a moins à voir avec la découverte d’une formule magique, et beaucoup plus avec la conception d’une interaction fiable entre votre application et un modèle qui se comporte de manière probabiliste.

    Points clés

    Quelques idées fondamentales méritent d’être retenues de tout cela :

    1. Un prompt prêt à la production est plus qu’une simple question.

    Il précise le comportement attendu, fournit du contexte, définit des limites, indique la tâche à accomplir, propose des exemples et décrit l’aspect que doit avoir la réponse.

    2. Séparez les instructions des données.

    3. Des contraintes claires réduisent les suppositions.

    N’attendez pas que le modèle décide ce qu’il faut faire en cas de données manquantes, ambiguës ou mal formatées.

    4. Les exemples servent à illustrer le comportement.

    Utilisez-les de manière intentionnelle, en particulier pour les cas limites complexes.

    5. Une sortie structurée doit être traitée comme un contrat API.

    Dès qu’un service intermédiaire lit la réponse du modèle, précisez exactement quelle forme cette réponse doit avoir.

    6. Ne laissez pas le prompt servir de seul mécanisme de vérification de sécurité.

    La véritable validation doit avoir lieu dans votre application, grâce à des contrôles de schéma et à des règles métier déterministes.

    7. Traitez les prompts comme du code qui doit être évalué.

    Versionnez-les, exécutez-les sur des cas de test représentatifs, et suivez leurs performances.

    8. Un prompt plus long n’est pas nécessairement meilleur.

    Chaque ligne que vous ajoutez doit justifier sa présence.

    Conclusion

    Créer un prompt de niveau production ne consiste pas à forcer un LLM à paraître plus intelligent.

    Cela consiste à rendre l’échange plus prévisible, plus transparent et plus facile à intégrer dans un système réel.

    Le changement se manifeste généralement de la manière suivante :

    Simple question
          ↓
    Structured instructions
          ↓
    Clear context
          ↓
    Explicit constraints
          ↓
    Defined task
          ↓
    Useful examples
          ↓
    Structured output
          ↓
    Application validation
          ↓
    Evaluation + monitoring
    

    Lorsque cette façon de penser s’installe, l’ingénierie des prompts cesse d’apparaître comme une méthode de trial et error pour la création de textes et commence plutôt à ressembler à la conception d’un contrat API pour un composant qui se comporte de manière probabiliste.

    Ce changement est extrêmement important une fois que l’on passe des démos pour commencer à développer des systèmes destinés à fonctionner en production.

    Lectures complémentaires

  • LangChain vs LlamaIndex : Choisir le bon framework LLM — Une comparaison de LangChain et LlamaIndex portant sur l’architecture, RAG, les agents et les performances afin de vous aider à sélectionner le framework idéal pour votre projet d’IA.