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:
- Compreender a função do processador de atividades na gestão de conversações.
- Conceber a lógica do bot para respostas inteligentes.
- Integrar o Processamento de Linguagem Natural (NLP) para traduzir intenções de utilizador para ações.
Processadores de atividade
A biblioteca de IA do Teams suporta os seguintes processadores de atividade:
- Enviar ou receber mensagem
- Funcionalidades da extensão de mensagens (ME)
- Capacidades de Cartões Ajustáveis
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 TeamsActivityHandler
Bot 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
eremoveItem
. 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";
}