Ingénierie des prompts

Dans le module sur l'IA générative, vous avez appris que l'espace d'entrée des modèles d'IA générative est pratiquement illimité. Pour générer des résultats qui répondent aux attentes de vos utilisateurs, vous devez créer des requêtes. Une requête est un contrat structuré entre votre application et le modèle.

Une requête bien rédigée :

  • Indique comment le LLM doit construire sa réponse.
  • Il se compose de plusieurs composants qui peuvent être versionnés, testés et améliorés au fil du temps.
  • Peut servir d'artefact partagé pour la collaboration entre les équipes.

Dans ce module, vous allez apprendre à rédiger des requêtes efficaces. Nous expliquons comment une requête est structurée et comment ses composants sont répartis entre le système et l'utilisateur final. Vous apprendrez également les techniques de requête de base et les scénarios dans lesquels les appliquer.

Tout au long de ce module, nous utiliserons un exemple commun : BlogBuddy, un assistant de rédaction optimisé par l'IA, inspiré de l'utilisation de l'API Prompt par CyberAgent.

Revenez au module d'IA générative pour le plan du système BlogBuddy.

Composants d'une requête

Chaque composant d'une requête a un rôle spécifique dans l'orientation du comportement du modèle.

  • Contexte : définit le rôle et le domaine du modèle pour qu'il comprenne comment se comporter.
  • Instruction : attribue une tâche spécifique au modèle.
  • Variables d'entrée : contexte spécifique à la situation, fourni par votre application en temps réel.
  • Format de sortie : définit la structure de sortie attendue. Par exemple, vous pouvez souhaiter obtenir des sorties JSON.
  • Exemples : montrez comment la tâche doit être exécutée pour une ou plusieurs autres entrées.
  • Contraintes : définissez des limites claires pour que le résultat soit cohérent, sûr et conforme à votre marque.

Votre requête peut inclure tout ou partie de ces composants. L'exemple suivant illustre ces composants pour la fonctionnalité d'assistance à la rédaction de BlogBuddy.

### Context

You are a writing assistant for blog authors.
Your job is to generate helpful, concise, and engaging content.

### Instruction

Generate 3 alternative titles for the user's blog post with a given style.

### Input variables

Here is the content of the blog post:
${blogPostContent}

Here is the desired style:
${titleStyle}

### Output format

Return valid JSON ONLY, in the following exact structure:
{
  "titles": ["Title option 1", "Title option 2", "Title option 3"]
}

### Examples

Example input:
{
  "blogPostContent": "I finally visited the small neighborhood café I've been eyeing for months...",
  "titleStyle": "friendly"
}

Example output:
{
  "titles": [
    "A First Visit to the Neighborhood Café",
    "Trying the Café I've Wanted to Visit for Months",
    "My Experience at a Long-Awaited Local Spot"
  ]
}
### Constraints

- Each title must be under 128 characters.
- Titles must be original, not copied verbatim from the draft.
- Keep the tone natural and human. Avoid emojis unless explicitly requested.
- Avoid sensationalism or clickbait.
- If the draft includes multiple topics, choose the most prominent topic.

Pour vos premières requêtes, commencez par l'essentiel : l'instruction et le format de sortie. Ensuite, ajoutez progressivement d'autres composants à mesure que vous analysez les résultats et que vous déterminez les contrôles plus précis nécessaires pour réussir.

Prompts système et prompts utilisateur

Certains composants d'invite sont codés en dur, tandis que d'autres peuvent être fournis par l'utilisateur final :

  • La requête système est fournie par les développeurs d'applications et définit le comportement global du modèle. Il peut définir le rôle du modèle, le ton attendu, le format de sortie (tel qu'un schéma JSON strict) et toutes les contraintes globales. C'est également dans l'invite système que vous encodez les exigences de sécurité et de responsabilité. Il reste cohérent d'une requête à l'autre et constitue une base stable pour le comportement du modèle.

  • La requête utilisateur contient la demande immédiate qui conduit à une sortie. L'utilisateur demande une tâche spécifique, qui peut inclure des variables spécifiques. Par exemple, "Affiche trois titres pour ce post", "Continue ce paragraphe" ou "Rends ce texte plus formel".

La plupart des API d'IA générative vous permettent de structurer une requête sous forme de tableau de messages, chacun ayant un rôle (système ou utilisateur) et un contenu. Cela permet de séparer plus facilement les instructions stables et globales des entrées dynamiques par requête.

Comment décidez-vous des composants à inclure dans l'invite système et de ceux que l'utilisateur doit spécifier ? La réponse dépend de la flexibilité de votre expérience utilisateur et des capacités de votre modèle.

Cas d'utilisation limités

