Prompts et gabarits de conversation
Chaque message que vous envoyez est enveloppé de balisage avant que le modèle ne le voie. Le gabarit de conversation transforme vos messages étiquetés par rôle en une seule chaîne de jetons plate, et le modèle a été entraîné à lire exactement cette chaîne — pas vos objets API bien rangés. L'enveloppe juste et un modèle instruct 3B se comporte ; l'enveloppe fausse et un modèle 70B émet de la soupe de mots.
L'enveloppe : une conversation, trois dialectes
Votre API expose des rôles : system, user, assistant. Le modèle voit des jetons spéciaux. La même conversation à deux messages, rendue de trois façons.
ChatML — modèles de la famille Qwen et fine-tunes de lignée Hermes :
<|im_start|>system
Tu es un assistant concis.<|im_end|>
<|im_start|>user
Résume ce fichier.<|im_end|>
<|im_start|>assistant
Style Llama 2 — marqueurs système imbriqués dans la première instruction :
<s>[INST] <<SYS>>Tu es un assistant concis.<</SYS>>
Résume ce fichier. [/INST] Le fichier implémente un tokenizer... </s>
Style Gemma — il n'y a pas de rôle système ; les instructions voyagent sur le premier tour utilisateur, et l'assistant s'appelle model :
<bos><start_of_turn>user
Tu es un assistant concis.
Résume ce fichier.<end_of_turn>
<start_of_turn>model
Même conversation, trois enveloppes incompatibles. Un modèle entraîné sur ChatML ne « déchiffre » pas le balisage Llama — il traite le balisage étranger comme du texte ordinaire et répond de même.
Les moteurs lisent le gabarit depuis le fichier modèle
Les métadonnées GGUF embarquent un chat_template (un extrait Jinja). llama.cpp, Ollama, LM Studio et Open WebUI le lisent et rendent vos messages automatiquement, voilà pourquoi le chat marche immédiatement avec un GGUF propre. Deux pièges classiques : l'endpoint brut de complétion (/completion) saute le gabarit et donne au modèle du texte nu — utilisez l'endpoint de chat ; et un GGUF peut arriver avec un gabarit manquant ou faux — passez-en un explicitement (--chat-template dans llama.cpp, un Modelfile dans Ollama) ou prenez un autre quant du même modèle chez une source qui l'a bien fait.
Symptômes d'un mauvais gabarit
- Réponse vide immédiate — le prompt rendu ressemble déjà à une conversation finie, donc le modèle émet EOS immédiatement.
- Fuite de rôles — la sortie se lit
user: bien sûr ! assistant:— le modèle imite l'enveloppe au lieu de répondre. - Charabia — soupe de mots de modèle base d'un modèle qui discutait bien il y a une heure, parce que vous avez changé de fichier sans changer de gabarit.
Pour diagnostiquer, videz le prompt rendu — le serveur llama.cpp le journalise verbeusement, OLLAMA_DEBUG=1 le montre dans Ollama. Puis corrigez le gabarit ou le fichier : dépannage.
Prompts système et précédence
Le rôle système fixe le comportement persistant : persona, langue, format de sortie, posture de sécurité. C'est du contexte, pas du firmware — une longue conversation peut le laver, et les petits modèles le pondèrent moins que vous ne l'espérez. Deux règles pratiques : mettez tout ce qui porte (langue, contrat de format, contraintes dures) dans le prompt système et reformulez-le dans le dernier message utilisateur ; les instructions les plus proches de la génération gagnent.
Zéro-shot vs few-shot
Le zéro-shot demande ; le few-shot montre. Extraire des champs structurés de rapports de bug avec un modèle 3B, en zéro-shot — « Extrais le titre, le composant et la sévérité en JSON » — donne un JSON valide à clés cohérentes environ deux fois sur trois, avec des noms de clés qui dérivent (severity à un tour, priority au suivant).
Few-shot : même modèle, deux exemples travaillés, troisième rapport laissé ouvert :
Rapport : « Le bouton de connexion ne fait rien sur Safari 17. »
{"title": "Bouton de connexion inactif", "component": "auth", "severity": "medium"}
Rapport : « L'appli plante lors de l'envoi de vidéo 4K. »
{"title": "Crash à l'envoi 4K", "component": "upload", "severity": "high"}
Rapport : « Le mode sombre rend le texte des réglages illisible. »
Les exemples portent le contrat de format, donc l'échantillonneur choisit du contenu au lieu d'inventer du schéma. Sur cette classe de tâches, le taux d'échec de format tombe typiquement de ~30% à quelques pourcents. Deux ou trois exemples sont le genou de la courbe ; au-delà, vous payez des jetons de contexte. Pour des schémas stricts, sautez les devinettes : sortie structurée.
Les motifs qui survivent aux petits modèles
| Motif | Pourquoi ça marche |
|---|---|
| Une tâche par prompt | les tâches se disputent l'attention ; les perdantes sont abandonnées |
| Format de sortie explicite (« JSON avec clés a, b, c ») | rend le format quasi déterministe |
| Étapes numérotées (« 1) localiser 2) expliquer 3) corriger ») | la chaîne reste sur rails au lieu d'errer |
| Des exemples plutôt que des descriptions | les modèles imitent mieux qu'ils n'obéissent à la prose |
| Méta-instructions courtes | chaque règle en plus dilue toutes les autres |
Le milieu du contexte est l'endroit où les instructions meurent
L'attention est la plus forte au début et à la fin du prompt — l'effet « lost in the middle », stable entre familles de modèles. Placement pratique : objectif et contrat de format en haut, le document à traiter en bas, et pour les longs documents une répétition d'instruction en une ligne après la charge. La position porte autant que le contenu — et chaque tour de contexte en plus coûte de la mémoire : cache KV.
Séquences d'arrêt
La génération s'arrête quand le modèle émet son jeton EOS — le gabarit définit quel jeton c'est. Des séquences d'arrêt supplémentaires (le paramètre stop sur le serveur llama.cpp et les APIs compatibles OpenAI) tronquent sur une chaîne : utile quand un modèle bavard commence à écrire votre prochain tour utilisateur. Choisissez des arrêts qui ne peuvent vouloir dire que « tour terminé » (\n<|im_start|> sur les modèles ChatML), jamais des chaînes présentes dans des réponses légitimes — un simple saut de ligne coupera du code multi-lignes en plein bloc.
La concision bat la verbosité sous ~7B
Les petits modèles instruct suivent une instruction de 40 mots mieux qu'un barème de 400 : leur attention limitée s'étale sur ce que vous leur tendez. Structure et exemples remplacent les règles en prose. Gardez les prompts-fleuves pour les gros modèles ; ce sont les seuls à lire chaque ligne.
Modèles de fragments réutilisables
Extraction :
Extrais du texte ci-dessous : noms de personnes, dates, montants.
Renvoie un tableau JSON, un objet par élément, clés : name, date, amount.
Pas de prose avant ni après le JSON.
Texte : {text}
Résumé :
Résume en exactement 3 puces, chacune de moins de 15 mots,
pour quelqu'un qui a raté la réunion. La décision la plus importante d'abord.
Texte : {text}
Revue de code :
Passe en revue le diff ci-dessous. Liste au plus 5 constats, ordonnés par sévérité.
Formate chacun ainsi : [severity] fichier:ligne — problème — correctif proposé.
Pas d'éloges ni de résumé. Diff : {diff}
Voir aussi : jetons · sortie structurée · paramètres moteur · dépannage