Compartir por


Funcionalidades de la biblioteca de inteligencia artificial de Teams

La biblioteca de inteligencia artificial de Teams admite JavaScript y está diseñada para simplificar el proceso de creación de bots que pueden interactuar con Microsoft Teams y facilita la migración de los bots existentes. La biblioteca de IA admite la migración de funcionalidades de mensajería, funcionalidades de extensión de mensajes (ME) y funcionalidades de tarjetas adaptables al nuevo formato. También es posible actualizar las aplicaciones de Teams existentes con estas características.

Anteriormente, usaba BotBuilder SDK directamente para crear bots para Microsoft Teams. La biblioteca de inteligencia artificial de Teams está diseñada para facilitar la construcción de bots que pueden interactuar con Microsoft Teams. Aunque una de las características clave de la biblioteca de inteligencia artificial de Teams es el soporte técnico de inteligencia artificial que los clientes pueden usar, el objetivo inicial podría ser actualizar su bot actual sin inteligencia artificial. Después de actualizar, el bot puede conectarse a IA o modelos de lenguaje grande (LLM) disponibles en la biblioteca de inteligencia artificial.

La biblioteca de inteligencia artificial de Teams admite las siguientes funcionalidades:

Debe usar la biblioteca de inteligencia artificial para aplicar scaffolding a los controladores de bot y tarjeta adaptable al archivo de origen.

En la sección siguiente, hemos usado los ejemplos de la biblioteca de inteligencia artificial para explicar cada funcionalidad y la ruta de acceso a la migración:

Envío o recepción de mensajes

Puede enviar y recibir mensajes mediante Bot Framework. La aplicación escucha al usuario para enviar un mensaje y, cuando recibe este mensaje, elimina el estado de la conversación y envía un mensaje de vuelta al usuario. La aplicación también realiza un seguimiento del número de mensajes recibidos en una conversación y devuelve el mensaje del usuario con un recuento de mensajes recibidos hasta ahora.

 // Listen for user to say "/reset" and then delete conversation state
    app.OnMessage("/reset", ActivityHandlers.ResetMessageHandler);

    // Listen for ANY message to be received. MUST BE AFTER ANY OTHER MESSAGE HANDLERS
    app.OnActivity(ActivityTypes.Message, ActivityHandlers.MessageHandler);

    return app;

Extensiones de mensajería

En el SDK de TeamsActivityHandlerBot Framework, necesitaba configurar el controlador de consultas de extensiones de mensaje mediante la extensión de métodos de controlador. La aplicación escucha las acciones de búsqueda y las pulsaciones de elementos, y da formato a los resultados de búsqueda como una lista de HeroCards que muestran información del paquete. El resultado se usa para mostrar los resultados de la búsqueda en la extensión de mensajería.

// Listen for search actions
    app.MessageExtensions.OnQuery("searchCmd", activityHandlers.QueryHandler);
    // Listen for item tap
    app.MessageExtensions.OnSelectItem(activityHandlers.SelectItemHandler);

    return app;

 // Format search results in ActivityHandlers.cs

            List<MessagingExtensionAttachment> attachments = packages.Select(package => new MessagingExtensionAttachment
            {
                ContentType = HeroCard.ContentType,
                Content = new HeroCard
                {
                    Title = package.Id,
                    Text = package.Description
                },
                Preview = new HeroCard
                {
                    Title = package.Id,
                    Text = package.Description,
                    Tap = new CardAction
                    {
                        Type = "invoke",
                        Value = package
                    }
                }.ToAttachment()
            }).ToList();

            // Return results as a list

            return new MessagingExtensionResult
            {
                Type = "result",
                AttachmentLayout = "list",
                Attachments = attachments
            };

Funcionalidades de tarjetas adaptables

Puede registrar controladores de acciones de tarjeta adaptable mediante la app.adaptiveCards propiedad . La aplicación escucha los mensajes que contienen las palabras clave static o dynamic y devuelve una tarjeta adaptable mediante los StaticMessageHandler métodos o DynamicMessageHandler . La aplicación también escucha las consultas de una tarjeta de búsqueda dinámica y envía botones en las tarjetas adaptables.

