Compartir por


Introducción a la biblioteca de inteligencia artificial de Teams

La biblioteca de inteligencia artificial de Teams simplifica el proceso para crear aplicaciones inteligentes de Microsoft Teams mediante los componentes de inteligencia artificial. Proporciona API para acceder a datos y manipularlos, así como una variedad de controles y componentes para crear interfaces de usuario personalizadas.

Puede integrar fácilmente la biblioteca de IA de Teams, la administración de mensajes y la moderación de seguridad en las aplicaciones y mejorar la experiencia del usuario. También facilita la creación de bots que usan una clave de API de OpenAI o Azure OpenAI para proporcionar una experiencia conversacional controlada por IA.

Configuración inicial

La biblioteca de inteligencia artificial de Teams se basa en bot framework SDK y usa sus aspectos básicos para ofrecer una extensión a las funcionalidades del SDK de Bot Framework. Como parte de la configuración inicial, es importante importar las funcionalidades del SDK de Bot Framework.

Nota:

La clase de adaptador que controla la conectividad con los canales se importa desde Bot Framework SDK.

Referencia de código de ejemplo

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>());

Importar biblioteca de IA de Teams

Importe todas las clases de @microsoft/teams-ai para compilar el bot y use las funcionalidades de la biblioteca de inteligencia artificial de Teams.

Referencia de código de ejemplo

// import Teams AI library
import {
    AI,
    Application,
    ActionPlanner,
    OpenAIModerator,
    OpenAIModel,
    PromptManager,
    TurnState
} from '@microsoft/teams-ai';
import { addResponseFormatter } from './responseFormatter';
import { VectraDataSource } from './VectraDataSource';

Creación de componentes de inteligencia artificial

Agregue funcionalidades de inteligencia artificial a la aplicación existente o a una nueva aplicación de Bot Framework.

OpenAIModel: la clase OpenAIModel proporciona una manera de acceder a la API de OpenAI o a cualquier otro servicio, que se adhiere al formato REST de OpenAI. Es compatible con los modelos de lenguaje OpenAI y Azure OpenAI.

Administrador de mensajes: el administrador de mensajes administra la creación de mensajes. Llama a funciones e inserta desde el código en el símbolo del sistema. Copia el estado de la conversación y el estado de usuario en el símbolo del sistema automáticamente.

ActionPlanner: ActionPlanner es el componente principal que llama al modelo de lenguaje grande (LLM) e incluye varias características para mejorar y personalizar el modelo. Es responsable de generar y ejecutar planes en función de la entrada del usuario y las acciones disponibles.

Referencia de código de ejemplo.

    // 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
    );

Definición del almacenamiento y la aplicación

El objeto de aplicación administra automáticamente la conversación y el estado del usuario del bot.

  • Almacenamiento: cree un proveedor de almacenamiento para almacenar la conversación y el estado del usuario del bot.

  • Aplicación: la clase de aplicación tiene toda la información y la lógica del bot necesarias para una aplicación. Puede registrar acciones o controladores de actividad para la aplicación en esta clase.

Referencia de código de ejemplo

 return new TeamsLightBot(new()
    {
        Storage = sp.GetService<IStorage>(),
        AI = new(planner),
        LoggerFactory = loggerFactory,
        TurnStateFactory = () =>
        {
            return new AppState();
        }
    });

TurnStateFactory permite crear una clase de estado personalizada para la aplicación. Puede usarlo para almacenar información adicional o lógica que necesita para el bot. También puede invalidar algunas de las propiedades predeterminadas del estado de turno, como la entrada del usuario, la salida del bot o el historial de conversaciones. Para usar TurnStateFactory, debe crear una clase que extienda el estado de turno predeterminado y pase una función que cree una instancia de la clase al constructor de la aplicación.

Registro de orígenes de datos

