Partilhar via


Compreender a biblioteca de IA do Teams

A biblioteca de IA do Teams suporta JavaScript e simplifica a criação de bots que podem interagir com o Microsoft Teams. Também facilita a migração de bots existentes para utilizar funcionalidades com tecnologia de IA. Suporta a migração de funcionalidades de mensagens, extensões de mensagens e Cartões Ajustáveis para o novo formato. Também pode atualizar as suas aplicações existentes do Teams com estas funcionalidades.

Anteriormente, utilizou o SDK do BotBuilder para criar bots para o Teams. A biblioteca de IA do Teams foi concebida para facilitar este processo e inclui suporte de IA. Inicialmente, pode atualizar o bot sem IA, mas após a atualização, pode ligar-se a IA ou a Modelos de Linguagem Grande (LLMs) disponíveis na biblioteca de IA.

Com a biblioteca de IA do Teams, pode concentrar-se em:

Processadores de atividade

A biblioteca de IA do Teams suporta os seguintes processadores de atividade:

Tem de utilizar a biblioteca de IA para estruturar o bot e os processadores de Cartões Ajustáveis ao ficheiro de origem. Nas secções subsequentes, utilizámos os exemplos da biblioteca de IA para explicar cada capacidade e o caminho para a migração.

Enviar ou receber mensagem

Pode enviar e receber mensagens com o Bot Framework. A aplicação escuta mensagens de utilizador, elimina o estado da conversação após o recibo e responde. Também monitoriza o número de mensagens numa conversação e faz eco da mensagem do utilizador com a contagem.

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

Extensões de mensagens

No SDK do TeamsActivityHandlerBot Framework, configure o processador de consultas extensões de mensagens ao expandir os métodos do processador. A aplicação escuta ações de pesquisa e o item toca. Formata os resultados da pesquisa como Cartões de Destaque a apresentar informações do pacote e apresenta-os na extensão de mensagens.

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

Capacidades de Cartões Ajustáveis

Registe os processadores de ações do Cartão Ajustável com a app.adaptiveCards propriedade . A aplicação escuta mensagens com static ou dynamic palavras-chave e devolve um Cartão Ajustável com StaticMessageHandler() ou DynamicMessageHandler(). Também escuta consultas de uma pesquisa dinâmica card e submeter botões.

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

Lógica do bot para processar uma ação

O bot responde à entrada do utilizador com a ação LightsOn para acender as luzes.

O exemplo seguinte mostra como a biblioteca de IA do Teams permite gerir a lógica do bot para processar uma ação LightsOn ou LightsOff ligá-la ao pedido utilizado com o 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 da extensão de mensagem

A biblioteca de IA do Teams fornece uma forma mais intuitiva de criar processadores para comandos de consulta de extensão de mensagens, trabalhando em conjunto com o SDK do Teams Bot Framework existente.

Segue-se um exemplo de como pode estruturar o código para processar uma consulta de extensão de mensagem para o 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
            };

Intenções para ações

Uma interface simples para ações e predições permite que os bots reajam com confiança. A presença ambiente ajuda os bots a aprender a intenção, a utilizar pedidos com base na lógica de negócio e a gerar respostas. Com a biblioteca de IA do Teams, o pedido descreve as ações do bot e fornece exemplos.

O histórico de conversações permite um diálogo natural, como adicionar cereais à lista de mercearias, seguido de também adicionar café, indicando que o café deve ser adicionado à lista.

Segue-se uma conversação com um assistente de IA. O assistente de IA pode gerir listas e reconhece os seguintes comandos:

  • DO <action> <optional entities>
  • DIGA <response>

Estas ações são suportadas:

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

Todas as entidades são parâmetros necessários para ações.

  • Nomes de lista atuais:

    {{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
    
    
  • Histórico de conversações:

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

    Human: {{activity.text}} 
    
  • Nomes de lista atuais:

    {{conversation.listNames}}
    
  • IA: a lógica do bot é simplificada para incluir processadores para ações como addItem e removeItem. Esta distinção entre ações e os pedidos serve como uma ferramenta avançada, uma vez que orienta a IA para executar as ações e os pedidos.

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

Próxima etapa