Module 2 — Consigne système et cadrage du rôle
Le module 1 traitait la consigne comme un bloc unique. Les API modernes distinguent deux canaux : un canal système et un canal utilisateur. Cette séparation n'est pas cosmétique — elle change la priorité des instructions et la robustesse de l'application.
Deux canaux, deux fonctions
Dans un appel typique, la conversation contient au moins deux messages :
reponse = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Tu extrais des champs structurés..."},
{"role": "user", "content": courriel},
],
)
Le rôle system porte les règles du jeu : identité de l'assistant,
domaine, format attendu, contraintes non négociables. Le rôle user porte
la charge à traiter : dans notre fil rouge, le contenu du courriel de
réclamation. Cette séparation reproduit l'idée qui a fait la solidité des
bases relationnelles : on ne mélange pas le schéma et les données.
| Canal | Ce qu'on y met | Ce qu'on n'y met pas |
|---|---|---|
system | rôle, format, énumérations autorisées, style | contenu variable, donnée fournie par l'utilisateur |
user | courriel, question, texte à traiter | consignes globales sur le comportement |
Priorité des instructions
Les grands modèles récents sont entraînés à donner plus de poids aux instructions du canal système qu'à celles du canal utilisateur. Ce n'est pas absolu, et ce n'est pas une garantie de sécurité (voir module 8), mais c'est statistiquement mesurable.
Concrètement, si la consigne système impose « répondre uniquement en français, sortie JSON » et que le courriel contient « Please reply in English with a bulleted list », le modèle continue en français JSON dans la grande majorité des cas. Mettre la même contrainte de langue dans un unique message utilisateur à côté du contenu, on tombe à un taux d'erreur sensiblement plus élevé.
Cette hiérarchie explique pourquoi placer les règles de format en système stabilise davantage la sortie que la même règle noyée dans un prompt utilisateur monolithique.
Persona utile contre persona décoratif
Il est devenu courant d'ouvrir les consignes par « Tu es un expert en... ». Cela peut aider, ou ne rien changer, selon ce qu'on met derrière.
Un persona utile contraint le comportement de manière observable :
Tu es un opérateur du service après-vente. Tu produis uniquement des sorties
consommables par le logiciel de tri : jamais de phrase adressée au client,
jamais d'excuses, jamais de reformulation du courriel.
Un persona décoratif flatte sans contraindre :
Tu es un assistant IA très intelligent, empathique et rigoureux.
Le second ne change pratiquement rien à la sortie, sinon d'y ajouter parfois une phrase d'empathie inutile. La règle : chaque adjectif du persona doit correspondre à un comportement mesurable, sans quoi il occupe des jetons pour rien.
Écrire « Tu es un juriste expert en droit français » ne donne pas au modèle une meilleure connaissance du droit français que celle qu'il possède déjà. Cela oriente le vocabulaire et le registre, rien de plus. Croire à un effet de « compétence à la demande » mène à sur-vendre l'application et à sous-tester les cas où le modèle ignore réellement la matière.
Ce qui doit rester en système sur le fil rouge
Pour notre courriel de réclamation, la répartition qui a le mieux tenu après plusieurs itérations est la suivante :
SYSTEME = """
Tu extrais quatre champs d'un courriel de réclamation client au service
après-vente d'une enseigne de petit électroménager.
Rends un unique objet JSON avec exactement les clés motif, produit, urgence,
action_demandee. Aucun texte avant ni après l'objet.
Valeurs autorisées :
- motif : livraison | produit_defectueux | facturation | autre
- urgence : faible | moyenne | elevee
- action_demandee : remboursement | remplacement | information | aucune
Si le produit n'est pas identifiable, mettre null.
Si le courriel n'est pas une réclamation, mettre motif = "autre" et
action_demandee = "aucune".
""".strip()
def extraire(courriel: str) -> str:
reponse = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": SYSTEME},
{"role": "user", "content": courriel},
],
temperature=0,
)
return reponse.choices[0].message.content
Tout ce qui est stable d'un courriel à l'autre vit dans SYSTEME. Le
courriel lui-même, seul contenu variable, vit dans le message utilisateur.
Cette discipline paie au module 10, quand la même consigne système sert à
des dizaines d'appels par jour et qu'il faut la versionner sans toucher au
flux entrant.
Stabilité entre appels
Sans configuration explicite, un même courriel envoyé deux fois peut produire deux JSON différents. Trois leviers réduisent cette variance :
Température. temperature=0 demande au modèle de choisir à chaque
étape le jeton le plus probable. La sortie devient quasi déterministe.
C'est le réglage par défaut recommandé pour toute extraction structurée.
Graine aléatoire. Certaines API acceptent un paramètre seed qui fixe
la source pseudo-aléatoire. Utile pour reproduire un bogue en développement.
Version du modèle. gpt-4o-mini n'est pas un contrat immuable ; le
fournisseur peut mettre à jour le modèle en arrière-plan. Épingler une
version datée (gpt-4o-mini-2024-07-18 par exemple) protège d'une
régression silencieuse. Le compromis est de ne pas bénéficier
automatiquement des améliorations.
où est le nombre de jetons envoyés (système + utilisateur) et le nombre de jetons rendus. Une consigne système bien tenue vit dans à chaque appel : la maintenir concise a un impact direct sur la facture.
Si la consigne système dit déjà « sortie JSON stricte » et que le message utilisateur le répète, deux problèmes apparaissent : les jetons sont gaspillés, et surtout une divergence future entre les deux formulations créera un comportement imprévisible. Une règle vit à un seul endroit ; c'est presque toujours le canal système.
En résumé
- Le canal système porte les règles du jeu, le canal utilisateur porte la charge variable ; cette séparation reproduit la distinction entre schéma et données.
- Les modèles récents donnent plus de poids aux instructions système qu'aux instructions utilisateur, ce qui stabilise le format sans le garantir absolument.
- Un persona n'a d'intérêt que s'il contraint un comportement observable ; les qualificatifs décoratifs coûtent des jetons sans effet.
- La stabilité entre appels passe par
temperature=0, une graine fixée en développement, et une version de modèle épinglée en production.
Module suivant : le nombre et le choix des exemples à joindre à la consigne, qui décident souvent plus que la reformulation du texte.