// Listen for messages that trigger returning an adaptive card
    app.OnMessage(new Regex(@"static", RegexOptions.IgnoreCase), activityHandlers.StaticMessageHandler);
    app.OnMessage(new Regex(@"dynamic", RegexOptions.IgnoreCase), activityHandlers.DynamicMessageHandler);

    // Listen for query from dynamic search card
    app.AdaptiveCards.OnSearch("nugetpackages", activityHandlers.SearchHandler);
    // Listen for submit buttons
    app.AdaptiveCards.OnActionSubmit("StaticSubmit", activityHandlers.StaticSubmitHandler);
    app.AdaptiveCards.OnActionSubmit("DynamicSubmit", activityHandlers.DynamicSubmitHandler);

    // Listen for ANY message to be received. MUST BE AFTER ANY OTHER HANDLERS
    app.OnActivity(ActivityTypes.Message, activityHandlers.MessageHandler);

    return app;

Funcionalidades principales

Lógica del bot para controlar una acción

El bot responde a la entrada del usuario con la acción LightsOn de encender las luces.

En el ejemplo siguiente se muestra cómo la biblioteca de inteligencia artificial de Teams permite administrar la lógica del bot para controlar una acción LightsOn o LightsOff conectarla al símbolo del sistema usado con OpenAI:

/ Create AI Model
if (!string.IsNullOrEmpty(config.OpenAI?.ApiKey))
{
    builder.Services.AddSingleton<OpenAIModel>(sp => new(
        new OpenAIModelOptions(config.OpenAI.ApiKey, "gpt-3.5-turbo")
        {
            LogRequests = true
        },
        sp.GetService<ILoggerFactory>()
    ));
}
else if (!string.IsNullOrEmpty(config.Azure?.OpenAIApiKey) && !string.IsNullOrEmpty(config.Azure.OpenAIEndpoint))
{
    builder.Services.AddSingleton<OpenAIModel>(sp => new(
        new AzureOpenAIModelOptions(
            config.Azure.OpenAIApiKey,
            "gpt-35-turbo",
            config.Azure.OpenAIEndpoint
        )
        {
            LogRequests = true
        },
        sp.GetService<ILoggerFactory>()
    ));
}
else
{
    throw new Exception("please configure settings for either OpenAI or Azure");
}

// Create the bot as transient. In this case the ASP Controller is expecting an IBot.
builder.Services.AddTransient<IBot>(sp =>
{
    // Create loggers
    ILoggerFactory loggerFactory = sp.GetService<ILoggerFactory>()!;

    // Create Prompt Manager
    PromptManager prompts = new(new()
    {
        PromptFolder = "./Prompts"
    });

    // Adds 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: sp.GetService<OpenAIModel>()!,
            prompts: prompts,
            defaultPrompt: async (context, state, planner) =>
            {
                PromptTemplate template = prompts.GetPrompt("sequence");
                return await Task.FromResult(template);
            }
        )
        { LogRepairs = true },
        loggerFactory: loggerFactory
    );

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

// LightBotActions defined in LightBotActions.cs
    
[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";
        }

Consulta de extensión de mensaje

La biblioteca de inteligencia artificial de Teams ofrece un enfoque más intuitivo para crear controladores para varios comandos de consulta de extensión de mensaje en comparación con iteraciones anteriores del SDK de Bot Framework de Teams. El nuevo SDK funciona junto con el SDK de Bot Framework de Teams existente.

A continuación se muestra un ejemplo de cómo puede estructurar su código para controlar una consulta de extensión de mensaje para el searchCmd comando .

// Listen for search actions
    app.MessageExtensions.OnQuery("searchCmd", activityHandlers.QueryHandler);
    // Listen for item tap
    app.MessageExtensions.OnSelectItem(activityHandlers.SelectItemHandler);

    return app;

 // Format search results
            List<MessagingExtensionAttachment> attachments = packages.Select(package => new MessagingExtensionAttachment
            {
                ContentType = HeroCard.ContentType,
                Content = new HeroCard
                {
                    Title = package.Id,
                    Text = package.Description
                },
                Preview = new HeroCard
                {
                    Title = package.Id,
                    Text = package.Description,
                    Tap = new CardAction
                    {
                        Type = "invoke",
                        Value = package
                    }
                }.ToAttachment()
            }).ToList();

            return new MessagingExtensionResult
            {
                Type = "result",
                AttachmentLayout = "list",
                Attachments = attachments
            };

