Le Mythe des “Prompts Avancées”
Bonjour à tous !
L’édition d'aujourd'hui se concentre sur le problème actuel du prompting. Nous aborderons les bases et ajouterons quelques techniques dites "avancées", qui ne sont en réalité que du bon sens enveloppé dans un jargon sophistiqué.
Malgré tout le 'hype' médiatique autour des techniques de prompting "avancées", il s'agit vraiment de dire au modèle ce que vous voulez en langage simple.
Tout est question de bonne communication.
Donner des directives - soyez clair, concis, et ajoutez peut-être quelques exemples si vous vous sentez généreux.
Voici notre court article d'opinion sur les instructions...
1. Comprendre le prompting
Un prompt est l'entrée ou l'instruction donnée à un modèle pour générer du texte. Concevoir un prompt efficace peut améliorer de manière significative la qualité et la pertinence des réponses du modèle. Mais ce n'est rien de trop complexe. Il s'agit simplement de bonne communication—dire ce que vous voulez de manière claire et concise, et ajouter des exemples si possible.
Dans leur forme la plus simple, les prompts peuvent être des questions ou des instructions, par exemple demander à un modèle de compléter une phrase :
Prompt : "Complétez cette phrase : Le ciel est"
Réponse : "Le ciel est bleu pendant la journée et sombre la nuit."
Bien que cela soit élémentaire, plus de contexte ou d'instructions détaillées peuvent conduire à des résultats mieux gérés. C'est l'essence même du prompt engineering, où vous optimisez les prompts pour des tâches spécifiques afin d'obtenir les résultats les plus pertinents et précis. Toutes les techniques "avancées" sont en grande partie exagérées sauf les quelques-unes que nous mentionnerons dans cette itération.
2. Notions de base du formatage des prompts
Le formatage des prompts est extrêmement important pour que le modèle comprenne ce que vous voulez. Utilisez des puces ou des listes numérotées claires pour donner vos instructions ou les étapes à suivre. Pensez simplement à rédiger le meilleur message Slack pour une nouvelle tâche à un collègue, et vous devriez être bon.
Le plus important : relisez-vous et utilisez Antidote ! Les fautes de frappe stupides transforment les mots et affectent la façon dont les modèles les interprètent.
Il existe des outils comme la fonctionnalité Generate a Prompt d'Anthropic ou le Prompt Tuner de Cohere qui peuvent aider. Ces outils optimisent votre prompt initial, le rendant plus détaillé et clair pour améliorer les performances de la tâche souhaitée. Mais vous ne voulez toujours pas dépendre de ces outils et apprendre d'abord les bases des prompts.
Par exemple, un prompt simple comme "Complétez les phrases que les utilisateurs vous donneront"
pourrait être complètement transformé en ce qui suit en utilisant la fonctionnalité Generate a prompt d'Anthropic :
"""
Vous êtes chargé de compléter les phrases que les utilisateurs vous fourniront. Votre objectif est de terminer la phrase de manière grammaticalement correcte, cohérente et contextuellement appropriée.
Voici la phrase incomplète :
<incomplete_sentence>
{{INCOMPLETE_SENTENCE}}
</incomplete_sentence>
Pour compléter la phrase :
1. Lisez attentivement la phrase incomplète et comprenez son contexte et son ton.
2. Considérez plusieurs fins possibles qui auraient du sens compte tenu du début de la phrase.
3. Choisissez la fin la plus appropriée et la plus naturelle.
4. Assurez-vous que votre fin maintient la structure grammaticale et le temps de la phrase originale partielle.
5. Assurez-vous que la phrase complète est cohérente et transmet un message clair.
Fournissez votre phrase complétée dans les balises <completed_sentence>. La phrase complétée doit inclure à la fois la partie incomplète originale et votre ajout, formant une phrase complète.
Maintenant, veuillez compléter la phrase donnée :
<completed_sentence>
"""
3. Techniques de prompting "avancées"
Comme nous l'avons dit, il n'existe pas de technique avancée pour formuler des prompts. Il suffit d'apprendre à discuter avec les modèles de langage et d'obtenir ce que vous voulez par essais et erreurs.
Le meilleur que vous puissiez faire est :
Soyez clair.
Soyez concis.
Demandez au modèle de donner ses étapes de raisonnement.
Itérez (enchaînez) avec le modèle.
Voici un peu plus de détails (avec les noms appropriés) sur les seules "techniques" que vous devez connaître…
Prompt sans contexte (Zero-shot Prompting), aka "Fais ça"
Il s'agit simplement de dire clairement ce que vous voulez. Donnez des instructions au modèle sans fournir d'exemples. C'est utile pour les tâches simples où le modèle possède suffisamment de connaissances préalables :
Exemple : "Classifiez le texte suivant comme positif ou négatif : 'J'ai passé une excellente journée !'"
Réponse : "Positif".
Remarque : "Zero-shot" vient de la littérature et est utilisé pour décrire ce dont un modèle est capable sans information supplémentaire. C'est un moyen pour les scientifiques de décrire les capacités brutes d'un modèle. Un mot compliqué pour un concept simple.
Prompt avec quelques exemples (Few-shot Prompting), aka "Voici quelques exemples"
Le prompt avec quelques exemples est la meilleure chose que vous puissiez faire sans réentraîner un modèle. Il améliore la capacité du modèle à effectuer une tâche en fournissant quelques exemples (par exemple, des paires question-réponse) avec le prompt principal. Cette spécificité aide le modèle à mieux comprendre la tâche :
Format :
"Q : <Question>? R : <Réponse>"
"Q : <Autre Question>? R : <Autre Réponse>"
Nous donnons généralement 3 à 5 exemples de questions et/ou de réponses, ce qui indique au modèle comment il doit se comporter. Cette approche est le meilleur rapport qualité-prix pour exécuter une nouvelle tâche pour laquelle le modèle n'a pas été formé.
Chain-of-Thought, aka "Réfléchis avant d'agir"
Le prompt avec chain-of-thought (CoT) est probablement la meilleure méthode pour rendre votre modèle de langage plus "intelligent". Il fait des merveilles. En CoT, nous demandons au modèle de décomposer ses étapes de raisonnement. Clairement, le modèle est invité à résoudre les problèmes étape par étape, ce qui est particulièrement utile pour les tâches complexes comme le raisonnement mathématique ou la génération de résumés de texte complets :
Prompt : "Réfléchissons à cela étape par étape pour résoudre le problème de mathématiques : 'Quelle est la somme de 23 + 56 ?'"
Réponse : "Tout d'abord, nous additionnons 20 et 50 pour obtenir 70. Ensuite, ajouter les 3 et 6 restants donne 9. Donc, 70 + 9 égale 79."
Cela agit essentiellement comme un mécanisme manuel pour reproduire notre processus de réflexion, tout comme nous réfléchirions avant de donner notre réponse finale. Le modèle génère le texte petit à petit, et chaque fois qu'il génère un nouveau mot (appelé token), il est ajouté au contexte avec le prompt original. Ce contexte mis à jour dynamiquement aide le modèle à "penser" en décomposant la tâche étape par étape. Cela signifie en fin de compte que lorsque vous promptez un modèle, vous le forcez à générer des connaissances supplémentaires avant de répondre et de les utiliser.
Donc, lorsque vous demandez au modèle de "Réfléchir avant d'agir", tout le texte intermédiaire généré (qui sont généralement les premières étapes ou le plan d'action) est dans son contexte, l'aidant à "comprendre" la demande et à planifier avant de donner sa réponse finale. C'est quelque chose que tous les humains (devraient) faire !
Chaînage de prompts (Chain Prompting), aka "Discuter"
Le chaînage de prompts signifie simplement itérer avec le modèle. Il s'agit essentiellement d'aller et venir avec l'IA pour améliorer ou corriger sa réponse. Vous pouvez le faire manuellement ou avec des prompts automatisés. Cela a un objectif similaire à la CoT, mais de manière plus dynamique. Le modèle aura plus de contexte et de meilleure qualité, ce qui lui permettra à nouveau de réfléchir. Il utilise généralement vous-même, d'autres modèles de langage ou des API pour "discuter" et obtenir de nouveaux résultats. Cela vous permet également d'ajouter du contenu plus dynamique dans les prompts en fonction de la façon dont la "discussion" (ou l'échange) progresse.
Génération augmentée par récupération, aka "Chercher avant de répondre"
Vous pouvez établir un parallèle avec la génération augmentée par récupération (RAG). La RAG consiste simplement à récupérer les informations les plus pertinentes dans une base de données avant de formuler un prompt pour un modèle de langage. Ensuite, vous ajoutez simplement ces informations récupérées avec la question de l'utilisateur dans le prompt. Ici, nous ajoutons essentiellement un contexte utile au prompt initial avant de l'envoyer au modèle.
Prompt : "Voici quelques informations contextuelles pour répondre à la question de l'utilisateur : <Informations récupérées>. Répondez à cette question : <question>"
Cela aide le modèle à répondre à la question de l'utilisateur avec des connaissances spécifiques. Vous pouvez ajouter autant de texte pertinent que le modèle peut gérer.
Évidemment, certaines fonctions vous permettent d'utiliser Internet, ce qui équivaut à une base de données RAG, mais c'est Internet.
Par exemple, avec ChatGPT, vous pouvez demander au modèle d'utiliser son outil de recherche Web avant de répondre. Cela est très efficace si la réponse que vous cherchez nécessite des informations à jour.
Prompt : "Quel pays a remporté le plus de médailles d'or olympiques jusqu'à présent ? Utilisez l'outil de recherche Web avant de répondre."
4. Optimisation des résultats
Outre le prompt, il existe d'autres méthodes pour améliorer la qualité du contenu et la structure des résultats.
Pour un meilleur contenu, vous pouvez ajuster le paramètre de température pour contrôler l'aléatoire : des valeurs plus basses pour des résultats plus déterministes et des valeurs plus élevées pour des résultats plus créatifs. Vous pouvez également mettre en œuvre la "Self-Consistency” (aka choisir la réponse la plus fréquente) en sollicitant le modèle plusieurs fois avec la même entrée et en sélectionnant la réponse la plus choisie.
Les vérifications Regex après la génération peuvent être utilisées pour s'assurer que la sortie du modèle respecte un certain format. Par exemple, vous pourriez masquer la génération d'une URL pour des raisons de sécurité si vous construisez une application pour vos clients en repérant le "http(s)://www…" ou en identifiant un domaine comme "towardsai.net". Un autre exemple serait de vérifier si le résultat respecte le format JSON.
L'échantillonnage contraint - Constrained sampling (aka blacklistage de mots) est un autre concept similaire qui peut être utilisé où vous indiquez au modèle quels mots ou parties de mots blacklister du vocabulaire d'un modèle de langage lors de la génération. Avec cette méthode, le modèle ne pourra pas produire les mots blacklistés et ne pourra donc générer que les mots souhaités. L'approche permet un contrôle précis du format des résultats avec un impact minimal sur les performances car elle filtre simplement les mots pendant la génération (comparé à la post-génération, qui pourrait être fait avec la vérification Regex).
Remarque : Cette méthode nécessite un accès total au modèle. Vous pouvez utiliser llama.cpp pour appliquer cette technique avec un modèle à poids ouvert comme Llama 3, mais elle ne peut pas être utilisée avec un modèle accessible via une API comme GPT-4o.
Avec OpenAI et la plupart des autres grands modèles de langage, vous pouvez utiliser l'appel d'outils (ou fonctions). Tous les modèles ne peuvent pas le faire car cela nécessite un entraînement spécifique du modèle. En mode JSON, les modèles de langage sont entraînés pour générer des sorties formatées en JSON valide, tandis que l'appel de fonction (function calling) vous permet de fournir une signature de fonction, et le modèle renvoie alors les arguments pour appeler cette fonction dans un format JSON valide.
Lorsque vous expérimentez ces approches, tenez compte non seulement des compromis entre créativité, précision et structure, mais aussi des capacités du modèle de langage choisi. Par exemple, vous pourriez combiner l'ajustement de la température et la cohérence automatique pour améliorer le contenu, puis appliquer une méthode de structuration appropriée en fonction des capacités de votre modèle de langage et de vos besoins spécifiques, qui changeront si vous passez de Llama à Claude.