Bien démarrer avec la bibliothèque IA Teams
La bibliothèque d’IA Teams simplifie le processus de création d’applications Microsoft Teams intelligentes à l’aide des composants IA. Il fournit des API pour accéder aux données et les manipuler, ainsi qu’une gamme de contrôles et de composants pour créer des interfaces utilisateur personnalisées.
Vous pouvez facilement intégrer la bibliothèque IA Teams, la gestion des invites et la modération de la sécurité dans vos applications et améliorer l’expérience utilisateur. Il facilite également la création de bots qui utilisent une clé API OpenAI ou Azure OpenAI pour fournir une expérience conversationnelle pilotée par l’IA.
Configuration initiale
La bibliothèque d’IA Teams repose sur le Kit de développement logiciel (SDK) Bot Framework et utilise ses principes fondamentaux pour offrir une extension aux fonctionnalités du Kit de développement logiciel (SDK) Bot Framework. Dans le cadre de la configuration initiale, il est important d’importer les fonctionnalités du Kit de développement logiciel (SDK) Bot Framework.
Remarque
La classe d’adaptateur qui gère la connectivité avec les canaux est importée à partir du Kit de développement logiciel (SDK) Bot Framework.
using Microsoft.Teams.AI;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.TeamsFx.Conversation;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddHttpClient("WebClient", client => client.Timeout = TimeSpan.FromSeconds(600));
builder.Services.AddHttpContextAccessor();
// Prepare Configuration for ConfigurationBotFrameworkAuthentication
var config = builder.Configuration.Get<ConfigOptions>();
builder.Configuration["MicrosoftAppType"] = "MultiTenant";
builder.Configuration["MicrosoftAppId"] = config.BOT_ID;
builder.Configuration["MicrosoftAppPassword"] = config.BOT_PASSWORD;
// Create the Bot Framework Authentication to be used with the Bot Adapter.
builder.Services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();
// Create the Cloud Adapter with error handling enabled.
// Note: some classes expect a BotAdapter and some expect a BotFrameworkHttpAdapter, so
// register the same adapter instance for all types.
builder.Services.AddSingleton<CloudAdapter, AdapterWithErrorHandler>();
builder.Services.AddSingleton<IBotFrameworkHttpAdapter>(sp => sp.GetService<CloudAdapter>());
builder.Services.AddSingleton<BotAdapter>(sp => sp.GetService<CloudAdapter>());
Importer la bibliothèque IA Teams
Importez toutes les classes de pour générer votre bot et utilisez les fonctionnalités de @microsoft/teams-ai
la bibliothèque d’IA Teams.
// import Teams AI library
import {
AI,
Application,
ActionPlanner,
OpenAIModerator,
OpenAIModel,
PromptManager,
TurnState
} from '@microsoft/teams-ai';
import { addResponseFormatter } from './responseFormatter';
import { VectraDataSource } from './VectraDataSource';
Créer des composants IA
Ajoutez des fonctionnalités d’IA à votre application existante ou à une nouvelle application Bot Framework.
OpenAIModel : la classe OpenAIModel permet d’accéder à l’API OpenAI ou à tout autre service, qui respecte le format REST OpenAI. Il est compatible avec les modèles de langage OpenAI et Azure OpenAI.
Gestionnaire d’invites : le gestionnaire d’invites gère la création de l’invite. Il appelle des fonctions et injecte à partir de votre code dans l’invite. Il copie automatiquement l’état de la conversation et l’état utilisateur dans l’invite.
ActionPlanner : ActionPlanner est le composant main qui appelle votre modèle LLM (Large Language Model) et inclut plusieurs fonctionnalités pour améliorer et personnaliser votre modèle. Il est responsable de la génération et de l’exécution des plans en fonction de l’entrée de l’utilisateur et des actions disponibles.
// Create model
OpenAIModel? model = null;
if (!string.IsNullOrEmpty(config.OpenAI?.ApiKey))
{
model = new(new OpenAIModelOptions(config.OpenAI.ApiKey, "gpt-3.5-turbo"));
}
else if (!string.IsNullOrEmpty(config.Azure?.OpenAIApiKey) && !string.IsNullOrEmpty(config.Azure.OpenAIEndpoint))
{
model = new(new AzureOpenAIModelOptions(
config.Azure.OpenAIApiKey,
"gpt-35-turbo",
config.Azure.OpenAIEndpoint
));
}
if (model == null)
{
throw new Exception("please configure settings for either OpenAI or Azure");
}
// Create prompt manager
PromptManager prompts = new(new()
{
PromptFolder = "./Prompts",
});
// Add function to be referenced in the prompt template
prompts.AddFunction("getLightStatus", async (context, memory, functions, tokenizer, args) =>
{
bool lightsOn = (bool)(memory.GetValue("conversation.lightsOn") ?? false);
return await Task.FromResult(lightsOn ? "on" : "off");
});
// Create ActionPlanner
ActionPlanner<AppState> planner = new(
options: new(
model: model,
prompts: prompts,
defaultPrompt: async (context, state, planner) =>
{
PromptTemplate template = prompts.GetPrompt("sequence");
return await Task.FromResult(template);
}
)
{ LogRepairs = true },
loggerFactory: loggerFactory
);
Définir le stockage et l’application
L’objet d’application gère automatiquement la conversation et l’état utilisateur de votre bot.
Stockage : créez un fournisseur de stockage pour stocker la conversation et l’état utilisateur de votre bot.
Application : la classe d’application contient toutes les informations et la logique de bot requises pour une application. Vous pouvez inscrire des actions ou des gestionnaires d’activités pour l’application dans cette classe.
return new TeamsLightBot(new()
{
Storage = sp.GetService<IStorage>(),
AI = new(planner),
LoggerFactory = loggerFactory,
TurnStateFactory = () =>
{
return new AppState();
}
});
TurnStateFactory
vous permet de créer une classe d’état personnalisée pour votre application. Vous pouvez l’utiliser pour stocker des informations ou une logique supplémentaires dont vous avez besoin pour votre bot. Vous pouvez également remplacer certaines des propriétés par défaut de l’état de tour, telles que l’entrée utilisateur, la sortie du bot ou l’historique des conversations. Pour utiliser TurnStateFactory
, vous devez créer une classe qui étend l’état de tour par défaut et passer une fonction qui crée un instance de votre classe au constructeur d’application.
Inscrire des sources de données
Une source de données vectorielle facilite l’ajout de RAG à n’importe quelle invite. Vous pouvez inscrire une source de données nommée auprès du planificateur, puis spécifier le nom des sources de données pour compléter l’invite dans le fichier de config.json
l’invite. Les sources de données permettent à l’IA d’injecter des informations pertinentes provenant de sources externes dans l’invite, telles que les bases de données vectorielles ou la recherche cognitive. Vous pouvez inscrire des sources de données nommées auprès du planificateur, puis spécifier le nom des sources de données qu’elles souhaitent ajouter à l’invite dans le fichier de config.json
l’invite.
// Register your data source with planner
planner.prompts.addDataSource(new VectraDataSource({
name: 'teams-ai',
apiKey: process.env.OPENAI_API_KEY!,
indexFolder: path.join(__dirname, '../index'),
}));
Incorporations
Un incorporation est une sorte de vecteur généré par un LLM qui représente un morceau de texte. Le texte peut être un mot, une phrase ou un document entier. Étant donné que le modèle comprend la syntaxe et la sémantique du langage, l’incorporation peut capturer la signification sémantique du texte sous une forme compacte. Les incorporations sont souvent utilisées dans les tâches de traitement du langage naturel, telles que la classification de texte ou l’analyse des sentiments, mais elles sont également utilisées pour la recherche.
Le modèle de génération d’incorporations est différent des llms de base. Par exemple, OpenAI fournit un modèle d’incorporation appelé text-embedding-ada-002, qui retourne une liste de 1536 nombres qui représente le texte d’entrée. Le système crée des incorporations de texte dans les documents et les stocke dans une base de données vectorielle. À présent, à partir de notre application Chat, nous pouvons implémenter le modèle RAG en récupérant d’abord les données pertinentes sur les documents à partir de la base de données vector, puis en ajoutant l’invite avec ces informations récupérées.
Voici un exemple de VectraDataSource et OpenAIEmbeddings :
import { DataSource, Memory, RenderedPromptSection, Tokenizer } from '@microsoft/teams-ai';
import { OpenAIEmbeddings, LocalDocumentIndex } from 'vectra';
import * as path from 'path';
import { TurnContext } from 'botbuilder';
/**
* Options for creating a `VectraDataSource`.
*/
export interface VectraDataSourceOptions {
/**
* Name of the data source and local index.
*/
name: string;
/**
* OpenAI API key to use for generating embeddings.
*/
apiKey: string;
/**
* Path to the folder containing the local index.
* @remarks
* This should be the root folder for all local indexes and the index itself
* needs to be in a subfolder under this folder.
*/
indexFolder: string;
/**
* Optional. Maximum number of documents to return.
* @remarks
* Defaults to `5`.
*/
maxDocuments?: number;
/**
* Optional. Maximum number of chunks to return per document.
* @remarks
* Defaults to `50`.
*/
maxChunks?: number;
/**
* Optional. Maximum number of tokens to return per document.
* @remarks
* Defaults to `600`.
*/
maxTokensPerDocument?: number;
}
/**
* A data source that uses a local Vectra index to inject text snippets into a prompt.
*/
export class VectraDataSource implements DataSource {
private readonly _options: VectraDataSourceOptions;
private readonly _index: LocalDocumentIndex;
/**
* Name of the data source.
* @remarks
* This is also the name of the local Vectra index.
*/
public readonly name: string;
/**
* Creates a new `VectraDataSource` instance.
* @param options Options for creating the data source.
*/
public constructor(options: VectraDataSourceOptions) {
this._options = options;
this.name = options.name;
// Create embeddings model
const embeddings = new OpenAIEmbeddings({
model: 'text-embedding-ada-002',
apiKey: options.apiKey,
});
// Create local index
this._index = new LocalDocumentIndex({
embeddings,
folderPath: path.join(options.indexFolder, options.name),
});
}
/**
* Renders the data source as a string of text.
* @param context Turn context for the current turn of conversation with the user.
* @param memory An interface for accessing state values.
* @param tokenizer Tokenizer to use when rendering the data source.
* @param maxTokens Maximum number of tokens allowed to be rendered.
*/
public async renderData(context: TurnContext, memory: Memory, tokenizer: Tokenizer, maxTokens: number): Promise<RenderedPromptSection<string>> {
// Query index
const query = memory.getValue('temp.input') as string;
const results = await this._index.queryDocuments(query, {
maxDocuments: this._options.maxDocuments ?? 5,
maxChunks: this._options.maxChunks ?? 50,
});
// Add documents until you run out of tokens
let length = 0;
let output = '';
let connector = '';
for (const result of results) {
// Start a new doc
let doc = `${connector}url: ${result.uri}\n`;
let docLength = tokenizer.encode(doc).length;
const remainingTokens = maxTokens - (length + docLength);
if (remainingTokens <= 0) {
break;
}
// Render document section
const sections = await result.renderSections(Math.min(remainingTokens, this._options.maxTokensPerDocument ?? 600), 1);
docLength += sections[0].tokenCount;
doc += sections[0].text;
// Append do to output
output += doc;
length += docLength;
connector = '\n\n';
}
return { output, length, tooLong: length > maxTokens };
}
}
Invite
Les invites sont des éléments de texte qui peuvent être utilisés pour créer des expériences de conversation. Les invites sont utilisées pour démarrer des conversations, poser des questions et générer des réponses. L’utilisation d’invites permet de réduire la complexité de la création d’expériences de conversation et de les rendre plus attrayantes pour l’utilisateur.
Un nouveau système d’invite basé sur un objet divise une invite en sections et chaque section peut recevoir un budget de jetons qui est soit un ensemble fixe de jetons, soit proportionnel aux jetons restants globaux. Vous pouvez générer des invites pour les API de style de saisie semi-automatique et de saisie semi-automatique de conversation.
Voici quelques instructions pour créer des invites :
- Fournissez des instructions, des exemples ou les deux.
- Fournissez des données de qualité. Vérifiez qu’il y a suffisamment d’exemples et corrigez vos exemples. Le modèle est suffisamment intelligent pour voir les fautes d’orthographe de base et vous donner une réponse, mais il peut également supposer que l’entrée est intentionnelle et qu’elle peut affecter la réponse.
- Vérifiez les paramètres de votre invite. Les paramètres de température et de top_p contrôlent la façon dont le modèle est déterministe dans la génération d’une réponse. Une valeur plus élevée, telle que 0,8, rend la sortie aléatoire, tandis qu’une valeur inférieure telle que 0,2 rend la sortie concentrée et déterministe.
Créez un dossier appelé invites et définissez vos invites dans le dossier . Lorsque l’utilisateur interagit avec le bot en entrant une invite de texte, le bot répond avec une saisie semi-automatique.
skprompt.txt
: contient le texte d’invite et prend en charge les variables et fonctions de modèle. Définissez toutes vos invites texte dans leskprompt.txt
fichier.config.json
: contient les paramètres du modèle d’invite. Fournissez la configuration appropriée pour vous assurer que les réponses du bot sont alignées sur vos besoins.{ "schema": 1.1, "description": "A bot that can turn the lights on and off", "type": "completion", "completion": { "model": "gpt-3.5-turbo", "completion_type": "chat", "include_history": true, "include_input": true, "max_input_tokens": 2800, "max_tokens": 1000, "temperature": 0.2, "top_p": 0.0, "presence_penalty": 0.6, "frequency_penalty": 0.0, "stop_sequences": [] }, "augmentation": { "augmentation_type": "sequence" "data_sources": { "teams-ai": 1200 } } }
Paramètres de requête
Le tableau ci-dessous décrit chaque paramètre de chaîne de requête.
Valeur | Description |
---|---|
model |
ID du modèle à utiliser. |
completion_type |
Type de saisie semi-automatique que vous souhaitez utiliser pour votre modèle. À l’invite, le modèle retourne une ou plusieurs achèvements prédits, ainsi que les probabilités de jetons alternatifs à chaque position. Les options prises en charge sont chat et text . La valeur par défaut est chat . |
include_history |
Valeur booléenne Si vous souhaitez inclure l’historique. Chaque invite obtient son propre historique des conversations distinct pour s’assurer que le modèle n’est pas confus. |
include_input |
Valeur booléenne Si vous souhaitez inclure l’entrée de l’utilisateur dans l’invite. Nombre de jetons pour l’invite. |
max_input_tokens |
Nombre maximal de jetons pour l’entrée. Le nombre maximal de jetons pris en charge est de 4 000. |
max_tokens |
Nombre maximal de jetons à générer dans la saisie semi-automatique. Le nombre de jetons de votre invite plus max_tokens ne peut pas dépasser la longueur du contexte du modèle. |
temperature |
Quelle température d’échantillonnage utiliser, entre 0 et 2. Des valeurs plus élevées comme 0,8 rendent la sortie plus aléatoire, tandis que des valeurs inférieures comme 0,2 la rendent plus ciblée et déterministe. |
top_p |
Alternative à l’échantillonnage avec température, appelé échantillonnage de noyau, où le modèle considère les résultats des jetons avec top_p masse de probabilité. Par conséquent, 0,1 signifie que seuls les jetons comprenant la masse de probabilité de 10 % supérieure sont pris en compte. |
presence_penalty |
Nombre compris entre -2.0 et 2.0. Les valeurs positives pénalisent les nouveaux jetons selon qu’ils apparaissent ou non dans le texte jusqu’à présent, ce qui augmente la probabilité que le modèle parle de nouveaux sujets. |
frequency_penalty |
Nombre compris entre -2.0 et 2.0. Les valeurs positives pénalisent les nouveaux jetons en fonction de leur fréquence existante dans le texte jusqu’à présent, ce qui réduit la probabilité du modèle de répéter la même ligne textuellement. |
stop_sequences |
Jusqu’à quatre séquences où l’API cesse de générer d’autres jetons. Le texte retourné ne contient pas la séquence d’arrêt. |
augmentation_type |
Type d’augmentation. Les valeurs prises en charge sont sequence , monologue et tools . |
Gestion des invites
La gestion des invites permet d’ajuster la taille et le contenu de l’invite envoyée au modèle de langage, en tenant compte du budget de jeton disponible et des sources de données ou des augmentations.
Si un bot a un maximum de 4 000 jetons où 2 800 jetons sont pour l’entrée et 1 000 jetons pour la sortie, le modèle peut gérer la fenêtre de contexte globale et s’assurer qu’il ne traite jamais plus de 3 800 jetons. Le modèle commence par un texte d’environ 100 jetons, ajoute la source de données de 1 200 jetons, puis examine le budget restant de 1 500 jetons. Le système alloue les 1 500 jetons restants à l’historique des conversations et à l’entrée. L’historique des conversations est ensuite condensé pour s’adapter à l’espace restant, ce qui garantit que le modèle ne dépasse jamais les 2 800 jetons.
Actions d’invite
Les plans permettent au modèle d’effectuer des actions ou de répondre à l’utilisateur. Vous pouvez créer un schéma du plan et ajouter une liste d’actions que vous prenez en charge pour effectuer une action et passer des arguments. Le point de terminaison OpenAI détermine les actions à utiliser, extrait toutes les entités et les transmet en tant qu’arguments à l’appel d’action.
The following is a conversation with an AI assistant.
The assistant can turn a light on or off.
context:
The lights are currently {{getLightStatus}}.
Modèle d’invite
Le modèle d’invite est un moyen simple et puissant de définir et de composer des fonctions IA à l’aide de texte brut. Vous pouvez utiliser le modèle d’invite pour créer des invites en langage naturel, générer des réponses, extraire des informations, appeler d’autres invites ou effectuer toute autre tâche qui peut être exprimée avec du texte.
Le langage prend en charge les fonctionnalités qui vous permettent d’inclure des variables, d’appeler des fonctions externes et de passer des paramètres à des fonctions. Vous n’avez pas besoin d’écrire de code ou d’importer des bibliothèques externes, il vous suffit d’utiliser les accolades {{...}} pour incorporer des expressions dans vos invites. Teams analyse votre modèle et exécute la logique qui le sous-tend. De cette façon, vous pouvez facilement intégrer l’IA dans vos applications avec un minimum d’effort et une flexibilité maximale.
{{function}}
: appelle une fonction inscrite et insère sa chaîne de valeur de retour.{{$input}}
: insère le texte du message. Il obtient sa valeur à partir de state.temp.input.{{$state.[property]}}
: insère les propriétés d’état.
Actions
Les actions gèrent les événements déclenchés par des composants IA.
FlaggedInputAction
et FlaggedOutputAction
sont les gestionnaires d’actions intégrés pour gérer les indicateurs de modérateur. Si le modérateur signale une entrée de message entrant, le modérateur redirige vers le FlaggedInputAction
gestionnaire et envoie context.sendActivity
un message à l’utilisateur sur l’indicateur. Si vous souhaitez arrêter l’action, vous devez ajouter AI.StopCommandName
.
// Register other AI actions
app.ai.action(
AI.FlaggedInputActionName,
async (context: TurnContext, state: ApplicationTurnState, data: Record<string, any>) => {
await context.sendActivity(`I'm sorry your message was flagged: ${JSON.stringify(data)}`);
return AI.StopCommandName;
}
);
app.ai.action(AI.FlaggedOutputActionName, async (context: TurnContext, state: ApplicationTurnState, data: any) => {
await context.sendActivity(`I'm not allowed to talk about such things.`);
return AI.StopCommandName;
});
Inscrire des gestionnaires d’actions
Les gestionnaires d’actions aident les utilisateurs à atteindre les objectifs, qui sont partagés dans les intentions de l’utilisateur.
L’un des aspects clés des gestionnaires d’actions est que vous devez d’abord inscrire les actions dans les invites, puis aider l’utilisateur à atteindre l’objectif.
Vous devez inscrire un gestionnaire pour chaque action répertoriée dans l’invite et ajouter un gestionnaire pour traiter les actions inconnues.
Dans l’exemple suivant d’un bot léger, nous avons l’action LightsOn
, LightsOff
et Pause
. Chaque fois qu’une action est appelée, vous retournez un string
. Si vous avez besoin que le bot retourne l’heure, vous n’avez pas besoin d’analyser l’heure et de la convertir en nombre. La PauseParameters
propriété garantit qu’elle retourne l’heure au format numérique sans interrompre l’invite.
public class LightBotActions
{
[Action("LightsOn")]
public async Task<string> LightsOn([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] AppState turnState)
{
turnState.Conversation!.LightsOn = true;
await turnContext.SendActivityAsync(MessageFactory.Text("[lights on]"));
return "the lights are now on";
}
[Action("LightsOff")]
public async Task<string> LightsOff([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] AppState turnState)
{
turnState.Conversation!.LightsOn = false;
await turnContext.SendActivityAsync(MessageFactory.Text("[lights off]"));
return "the lights are now off";
}
[Action("Pause")]
public async Task<string> LightsOff([ActionTurnContext] ITurnContext turnContext, [ActionParameters] Dictionary<string, object> args)
{
// Try to parse entities returned by the model.
// Expecting "time" to be a number of milliseconds to pause.
if (args.TryGetValue("time", out object? time))
{
if (time != null && time is string timeString)
{
if (int.TryParse(timeString, out int timeInt))
{
await turnContext.SendActivityAsync(MessageFactory.Text($"[pausing for {timeInt / 1000} seconds]"));
await Task.Delay(timeInt);
}
}
}
return "done pausing";
}
[Action("LightStatus")]
public async Task<string> LightStatus([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] AppState turnState)
{
await turnContext.SendActivityAsync(ResponseGenerator.LightStatus(turnState.Conversation!.LightsOn));
return turnState.Conversation!.LightsOn ? "the lights are on" : "the lights are off";
}
[Action(AIConstants.UnknownActionName)]
public async Task<string> UnknownAction([ActionTurnContext] TurnContext turnContext, [ActionName] string action)
{
await turnContext.SendActivityAsync(ResponseGenerator.UnknownAction(action ?? "Unknown"));
return "unknown action";
}
}
}
Si vous utilisez sequence
ou monologue
tools
une augmentation, il est impossible pour le modèle d’halluciner un nom de fonction, un nom d’action ou les paramètres corrects non valides. Vous devez créer un fichier d’actions et définir toutes les actions que l’invite doit prendre en charge pour l’augmentation. Vous devez définir les actions pour indiquer au modèle quand effectuer l’action. L’augmentation de séquence convient aux tâches qui nécessitent plusieurs étapes ou une logique complexe.
L’augmentation de monologue est adaptée aux tâches qui nécessitent une compréhension et une génération du langage naturel, ainsi qu’une plus grande flexibilité et créativité.
Dans l’exemple suivant d’un bot léger, le actions.json
fichier contient une liste de toutes les actions que le bot peut effectuer :
[
{
"name": "LightsOn",
"description": "Turns on the lights"
},
{
"name": "LightsOff",
"description": "Turns off the lights"
},
{
"name": "Pause",
"description": "Delays for a period of time",
"parameters": {
"type": "object",
"properties": {
"time": {
"type": "number",
"description": "The amount of time to delay in milliseconds"
}
},
"required": [
"time"
]
}
}
]
-
name
: nom de l’action. Obligatoire. -
description
: description de l’action. Optional. -
parameters
: ajoutez un objet de schéma JSON des paramètres requis.
La boucle de commentaires est la réponse d’un modèle pour valider, corriger ou affiner la réponse à votre question. Si vous utilisez une sequence
augmentation, vous pouvez désactiver la boucle pour vous protéger contre tout bouclage accidentel des manières suivantes :
- Vous pouvez définir sur
allow_looping?
false
dans laAIOptions
définition. - Vous pouvez définir sur
max_repair_attempts
0
dans leindex.ts
fichier.
Gérer l’historique
Vous pouvez utiliser les MaxHistoryMessages
arguments et MaxConversationHistoryTokens
pour permettre à la bibliothèque IA de gérer automatiquement votre historique.
Boucle de commentaires
Une boucle de commentaires vous permet de surveiller et d’améliorer les interactions du bot au fil du temps, ce qui aboutit à des applications plus efficaces et conviviales. Les commentaires reçus peuvent être utilisés pour apporter des ajustements et des améliorations, garantissant que le bot répond de manière cohérente aux besoins et aux attentes des utilisateurs.
Une boucle de commentaires se compose des éléments suivants :
Réparer Loop : si la réponse du modèle ne répond pas aux attentes, une boucle de réparation est déclenchée. L’historique des conversations duplique, ce qui permet au système d’essayer différentes solutions sans affecter la main conversation.
Validation : la validation vérifie la réponse corrigée. S’il réussit la validation, le système défork la conversation et réinsécrit la structure réparée dans la conversation main.
Apprendre des erreurs : une fois que le modèle voit un exemple de comportement correct, il apprend à éviter de faire des erreurs similaires à l’avenir.
Gérer les commandes complexes : une fois que le modèle a appris de ses erreurs, il devient capable de gérer des commandes plus complexes et de retourner le plan souhaité.