Partager via


Ingénierie d’invites dans .NET

Dans cet article, vous explorez les concepts essentiels d’ingénierie de prompt. De nombreux modèles IA sont basés sur des prompts, ce qui signifie qu’ils répondent au texte d’entrée utilisateur (un prompt) avec une réponse générée par des algorithmes prédictifs (une complétion, ou achèvement). Les modèles récents prennent souvent en charge les complétions sous forme de conversation, avec des messages basés sur des rôles (système, utilisateur, assistant) et sur l’historique des conversations afin de conserver les conversations.

Utiliser des prompts

Considérez cet exemple de génération de texte dans lequel invite est l’entrée utilisateur et saisie semi-automatique est la sortie du modèle :

Invite : « Le président qui a servi le plus court mandat était »

Saisie semi-automatique : « Pedro Lascurain. »

L’achèvement s’affiche correctement, mais que se passe-t-il si votre application est censée aider des étudiants en Histoire des États-Unis ? Le mandat de Pedro Lascurain de 45 minutes est le plus court mandat de tous les présidents, mais il assuma la fonction de président du Mexique. Les étudiants en Histoire des États-Unis sont probablement à la recherche de « William Henry Harrison ». Clairement, l’application peut être plus utile à ses utilisateurs prévus si vous lui donnez un contexte.

L’ingénierie de prompt ajoute du contexte au prompt en fournissant des instructions, des exemples et des indications pour aider le modèle à produire de meilleures achèvements.

Bien souvent, les modèles qui prennent en charge la génération de texte ne nécessitent aucun format spécifique, mais vous devez organiser vos prompts afin de différencier clairement les instructions des exemples. Les modèles qui prennent en charge les applications basées sur les conversations utilisent trois rôles pour organiser les achèvements : un rôle système qui contrôle la conversation, un rôle utilisateur pour représenter l’entrée utilisateur, et un rôle assistant pour répondre aux utilisateurs. Divisez vos prompts en messages pour chaque rôle :

  • Les messages système donnent au modèle les instructions sur l’assistant. Une invite ne peut avoir qu’un seul message système, qui doit être le premier message.
  • Les messages utilisateur incluent les prompts de l’utilisateur, et affichent des exemples et des prompts historiques, ou contiennent des instructions pour l’assistant. Un exemple de saisie semi-automatique de conversation doit avoir au moins un message utilisateur.
  • Les messages assistant affichent des exemples d’achèvements ou des achèvements historiques, et doivent contenir une réponse au message utilisateur précédent. Les messages de l’assistant ne sont pas obligatoires, mais si vous en incluez un, il doit être associé à un message utilisateur pour former un exemple.

Utiliser des instructions pour améliorer l’achèvement

Une instruction est un texte qui indique au modèle comment répondre. Une instruction peut être une directive ou un impératif :

  • Les directives indiquent au modèle comment se comporter, mais ne sont pas des commandes simples. Pensez à la configuration des personnages pour un acteur d’improvisation : « Tu aides les étudiants à découvrir l’Histoire des États-Unis, alors parle des États-Unis, sauf s’ils demandent spécifiquement pour d’autres pays. »
  • Les impératifs sont des commandes non ambiguës que le modèle doit suivre. « Traduis en Tagalog : »

Les directives sont plus ouvertes et flexibles que les impératifs :

  • Vous pouvez combiner plusieurs directives dans une seule instruction.
  • Les instructions fonctionnent généralement mieux lorsque vous les utilisez avec des exemples. Toutefois, étant donné que les impératifs sont des commandes non ambiguës, les modèles n’ont pas besoin d’exemples pour les comprendre (même si vous pouvez utiliser un exemple pour montrer au modèle comment mettre en forme les réponses). Étant donné qu’une directive n’indique pas exactement au modèle ce qu’il faut faire, chaque exemple peut aider le modèle à mieux répondre.
  • Il est généralement préférable de décomposer une instruction difficile en une série d’étapes, ce que vous pouvez faire avec une séquence de directives. Vous devez également indiquer au modèle de générer le résultat de chaque étape afin que vous puissiez facilement effectuer des ajustements granulaires. Bien que vous puissiez décomposer l’instruction en étapes vous-même, il est plus facile d’indiquer au modèle de le faire et de générer le résultat de chaque étape. Cette approche est appelée invite pat chaîne de pensées.