Un origen de datos vectorial facilita la incorporación de RAG a cualquier símbolo del sistema. Puede registrar un origen de datos con nombre con el planificador y, a continuación, especificar los nombres de los orígenes de datos para aumentar el símbolo del sistema dentro del archivo del símbolo del config.json sistema. Los orígenes de datos permiten a la inteligencia artificial insertar información relevante de orígenes externos en el símbolo del sistema, como bases de datos vectoriales o búsqueda cognitiva. Puede registrar orígenes de datos con nombre con el planificador y, a continuación, especificar los nombres de los orígenes de datos que desean aumentar el símbolo del sistema en el archivo del símbolo del config.json sistema.

Referencia de código de ejemplo

// 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'),
}));

Incrustaciones

Una inserción es un tipo de vector generado por un LLM que representa un fragmento de texto. El texto podría ser una palabra, una oración o un documento completo. Dado que el modelo entiende la sintaxis y la semántica del lenguaje, la inserción puede capturar el significado semántico del texto en un formato compacto. Las incrustaciones se usan a menudo en tareas de procesamiento de lenguaje natural, como la clasificación de texto o el análisis de sentimiento, pero también se usan para la búsqueda.

El modelo para generar incrustaciones es diferente de los LLM fundamentales. Por ejemplo, OpenAI proporciona un modelo de inserción denominado text-embedding-ada-002, que devuelve una lista de 1536 números que representa el texto de entrada. El sistema crea incrustaciones para texto dentro de los documentos y las almacena en una base de datos vectorial. Ahora, desde nuestra aplicación chat, podemos implementar el patrón RAG recuperando primero los datos pertinentes sobre los documentos de la base de datos vectorial y, a continuación, aumentando el símbolo del sistema con esta información recuperada.


A continuación se muestra un ejemplo de VectraDataSource y 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 };
    }

}

Prompt

Los mensajes son fragmentos de texto que se pueden usar para crear experiencias conversacionales. Los mensajes se usan para iniciar conversaciones, formular preguntas y generar respuestas. El uso de mensajes ayuda a reducir la complejidad de la creación de experiencias conversacionales y a hacerlas más atractivas para el usuario.

Un nuevo sistema de aviso basado en objetos divide un símbolo del sistema en secciones y a cada sección se le puede proporcionar un presupuesto de tokens que sea un conjunto fijo de tokens o proporcional a los tokens restantes globales. Puede generar mensajes para las API de estilo Finalización de texto y Finalización de chat.

A continuación se indican algunas directrices para crear mensajes:

  • Proporcione instrucciones, ejemplos o ambos.
  • Proporcionar datos de calidad. Asegúrese de que hay suficientes ejemplos y revise los ejemplos. El modelo es lo suficientemente inteligente como para ver a través de errores ortográficos básicos y darle una respuesta, pero también podría suponer que la entrada es intencionada y podría afectar a la respuesta.
  • Compruebe la configuración del símbolo del sistema. La configuración de temperatura y top_p controla la determinismo del modelo en la generación de una respuesta. Un valor más alto, como 0,8, hace que la salida sea aleatoria, mientras que un valor inferior, como 0,2, hace que la salida se centre y determinista.

Cree una carpeta denominada prompts y defina los mensajes en la carpeta. Cuando el usuario interactúa con el bot escribiendo un mensaje de texto, el bot responde con una finalización de texto.

  • skprompt.txt: contiene el texto de las solicitudes y admite funciones y variables de plantilla. Defina todas las solicitudes de texto en el skprompt.txt archivo.

  • config.json: contiene la configuración del modelo de aviso. Proporcione la configuración adecuada para asegurarse de que las respuestas del bot estén alineadas con sus necesidades.

    Referencia de código de ejemplo

     {
        "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
         }
        }
      }
    

Parámetros de consulta

En la tabla siguiente se incluyen los parámetros de consulta:

Valor Descripción
model Identificador del modelo que se va a usar.
completion_type Tipo de finalización que desea usar para el modelo. Dado un aviso, el modelo devolverá una o varias finalizaciones previstas junto con las probabilidades de tokens alternativos en cada posición. Las opciones admitidas son chat y text. El valor predeterminado es chat.
include_history Valor Boolean. Si desea incluir el historial. Cada símbolo del sistema obtiene su propio historial de conversaciones independiente para asegurarse de que el modelo no se confunde.
include_input Valor Boolean. Si desea incluir la entrada del usuario en el símbolo del sistema. Cuántos tokens para el símbolo del sistema.
max_input_tokens Número máximo de tokens para la entrada. El número máximo de tokens admitidos es 4000.
max_tokens Número máximo de tokens que se generarán durante la finalización. El recuento de tokens del símbolo del sistema más max_tokens no puede superar la longitud del contexto del modelo.
temperature Qué temperatura de muestreo usar, entre 0 y 2. Valores más altos como 0.8 hacen que la salida sea más aleatoria, mientras que valores más bajos como 0.2 lo hacen más centrado y determinista.
top_p Alternativa al muestreo con temperatura, denominada muestreo de núcleo, donde el modelo tiene en cuenta los resultados de los tokens con top_p masa de probabilidad. Por lo tanto, 0,1 significa que solo se tienen en cuenta los tokens que componen la masa de probabilidad del 10 % superior.
presence_penalty Número entre -2.0 y 2.0. Los valores positivos penalizan los nuevos tokens en función de si aparecen en el texto hasta ahora, lo que aumenta la probabilidad del modelo de hablar de nuevos temas.
frequency_penalty Número entre -2.0 y 2.0. Los valores positivos penalizan los nuevos tokens en función de su frecuencia existente en el texto hasta ahora, lo que reduce la probabilidad de que el modelo repita la misma línea textualmente.
stop_sequences Hasta cuatro secuencias en las que la API deja de generar más tokens. El texto devuelto no contendrá la secuencia de detención.
augmentation_type Tipo de aumento. Los valores admitidos son sequence, monologue y tools.

Administración de mensajes

La administración de mensajes ayuda a ajustar el tamaño y el contenido del mensaje enviado al modelo de lenguaje, teniendo en cuenta el presupuesto de tokens disponible y los orígenes de datos o los aumentos.

Si un bot tiene un máximo de 4 000 tokens donde 2800 tokens son para entrada y 1000 tokens para salida, el modelo puede administrar la ventana de contexto general y asegurarse de que nunca procesa más de 3 800 tokens. El modelo comienza con un texto de aproximadamente 100 tokens, agrega en el origen de datos de otros 1.200 tokens y, a continuación, examina el presupuesto restante de 1.500 tokens. El sistema asigna los 1500 tokens restantes al historial de conversaciones y la entrada. A continuación, el historial de conversaciones se condensa para ajustarse al espacio restante, lo que garantiza que el modelo nunca supere los 2.800 tokens.

Acciones de solicitud

Los planes permiten al modelo realizar acciones o responder al usuario. Puede crear un esquema del plan y agregar una lista de acciones que admita para realizar una acción y pasar argumentos. El punto de conexión de OpenAI determina las acciones necesarias para usarse, extrae todas las entidades y las pasa como argumentos a la llamada a la acción.

The following is a conversation with an AI assistant.
The assistant can turn a light on or off.

context:
The lights are currently {{getLightStatus}}.

Plantilla de solicitud

La plantilla de aviso es una manera sencilla y eficaz de definir y redactar funciones de inteligencia artificial mediante texto sin formato. Puede usar la plantilla de solicitud para crear mensajes de lenguaje natural, generar respuestas, extraer información, invocar otros mensajes o realizar cualquier otra tarea que se pueda expresar con texto.

El lenguaje admite características que permiten incluir variables, llamar a funciones externas y pasar parámetros a las funciones. No es necesario escribir ningún código ni importar ninguna biblioteca externa, solo tiene que usar las llaves {{...}} para insertar expresiones en los mensajes. Teams analiza la plantilla y ejecuta la lógica subyacente. De este modo, puede integrar fácilmente la inteligencia artificial en sus aplicaciones con un esfuerzo mínimo y la máxima flexibilidad.

  • {{function}}: llama a una función registrada e inserta su cadena de valor devuelto.

  • {{$input}}: inserta el texto del mensaje. Obtiene su valor de state.temp.input.

  • {{$state.[property]}}: inserta propiedades de estado.