Pour les cas d'utilisation très spécifiques, la majeure partie du prompt peut être prédéfinie dans le prompt système. Par exemple, dans BlogBuddy, les utilisateurs peuvent cliquer sur Afficher les titres pour lister les suggestions de titres générées pour leur brouillon.

La tâche est fixe, le format de sortie est connu et l'utilisateur n'a pas besoin de fournir de contexte supplémentaire pour obtenir le résultat attendu. Dans ce cas, vous placez toutes les règles stables, les consignes de ton, les schémas de sortie et les exemples dans l'invite système.

Pour créer cela avec l'API Prompt, nous utiliserons initialPrompts pour définir le comportement au niveau du système pour l'ensemble de la session :

// Defines stable behavior for the entire session
const session = await LanguageModel.create({
  initialPrompts: [
    {
      role: "system",
      content: `You are a blog-writing assistant.
      Your task is to generate high-quality titles for blog posts.
      Always respond in concise, friendly language.
      Return exactly 3 alternative titles.
      Produce valid JSON with a "titles" array of strings.`
    }
  ]
});

Lorsque l'utilisateur clique sur Afficher les titres, l'invite est appelée pour le contenu actuel :

// The only variable input is the blog content
const result = await session.prompt(blogContent);

Au fil du temps, les utilisateurs peuvent demander plus de flexibilité et de contrôle. Dans ce cas, vous pouvez déplacer certains composants dans l'invite utilisateur, avec des commandes d'interface. Par exemple, un menu déroulant d'options de style ou de ton.

Toutefois, un nombre excessif d'actions structurées peut nuire à l'expérience utilisateur. Dans ce cas, vous pouvez envisager de passer à une conception plus ouverte qui permet aux utilisateurs de spécifier eux-mêmes la plupart de leurs requêtes. Vous en apprendrez davantage sur l'optimisation de cette conception dans le module sur les modèles UX.

Les tâches flexibles reposent sur des requêtes utilisateur détaillées

Une expérience interactive et ouverte qui aide les utilisateurs à rédiger des articles de blog à partir de zéro, offrant ainsi plus de flexibilité à vos utilisateurs. Ils peuvent demander des idées, des plans, des réécritures, des changements de ton ou des brainstormings, ou préciser exactement comment une tâche doit être exécutée. Avec ce type d'application, vous avez probablement besoin d'un modèle côté serveur plus puissant.

Avec les tâches flexibles, l'utilisateur doit spécifier plus d'informations, car la gamme d'options possibles est beaucoup plus large. Le prompt système régit toujours le comportement global.

Voici les bonnes pratiques :

  • Placez des règles, une structure et des exemples stables dans l'invite système. Placez le contenu dynamique et les demandes spécifiques aux tâches dans la requête utilisateur.
  • Plus votre UX est ouverte, plus la requête utilisateur doit être flexible pour s'adapter à des entrées imprévisibles.
  • Plus la requête utilisateur doit effectuer de tâches, plus le modèle doit être performant, car il doit gérer une plus grande variation avec moins de structure intégrée.

Vous pouvez utiliser ces règles pour optimiser progressivement le compromis entre le contrôle et la flexibilité des utilisateurs dans le contexte de votre produit. Observer attentivement les préférences et les comportements des utilisateurs. Plus de flexibilité ne se traduit pas toujours par une valeur réelle. Vos utilisateurs doivent également avoir le temps, les compétences et la bande passante cognitive nécessaires pour rédiger des requêtes plus détaillées.

Techniques de prompting courantes

Les développeurs essaient généralement plusieurs techniques d'incitation pour trouver celle qui convient le mieux à leur cas d'utilisation et à leur modèle.

Prompt zero-shot

Vous décrivez la tâche au modèle et espérez que tout ira pour le mieux. Exemple :

"What is the capital of France?"

L'incitation zero-shot est une référence efficace pour de nombreuses tâches d'IA. Pour les requêtes simples, comme celles qui portent sur des connaissances encyclopédiques, il est probablement préférable de continuer à utiliser cette technique. Toutefois, dans la plupart des applications concrètes, vous devez développer votre requête avec une logique et des conditions supplémentaires.

Prompt few-shot

Avec le prompting few-shot, vous fournissez des exemples pour illustrer le bon comportement, le style, la structure et d'autres variables importantes. Voici un exemple de requête pour la classification des sentiments :

You classify user messages into one of the following categories:
- "positive"
- "negative"
- "neutral"
Here are examples to guide your classifications:
Input: "I love this product! It works perfectly."
Output: { "label": "positive" }

Input: "This is terrible. I want a refund."
Output: { "label": "negative" }

