Partager via


Fonctionnalités de la bibliothèque IA Teams

La bibliothèque IA Teams prend en charge JavaScript et est conçue pour simplifier le processus de création de bots capables d’interagir avec Microsoft Teams et faciliter la migration des bots existants. La bibliothèque IA prend en charge la migration des fonctionnalités de messagerie, des fonctionnalités d’extension de message (ME) et des fonctionnalités de cartes adaptatives vers le nouveau format. Il est également possible de mettre à niveau des applications Teams existantes avec ces fonctionnalités.

Auparavant, vous utilisiez le Kit de développement logiciel (SDK) BotBuilder directement pour créer des bots pour Microsoft Teams. La bibliothèque d’IA Teams est conçue pour faciliter la construction de bots capables d’interagir avec Microsoft Teams. Bien que l’une des principales fonctionnalités de la bibliothèque d’IA Teams soit la prise en charge de l’IA que les clients peuvent utiliser, l’objectif initial peut être de mettre à niveau leur bot actuel sans IA. Après la mise à niveau, le bot peut se connecter à l’IA ou aux modèles de langage volumineux (LLM) disponibles dans la bibliothèque IA.

La bibliothèque IA Teams prend en charge les fonctionnalités suivantes :

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 la section suivante, 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 l’utilisateur pour envoyer un message et lorsqu’elle reçoit ce message, elle supprime l’état de la conversation et renvoie un message à l’utilisateur. L’application effectue également le suivi du nombre de messages reçus dans une conversation et renvoie le message de l’utilisateur avec le nombre de messages reçus jusqu’à présent.

 // 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, vous deviez configurer 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, et met en forme les résultats de la recherche sous la forme d’une liste de HeroCards affichant des informations de package. Le résultat est utilisé pour afficher les résultats de la recherche 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

Vous pouvez inscrire des gestionnaires d’actions de carte adaptative à l’aide de la app.adaptiveCards propriété . L’application écoute les messages contenant les mots clés static ou et dynamic retourne une carte adaptative à l’aide des StaticMessageHandler méthodes ou DynamicMessageHandler . L’application écoute également les requêtes à partir d’une carte de recherche dynamique et les boutons Envoyer sur les cartes adaptatives.

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

Fonctionnalités principales

Logique de bot pour la gestion d’une action

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

L’exemple suivant illustre 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 IA Teams vous offre une approche plus intuitive pour créer des gestionnaires pour différentes commandes de requête d’extension de message par rapport aux itérations précédentes du Kit de développement logiciel (SDK) Teams Bot Framework. Le nouveau KIT de développement logiciel (SDK) fonctionne en même temps que le Kit de développement logiciel (SDK) Teams Bot Framework existant.

Voici un exemple de la façon dont vous pouvez structurer leur 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 lorsqu’ils ont une grande confiance en l’action. 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.

Grâce à notre bibliothèque d’IA, l’invite doit simplement décrire les actions prises en charge par le bot et fournir un exemple en quelques plans de la façon d’utiliser ces actions. L’historique des conversations facilite un dialogue naturel entre l’utilisateur et le bot, comme ajouter des céréales à la liste des courses, puis ajouter du café, ce qui devrait indiquer que le café doit être ajouté à la liste des courses.

Voici une conversation avec un assistant IA. L’assistant IA est capable de 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 requis 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 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 séparation distincte entre les actions et les invites guidant l’IA sur la façon d’exécuter les actions et les invites sert d’outil puissant.

        [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