Partager via


Comprendre la bibliothèque d’IA Teams

La bibliothèque IA Teams prend en charge JavaScript et simplifie la création de bots capables d’interagir avec Microsoft Teams. Il facilite également la migration des bots existants pour utiliser des fonctionnalités basées sur l’IA. Il prend en charge la migration des fonctionnalités de messagerie, d’extension de message et de cartes adaptatives vers le nouveau format. Vous pouvez également mettre à niveau vos applications Teams existantes avec ces fonctionnalités.

Précédemment, vous avez utilisé le Kit de développement logiciel (SDK) BotBuilder pour créer des bots pour Teams. La bibliothèque IA Teams est conçue pour faciliter ce processus et inclut la prise en charge de l’IA. Au départ, vous pouvez mettre à niveau votre bot sans IA, mais après la mise à niveau, il peut se connecter à l’IA ou aux modèles LLM (Large Language Models) disponibles dans la bibliothèque IA.

Avec la bibliothèque d’IA Teams, vous pouvez vous concentrer sur :

Gestionnaires d’activités

La bibliothèque IA Teams prend en charge les gestionnaires d’activités suivants :

Vous devez utiliser la bibliothèque IA pour générer des modèles de bot et de gestionnaires de cartes adaptatives dans le fichier source. Dans les sections suivantes, nous avons utilisé les exemples de la bibliothèque IA pour expliquer chaque fonctionnalité et le chemin d’accès à la migration.

Envoyer ou recevoir un message

Vous pouvez envoyer et recevoir des messages à l’aide de Bot Framework. L’application écoute les messages utilisateur, supprime l’état de la conversation lors de la réception et répond. Il suit également le nombre de messages dans une conversation et renvoie le message de l’utilisateur avec le nombre.

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

Extensions de messages

Dans le Kit de développement logiciel (SDK) Bot TeamsActivityHandlerFramework, configurez le gestionnaire de requêtes Extensions de message en étendant les méthodes de gestionnaire. L’application écoute les actions de recherche et les appuis sur les éléments. Il met en forme les résultats de la recherche en tant que cartes héroïque affichant les informations du package et les affiche dans l’extension de messagerie.

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

Fonctionnalités des cartes adaptatives

Inscrivez les gestionnaires d’actions de carte adaptative à l’aide de la app.adaptiveCards propriété . L’application écoute les messages avec static des mots clés ou dynamic et retourne une carte adaptative à l’aide StaticMessageHandler() de ou DynamicMessageHandler(). Il écoute également les requêtes d’une recherche dynamique carte et les boutons d’envoi.

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

Logique de bot pour la gestion d’une action

Le bot répond à l’entrée de l’utilisateur avec l’action LightsOn pour allumer les lumières.

L’exemple suivant montre comment la bibliothèque IA Teams permet de gérer la logique du bot pour gérer une action LightsOn ou LightsOff de la connecter à l’invite utilisée avec 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";
        }

Requête d’extension de message

La bibliothèque d’IA Teams offre un moyen plus intuitif de créer des gestionnaires pour les commandes de requête d’extension de message, en collaboration avec le Kit de développement logiciel (SDK) Teams Bot Framework existant.

Voici un exemple de la façon dont vous pouvez structurer le code pour gérer une requête d’extension de message pour la searchCmd commande .

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

Intentions d’actions

Une interface simple pour les actions et les prédictions permet aux bots de réagir en toute confiance. La présence ambiante permet aux bots d’apprendre l’intention, d’utiliser des invites basées sur la logique métier et de générer des réponses. Avec la bibliothèque IA Teams, l’invite décrit les actions du bot et fournit des exemples.

L’historique des conversations permet un dialogue naturel, comme ajouter des céréales à la liste des courses, puis ajouter du café, indiquant que le café doit être ajouté à la liste.

Voici une conversation avec un assistant IA. L’ia assistant peut gérer les listes et reconnaît les commandes suivantes :

  • FAIRE <action> <optional entities>
  • DIRE <response>

Les actions suivantes sont prises en charge :

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

Toutes les entités sont des paramètres obligatoires pour les actions.

  • Noms de liste actuels :

    {{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 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
    
    
  • Historique des conversations :

    {{conversation.(history}} 
    
  • Requête actuelle :

    Human: {{activity.text}} 
    
  • Noms de liste actuels :

    {{conversation.listNames}}
    
  • IA : la logique du bot est rationalisée pour inclure des gestionnaires pour des actions telles que addItem et removeItem. Cette distinction entre les actions et les invites sert d’outil puissant car elle guide l’IA pour exécuter les actions et les invites.

        [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";
        }

Étape suivante