Le contenu principal et le contenu de support ajoutent un contexte

Vous pouvez fournir du contenu pour ajouter davantage de contexte aux instructions.

le contenu principal est du texte que vous souhaitez que le modèle traite avec une instruction. Quelle que soit l’action que l’instruction implique, le modèle l’exécute sur le contenu principal pour produire une saisie semi-automatique.

Le contenu de support est du texte auquel vous faites référence dans une instruction, mais qui n’est pas la cible de l’instruction. Le modèle utilise le contenu de support pour terminer l’instruction, ce qui signifie que le contenu de support apparaît également dans des saisies semi-automatiques, généralement comme un type de structure (par exemple, dans les en-têtes ou les étiquettes de colonne).

Utilisez des étiquettes avec votre contenu d’instructions pour aider le modèle à déterminer comment l’utiliser avec l’instruction. Ne vous inquiétez pas trop sur la précision. les étiquettes n’ont pas besoin de correspondre exactement aux instructions, car le modèle gère des éléments tels que la casse et le format des mots.

Supposons que vous utilisez l’instruction « Résume les réalisations présidentielles américaines » pour produire une liste. Le modèle peut l’organiser et l’ordonner de plusieurs façons. Mais que se passe-t-il si vous voulez que la liste regroupe les réalisations selon un ensemble spécifique de catégories ? Utilisez un contenu de support pour ajouter ces informations à l’instruction.

Ajustez votre instruction afin que le modèle regroupe par catégorie et ajoutez le contenu de support qui spécifie ces catégories :

prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: 'George Washington
- First president of the United States.
- First president to have been a military veteran.
- First president to be elected to a second term in office.
- Received votes from every presidential elector in an election.
- Filled the entire body of the United States federal judges; including the Supreme Court.
- First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ...' ///Text truncated
""";

Utiliser des exemples pour guider le modèle

Voici un exemple de texte qui montre au modèle comment répondre en fournissant un exemple d’entrée utilisateur et de sortie de modèle. Le modèle utilise des exemples pour déduire ce qu’il faut inclure dans les saisies semi-automatiques. Les exemples peuvent être fournis avant ou après les instructions d’une invite d’ingénierie, mais les deux ne doivent pas être mélangés.

Un exemple commence par un prompt, et peut éventuellement inclure un achèvement. Une saisie semi-automatique dans un exemple n’a pas besoin d’inclure la réponse détaillée. Elle peut simplement contenir un mot mis en forme, la première puce d’une liste non triée ou quelque chose de similaire pour indiquer comment chaque saisie semi-automatique doit démarrer.

Les exemples sont classés comme apprentissage zero-shot ou apprentissage few-shot en fonction des saisies semi-automatiques qu’ils contiennent.

  • Les exemples d’apprentissage zero-shot incluent une invite sans saisie semi-automatique détaillée. Cette approche teste les réponses d’un modèle sans lui donner d’exemple de sortie de données. Les prompts zero-shot peuvent avoir des achèvements qui incluent des indices, comme indiquer au modèle de générer une liste ordonnée en incluant « 1. » comme achèvement.
  • Les exemples d’apprentissage few-shot incluent plusieurs paires d’invites avec des saisies semi-automatiques détaillées. L’apprentissage few-shot peut modifier le comportement du modèle en ajoutant à ses connaissances existantes.

Comprendre les indices

Un indice est un texte qui transmet la structure ou le format de sortie souhaités. Comme une instruction, un indice n’est pas traité par le modèle comme s’il s’agissait d’une entrée utilisateur. À l’instar d’un exemple, un indice montre au modèle ce que vous voulez au lieu de lui dire ce qu’il faut faire. Vous pouvez ajouter autant d’indices que vous le souhaitez, afin de pouvoir itérer pour obtenir le résultat souhaité. Les indices sont utilisés avec une instruction ou un exemple et doivent se trouver à la fin de l’invite.

Supposons que vous utilisez une instruction pour indiquer au modèle de produire une liste de réalisations présidentielles par catégorie, ainsi que du contenu de support qui indique au modèle quelles catégories utiliser. Vous décidez que vous souhaitez que le modèle produise une liste imbriquée avec les catégories en capitales, avec les réalisations de chaque président dans chaque catégorie répertoriées sur une ligne commençant par leur nom, avec les présidents répertoriés chronologiquement. Après vos instructions et le contenu de support, vous pouvez ajouter trois indices pour montrer au modèle comment structurer et mettre en forme la liste :

prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: George Washington
First president of the United States.
First president to have been a military veteran.
First president to be elected to a second term in office.
First president to receive votes from every presidential elector in an election.
First president to fill the entire body of the United States federal judges; including the Supreme Court.
First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ...  /// Text truncated

DOMESTIC POLICY
- George Washington: 
- John Adams:
""";
  • STRATÉGIE INTÉRIEURE montre au modèle que vous souhaitez qu’il démarre chaque groupe avec la catégorie en capitales.
  • – George Washington : montre au modèle qu’il doit commencer chaque section avec les réalisations de George Washington répertoriées sur une ligne.
  • – John Adams : montre au modèle qu’il devrait répertorier les présidents restants dans l’ordre chronologique.