Le prompting few-shot est utile pour ce type de tâche pseudo-prédictive. Elle peut également être appliquée à des tâches qui suivent une structure reconnaissable, comme la génération de titres dans la figure 1.

Lorsque l'espace de sortie est très large, comme pour les contenus ouverts ou longs, le prompting few-shot n'est probablement pas la meilleure technique. Il est difficile, voire impossible, de fournir des exemples qui couvrent de manière significative l'espace.

Prompting par chaîne de pensée

Vous encouragez le modèle à raisonner étape par étape avant de produire une réponse. Les étapes peuvent être décrites explicitement ou laissées à la définition du modèle. Exemple :

"Think step-by-step to identify the main idea of this paragraph. Then produce a
short heading under 60 characters."

La chaîne de pensée est très efficace pour les tâches qui nécessitent un raisonnement et une exécution en plusieurs étapes, comme la création d'un plan pour un article de blog ou la prise de décisions complexes. Il s'agit de la principale technique utilisée par les modèles de raisonnement.

Cela peut s'avérer coûteux. La génération de traces de raisonnement détaillées augmente la puissance de calcul, les coûts et la latence. Ne l'utilisez que lorsque votre cas d'utilisation nécessite un raisonnement et une planification complexes.

Requêtes d'introspection

Après la génération initiale, vous demandez au modèle de critiquer et de réviser sa propre sortie. Exemple :

"Review your previous output.
Identify unclear phrasing and rewrite it more concisely."

L'autoréflexion est particulièrement utile pour les tâches qui bénéficient d'un affinement itératif, comme les outils d'édition ou de réécriture. Elle est rapide à implémenter et peut améliorer considérablement la qualité. Une boucle d'autoréflexion est utile une fois que votre requête fonctionne bien. Tout d'abord, affinez le résultat pour plus de clarté ou pour ravir davantage l'utilisateur.

Vos points à retenir

Dans ce module, vous avez appris comment les requêtes sont créées à partir de composants structurés. En pratique, l'ingénierie des requêtes est très expérimentale. La clarté et la fiabilité n'apparaissent qu'après plusieurs cycles d'amélioration.

Dans le prochain module, nous examinerons le développement de requêtes axé sur l'évaluation. Cette pratique vous aide à améliorer systématiquement les requêtes et à trouver ce qui fonctionne le mieux pour votre produit et vos utilisateurs.

Ressources

Chacune de ces techniques comporte ses propres variantes et bonnes pratiques. Il existe un large éventail de ressources externes détaillées, par exemple :

Consultez la documentation du modèle que vous avez choisi, car vous y trouverez peut-être des conseils spécifiques pour obtenir les meilleurs résultats possible.

Vérifier que vous avez bien compris

Quels types de règles pouvez-vous spécifier dans une invite système ?

Variables d'entrée spécifiques (telles que les entrées utilisateur), structure de sortie attendue, rôle du modèle et limite du nombre de caractères.
Bravo, bonne réponse !
Seule l'entrée utilisateur doit être saisie ici.
Pas tout à fait. Essayez encore.
Pour définir le rôle et le domaine du modèle, afin qu'il comprenne comment se comporter.
Pas tout à fait. Essayez encore.
Le type et la taille du modèle que vous utilisez.
Pas tout à fait. Essayez encore.

Quelle technique devez-vous utiliser lorsque vous souhaitez que le modèle raisonne par étapes avant de produire la réponse ?

Prompt zero-shot
Mauvaise réponse.
Prompt few-shot
Mauvaise réponse.
Prompting par chaîne de pensée
Bravo, bonne réponse !
Requêtes d'introspection
Mauvaise réponse.

Quand le few-shot prompting est-il le plus utile ?

Lorsque vous demandez au modèle d'effectuer une tâche sans aucun contexte.
Mauvaise réponse.
Lorsque la tâche suit une structure reconnaissable (comme la génération de titres) ou nécessite une mise en forme spécifique.
Bravo, bonne réponse !
Lorsque l'espace de sortie est très grand, comme pour l'écriture créative ouverte.
Mauvaise réponse.
Lorsque vous souhaitez que le modèle critique son propre travail.
Mauvaise réponse.

Qu'est-ce que la technique de prompting par réflexion personnelle ?

Demander au modèle de critiquer et de réviser sa propre sortie pour améliorer la clarté ou la qualité.
Bravo, bonne réponse !
Exécuter la requête plusieurs fois et faire la moyenne des résultats.
Mauvaise réponse.
Demander à l'utilisateur de reformuler la requête si le résultat est mauvais.
Mauvaise réponse.
Cela permet au modèle de modifier la requête système de manière dynamique.
Mauvaise réponse.