Intenciones para acciones

Una interfaz sencilla para acciones y predicciones permite a los bots reaccionar cuando tienen alta confianza para realizar acciones. La presencia ambiental permite a los bots aprender la intención, usar mensajes basados en la lógica de negocios y generar respuestas.

Gracias a nuestra biblioteca de inteligencia artificial, el aviso solo necesita describir las acciones admitidas por el bot y proporcionar un ejemplo de cómo emplear esas acciones. El historial de conversaciones ayuda con un diálogo natural entre el usuario y el bot, como agregar cereales a la lista de comestibles, seguido de agregar también café, que debe indicar que el café se va a agregar a la lista de comestibles.

A continuación se muestra una conversación con un asistente de inteligencia artificial. El asistente de inteligencia artificial es capaz de administrar listas y reconoce los siguientes comandos:

  • HACER <action> <optional entities>
  • DECIR <response>

Además, admiten las siguientes acciones:

  • addItem list="<list name>" item="<text>"
  • removeItem list="<list name>" item="<text>"
  • summarizeLists

Todas las entidades son parámetros necesarios para las acciones.

  • Nombres de lista actuales:

    {{conversation.listNames}} 
    
    
    Examples:  
    
    Human: remind me to buy milk
    AI: DO addItem list="groceries" item="milk" THEN SAY Ok I added milk to your groceries list
    Human: we already have milk
    AI: DO removeItem list="groceries" item="milk" THEN SAY Ok I removed milk from your groceries list
    Human: buy ingredients to make margaritas
    AI: DO addItem list="groceries" item="tequila" THEN DO addItem list="groceries" item="orange liqueur" THEN DO addItem list="groceries" item="lime juice" THEN SAY Ok I added tequila, orange liqueur, and lime juice to your groceries list
    Human: do we have have milk
    AI: DO findItem list="groceries" item="milk"
    Human: what's in my grocery list
    AI: DO summarizeLists  
    Human: what's the contents of all my lists?
    AI: DO summarizeLists
    Human: show me all lists but change the title to Beach Party
    AI: DO summarizeLists
    Human: show me all lists as a card and sort the lists alphabetically
    AI: DO summarizeLists
    
    
  • Historial de conversaciones:

    {{conversation.(history}} 
    
  • Consulta actual:

    Human: {{activity.text}} 
    
  • Nombres de lista actuales:

    {{conversation.listNames}}
    
  • IA: la lógica del bot se simplifica para incluir controladores para acciones como addItem y removeItem. Esta separación distinta entre las acciones y las indicaciones que guían a la inteligencia artificial sobre cómo ejecutar las acciones y los avisos actúa como una herramienta eficaz.

        [Action("AddItem")]
        public string AddItem([ActionTurnState] ListState turnState, [ActionParameters] Dictionary<string, object> parameters)
        {
            ArgumentNullException.ThrowIfNull(turnState);
            ArgumentNullException.ThrowIfNull(parameters);

            string listName = GetParameterString(parameters, "list");
            string item = GetParameterString(parameters, "item");

            IList<string> items = GetItems(turnState, listName);
            items.Add(item);
            SetItems(turnState, listName, items);

            return "item added. think about your next action";
        }

        [Action("RemoveItem")]
        public async Task<string> RemoveItem([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] ListState turnState, [ActionParameters] Dictionary<string, object> parameters)
        {
            ArgumentNullException.ThrowIfNull(turnContext);
            ArgumentNullException.ThrowIfNull(turnState);
            ArgumentNullException.ThrowIfNull(parameters);

            string listName = GetParameterString(parameters, "list");
            string item = GetParameterString(parameters, "item");

            IList<string> items = GetItems(turnState, listName);

            if (!items.Contains(item))
            {
                await turnContext.SendActivityAsync(ResponseBuilder.ItemNotFound(listName, item)).ConfigureAwait(false);
                return "item not found. think about your next action";
            }

            items.Remove(item);
            SetItems(turnState, listName, items);
            return "item removed. think about your next action";
        }

Paso siguiente