Tu veux les meilleurs outils IA avant les autres ?
On teste et on décrypte les nouveaux outils IA chaque soir, en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
Automatisez l'écriture de vos prompts LLM avec DSPy
Modèles de Langage de Grande Taille
L'automatisation de l'écriture de prompts pour les modèles de langage de grande taille (LLM) est un enjeu crucial pour optimiser les interactions avec ces systèmes. DSPy se présente comme un outil révolutionnaire qui permet non seulement de générer des prompts de manière automatique, mais aussi de les évaluer et de les optimiser pour garantir leur efficacité en production.
Nous avons tous probablement fait l'expérience de recevoir des réponses de LLM qui ne correspondaient pas exactement à nos attentes. Souvent, cela nous oblige à reformuler nos prompts plusieurs fois jusqu'à obtenir une réponse satisfaisante. Pour ce faire, nous devons parfois être plus explicites, fournir des exemples, ou encore expliquer pourquoi nous avons besoin de la réponse. Il peut également être nécessaire de définir une persona ou de fournir suffisamment de contexte pour que le LLM puisse répondre de manière appropriée.
Cette approche peut fonctionner lorsque nous interagissons directement avec le LLM. Cependant, la situation change radicalement lorsque nous développons une application basée sur un LLM, un logiciel qui fonctionnera de manière autonome et interagira avec un ou plusieurs LLM. Dans ce cas, le logiciel utilise des prompts prédéfinis qu'il transmet aux LLM. Si les résultats ne sont pas satisfaisants, nous ne sommes pas présents pour reformuler les prompts et réessayer. Cela signifie que les prompts doivent être conçus dès le départ pour être robustes et fiables, afin de garantir un fonctionnement cohérent en production.
Créer un prompt de cette nature peut s'avérer complexe. Dans cet article, nous allons explorer pourquoi cela est le cas et comment un outil Python nommé DSPy peut aider à créer des prompts fiables. DSPy ne se contente pas de générer des prompts automatiquement, il les évalue également en profondeur, vous assurant ainsi de leur efficacité en production. Je partagerai également un extrait de mon dernier livre publié chez Manning Publishing, Building LLM Applications with DSPy, coécrit avec Serj Smorodinsky. Ce livre offre une description complète de DSPy et de son utilisation pour créer des applications basées sur des LLM.
La difficulté de créer un prompt fiable en production
L'un des principaux défis dans la création de prompts fiables réside dans l'imprévisibilité des entrées que nous aurons à traiter. Par exemple, si nous développons une application logicielle qui doit traiter des documents, ces derniers peuvent être trouvés en ligne ou soumis par les utilisateurs du logiciel. Dans le cadre du traitement des documents, l'application peut demander à un LLM de les résumer, de les traduire, d'extraire des informations clés ou d'effectuer d'autres tâches similaires. Supposons que le logiciel demande au LLM de critiquer la plausibilité du contenu des documents. Pour cela, nous pourrions écrire un prompt tel que :
prompt_text = f"Évaluez à quel point le texte suivant est plausible : {document_text}"
Ce prompt utilise une f-string Python pour former le prompt, avec un espace réservé pour le texte du document. D'autres prompts peuvent avoir plusieurs espaces réservés pour les entrées, mais pour simplifier, nous supposerons ici que chaque prompt n'a qu'une seule entrée — le contenu que vous souhaitez que le LLM traite (ce qui est la partie imprévisible).
Ce prompt peut fonctionner suffisamment bien, mais il se peut aussi que non. Il existe de nombreuses façons dont le LLM peut répondre d'une manière qui ne nous plaît pas, au moins occasionnellement. Nous pouvons constater que le LLM se concentre sur des détails non pertinents dans les documents. Ou qu'il a une compréhension différente de ce qui est « plausible » que celle que nous avions en tête. Ou il peut indiquer que presque tous les documents sont entièrement plausibles (ou l'inverse, que presque aucun ne l'est). Ou les réponses peuvent ne pas être formatées comme nous le souhaitons.
Nous pourrions avoir besoin d'ajuster le prompt pour obtenir de manière cohérente les réponses que nous attendons. Pour commencer, nous pouvons essayer ce prompt et quelques autres simples, mais le prompt final pourrait finir par être considérablement plus long et plus détaillé que cela.
En général, à mesure que nous testons avec plus d'entrées (dans ce cas, plus de documents), nous trouverons plus de cas où le prompt actuel ne gère pas bien l'entrée, donc nous ajusterons le prompt pour mieux gérer ces cas. Parfois, nous reformulons le prompt pour qu'il soit plus clair, et d'autres fois, nous ajoutons des phrases au prompt pour traiter ces cas spécifiques. Par exemple : « Si le document fait des affirmations métaphoriques, évaluez l'intention générale et non le sens littéral. » Nous pouvons nous retrouver avec un certain nombre d'instructions supplémentaires comme celle-ci dans le prompt, ce qui peut aider le prompt à bien fonctionner pour ces cas, mais, bien sûr, cela peut aussi rendre le prompt moins efficace pour d'autres entrées.
Et, à mesure que les prompts deviennent plus longs et plus compliqués, ils peuvent devenir plus difficiles à ajuster. Il peut devenir de moins en moins clair quel sera l'effet d'ajouter, de supprimer, de réorganiser ou de reformuler des phrases dans le prompt.
D'autres applications basées sur des LLM peuvent travailler avec d'autres types de données textuelles : messages texte, e-mails, essais, articles de journaux, demandes de brevet, etc. Ou peuvent traiter des images, de l'audio, de la vidéo ou d'autres modalités. Mais, quel que soit le type d'entrée, pour une application non triviale, l'entrée spécifique que l'application rencontre (et transmet au LLM) sera au moins en partie imprévisible. Ce qui signifie que nous aurons besoin d'un prompt robuste et bien spécifié pour gérer une large gamme d'entrées réalistes.
Pour prendre l'exemple des e-mails, si une application basée sur un LLM traite une collection d'e-mails (qu'elle rencontrera en production, et que nous ne pouvons pas prédire complètement), il peut y avoir des e-mails qui sont exceptionnellement : longs, complexes, nuancés, déroutants, erratiques ou autrement différents de ce que nous avions prévu lors de la formation du prompt. La seule façon de tester que votre application fonctionnera de manière fiable en production est de tester avec un ensemble d'entrées large, diversifié et réaliste (dans ce cas, une grande collection d'e-mails réalistes).
Et pour chaque cas de test, nous devons examiner attentivement la réponse du LLM et vérifier qu'elle est appropriée. Dans certains cas, cela est simple. Par exemple, nous pouvons transmettre un texte à un LLM et demander à le classifier d'une certaine manière. Le LLM peut classifier le texte en identifiant la langue (anglais, français, etc.), le sentiment, la toxicité, etc. Dans ces cas, il existe une classe réelle pour chaque entrée, et il y a la classe que le LLM retourne. Nous devons simplement vérifier qu'elles sont identiques : si le texte est en espagnol et que le LLM prédit l'espagnol, c'est correct ; sinon, ce n'est pas le cas. De nombreuses autres tâches LLM produisent également des résultats faciles à évaluer.
Cependant, dans certains cas, l'évaluation des réponses n'est pas si simple. Un exemple est lorsque nous demandons au LLM de générer une réponse plus longue, comme un résumé, une traduction, une critique, des suggestions pour des étapes de suivi, ou toute autre sortie longue basée sur l'entrée. Si vous avez déjà regardé deux ou plusieurs réponses différentes d'un LLM (où chacune est constituée d'une ou plusieurs phrases complètes, et possiblement beaucoup plus longues) et essayé d'évaluer laquelle est meilleure, vous savez que cela prend du temps. Et c'est sujet à erreur. Certaines peuvent être plus succinctes, d'autres plus nuancées, d'autres plus claires. Néanmoins — aussi difficile que cela soit à évaluer — nous devons les évaluer pour déterminer l'efficacité de chaque prompt que nous essayons. L'un des avantages de DSPy est qu'il vous permet d'automatiser cette évaluation.
Ingénierie des Prompts
Pour voir la valeur d'outils comme DSPy, il est bon de regarder l'alternative et le problème que DSPy résout. Normalement, la façon dont nous travaillons avec les LLM est en utilisant une technique connue sous le nom d'ingénierie des prompts. En procédant ainsi, nous écrivons un prompt, le testons (généralement avec juste quelques entrées et en regardant simplement les sorties), écrivons un autre prompt, le testons de manière similaire, et continuons.
Dans des cas plus simples, cela peut fonctionner, mais cela présente un certain nombre de limitations. L'une d'elles est : il est très chronophage de tester chaque prompt candidat avec plus qu'un petit nombre d'entrées. Donc, en pratique, nous testons normalement chaque prompt beaucoup moins que nous le devrions. Ce qui peut poser des problèmes — tester chaque prompt avec très peu d'entrées peut nous donner une mauvaise idée des prompts qui fonctionnent mieux.
Pour compliquer les choses — pour chaque entrée, nous devrions vraiment tester le prompt plusieurs fois (et pas juste une fois), puisque les LLM sont stochastiques. Si un LLM reçoit le même prompt (y compris les mêmes valeurs dans les espaces réservés) plusieurs fois, il peut renvoyer des réponses différentes à chaque fois. Et certaines peuvent être meilleures que d'autres. Si nous avons, disons, 20 documents à tester (dans un exemple où le LLM sera utilisé pour estimer la plausibilité de chaque document), idéalement, nous devrions tester chacun plusieurs fois. Si nous testons chacun 3 fois, cela signifie 60 tests au total. Ce qui, en réalité, ne sera probablement pas fait. Probablement même pas de près.
Et, comme indiqué, cela est encore plus difficile lorsque les LLM renvoient des sorties plus longues, car il est chronophage de les lire, et presque impossible d'être cohérent dans la manière dont nous les évaluons.
Ainsi, tester chaque prompt candidat prend du temps. Tester de nombreux prompts candidats en prend beaucoup plus. Et il n'est pas clair que nous puissions vraiment les comparer équitablement.
Tout cela signifie qu'en général, l'ingénierie des prompts a la qualité intéressante d'être à la fois chronophage et peu fiable. C'est un processus très lent, fastidieux et sujet à erreurs. Les développeurs expérimentés peuvent souvent passer des heures, voire des jours, sur un seul prompt. Et à la fin, ils ne peuvent pas être certains que celui qu'ils ont choisi est vraiment le plus fort.
Existe-t-il une meilleure méthode ?
Si nous prenons un moment pour réfléchir, nous pouvons voir comment nous gérons une situation similaire lorsque nous travaillons avec l'apprentissage automatique. Si nous construisons un réseau de neurones, un modèle Random Forest, XGBoost (ou quelque chose de similaire), chaque fois que nous l'entraînons, nous ne testons pas manuellement chaque élément de l'ensemble de test un par un. En fait, l'idée de faire cela semble un peu ridicule. Le processus est automatisé ; le test est assez simple. Nous faisons simplement passer chaque élément de l'ensemble de test à travers le modèle, obtenons une prédiction pour chacun, et exécutons une fonction pour générer un score global.
Par exemple, nous pouvons utiliser l'Erreur Quadratique Moyenne ou le R Carré pour un problème de régression, et éventuellement le Score F1, le MCC ou l'AUROC pour un problème de classification. En utilisant un outil tel que scikit-learn, nous pouvons prendre les prédictions du modèle pour l'ensemble de test et les valeurs de vérité de référence correspondantes, et simplement les passer à une fonction pour calculer le score global. Nous avons alors un seul nombre indiquant à quel point ce modèle a bien fonctionné.
Nous pouvons ensuite, si nous le souhaitons, réessayer avec différentes caractéristiques, différents hyperparamètres, différentes données d'entraînement (ou tout autre changement par rapport au modèle précédent), réentraîner et réexécuter.