Exemple de prompt à l’aide de .NET

.NET fournit différents outils pour prompter et discuter avec différents modèles IA. Utilisez Noyau sémantique pour vous connecter à un large éventail de modèles et de services IA, ainsi qu’à d’autres kits SDK tels que la bibliothèque .NET OpenAI officielle. Noyau sémantique inclut des outils permettant de créer des prompts avec différents rôles et de conserver l’historique des conversations, ainsi que de nombreuses autres fonctionnalités.

Considérez l’exemple de code suivant :

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

// Create a kernel with OpenAI chat completion
#pragma warning disable SKEXP0010
Kernel kernel = Kernel.CreateBuilder()
                    .AddOpenAIChatCompletion(
                        modelId: "phi3:mini",
                        endpoint: new Uri("http://localhost:11434"),
                        apiKey: "")
                    .Build();

var aiChatService = kernel.GetRequiredService<IChatCompletionService>();
var chatHistory = new ChatHistory();
chatHistory.Add(
    new ChatMessageContent(AuthorRole.System, "You are a helpful AI Assistant."));

while (true)
{
    // Get user prompt and add to chat history
    Console.WriteLine("Your prompt:");
    chatHistory.Add(new ChatMessageContent(AuthorRole.User, Console.ReadLine()));

    // Stream the AI response and add to chat history
    Console.WriteLine("AI Response:");
    var response = "";
    await foreach (var item in
        aiChatService.GetStreamingChatMessageContentsAsync(chatHistory))
    {
        Console.Write(item.Content);
        response += item.Content;
    }
    chatHistory.Add(new ChatMessageContent(AuthorRole.Assistant, response));
    Console.WriteLine();
}

Le code précédent fournit des exemples des concepts suivants :

  • Il crée un service d’historique des conversations pour prompter le modèle IA afin de générer des achèvements basés sur les rôles de l’auteur.
  • Il configure l’IA avec un message AuthorRole.System.
  • Il accepte l’entrée utilisateur pour autoriser différents types de prompts dans le contexte d’un AuthorRole.User.
  • Il diffuse de façon asynchrone l’achèvement à partir de l’IA pour fournir une expérience de conversation dynamique.

Étendre vos techniques d’ingénierie de prompt

Vous pouvez également augmenter la puissance de vos prompts avec des techniques d’ingénierie de prompt plus avancées qui sont abordées en profondeur dans leurs propres articles.

  • Les LLM ont des limites d’entrée de jeton qui limitent la quantité de texte que vous pouvez placer dans une invite. Utilisez des incorporations et des solutions de base de données vectorielles afin de réduire le nombre de jetons dont vous avez besoin pour représenter un texte donné.
  • Les LLM ne sont pas formés sur vos données, sauf si vous les formez vous-même, ce qui peut être coûteux et fastidieux. Utilisez la génération augmentée de récupération (RAG) pour mettre vos données à la disposition d’un LLM sans l’entraîner.