Acciones

Las acciones controlan los eventos desencadenados por los componentes de IA.

FlaggedInputAction y FlaggedOutputAction son los controladores de acción integrados para controlar las marcas de moderador. Si el moderador marca una entrada de mensaje entrante, el moderador redirige al FlaggedInputAction controlador y context.sendActivity envía un mensaje al usuario sobre la marca. Si desea detener la acción, debe agregar AI.StopCommandName.

Referencia de código de ejemplo

// 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;
});

Registrar controladores de acciones

Los controladores de acciones ayudan a los usuarios a lograr los objetivos, que se comparten en las intenciones del usuario.

Uno de los aspectos clave de los controladores de acciones es que primero debe registrar las acciones en los mensajes y, a continuación, ayudar al usuario a lograr el objetivo.

Debe registrar un controlador para cada acción que aparece en el símbolo del sistema y también agregar un controlador para tratar con acciones desconocidas.

En el ejemplo siguiente de un bot ligero, tenemos la LightsOnacción , LightsOffy Pause . Cada vez que se llama a una acción, se devuelve .string Si necesita que el bot devuelva el tiempo, no es necesario analizar la hora y convertirla en un número. La PauseParameters propiedad garantiza que devuelve el tiempo en formato de número sin pausar el aviso.

Referencia de código de ejemplo

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 usa sequence, monologue o tools el aumento, es imposible que el modelo halle un nombre de función, un nombre de acción o los parámetros correctos no válidos. Debe crear un nuevo archivo de acciones y definir todas las acciones que desea que el símbolo del sistema admita para el aumento. Debe definir las acciones para indicar al modelo cuándo realizar la acción. El aumento de secuencias es adecuado para tareas que requieren varios pasos o lógica compleja. El aumento de monólogos es adecuado para tareas que requieren comprensión y generación de lenguaje natural, y más flexibilidad y creatividad.

En el ejemplo siguiente de un bot ligero, el actions.json archivo tiene una lista de todas las acciones que el bot puede realizar:

[
    {
        "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: nombre de la acción. Obligatorio.
  • description: descripción de la acción. Opcional.
  • parameters: agregue un objeto de esquema JSON de los parámetros necesarios.

El bucle de comentarios es la respuesta de un modelo para validar, corregir o refinar la respuesta a la pregunta. Si usa un sequence aumento, puede deshabilitar el bucle para protegerse contra cualquier bucle accidental de las siguientes maneras:

  • Puede establecer en allow_looping?false en la AIOptions definición.
  • Puede establecer en max_repair_attempts0 en el index.ts archivo.

Administrar historial

Puede usar los MaxHistoryMessages argumentos y MaxConversationHistoryTokens para permitir que la biblioteca de inteligencia artificial administre automáticamente el historial.

Retroalimentación

Un bucle de comentarios le permite supervisar y mejorar las interacciones del bot a lo largo del tiempo, lo que conduce a aplicaciones más eficaces y fáciles de usar. Los comentarios recibidos se pueden usar para realizar ajustes y mejoras, lo que garantiza que el bot satisfaga de forma coherente las necesidades y expectativas del usuario.

Un bucle de comentarios consta de lo siguiente:

Reparar Loop: si la respuesta del modelo no cumple las expectativas, desencadena un bucle de reparación. El historial de conversaciones bifurca, lo que permite al sistema probar varias soluciones sin afectar a la conversación principal.

Validación: la validación comprueba la respuesta corregida. Si pasa correctamente la validación, el sistema desforza la conversación y vuelve a insertar la estructura reparada en la conversación principal.

Aprender de los errores: una vez que el modelo ve un ejemplo de comportamiento correcto, aprende a evitar cometer errores similares en el futuro.

Controlar comandos complejos: una vez que el modelo ha aprendido de sus errores, se vuelve capaz de controlar comandos más complejos y devolver el plan deseado.

Paso siguiente