Возможности библиотеки ИИ Teams
Библиотека ИИ Teams поддерживает JavaScript и предназначена для упрощения процесса создания ботов, которые могут взаимодействовать с Microsoft Teams, и упрощает миграцию существующих ботов. Библиотека ИИ поддерживает перенос возможностей обмена сообщениями, возможностей расширения сообщений (ME) и адаптивных карточек в новый формат. С помощью этих функций можно также обновить существующие приложения Teams.
Ранее вы использовали пакет SDK BotBuilder непосредственно для создания ботов для Microsoft Teams. Библиотека ИИ Teams предназначена для упрощения создания ботов, которые могут взаимодействовать с Microsoft Teams. Хотя одной из ключевых функций библиотеки ИИ Teams является поддержка ИИ, которую клиенты могут использовать, начальной целью может быть обновление текущего бота без ИИ. После обновления бот может подключаться к ИИ или крупным языковым моделям (LLM), доступным в библиотеке ИИ.
Библиотека ИИ Teams поддерживает следующие возможности:
Необходимо использовать библиотеку ИИ для формирования шаблонов бота и обработчиков адаптивных карточек в исходный файл.
В следующем разделе мы использовали примеры из библиотеки ИИ , чтобы объяснить каждую возможность и путь к миграции:
Отправка или получение сообщения
Вы можете отправлять и получать сообщения с помощью Bot Framework. Приложение прослушивает отправку пользователем сообщения, а при получении этого сообщения удаляет состояние беседы и отправляет сообщение обратно пользователю. Приложение также отслеживает количество сообщений, полученных в беседе, и повторяет сообщение пользователя с количеством полученных сообщений.
// 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;
Расширения для обмена сообщениями
В пакете SDK TeamsActivityHandler
Bot Framework необходимо настроить обработчик запросов расширений сообщений, расширив методы обработчика. Приложение прослушивает действия поиска и касания элементов и форматирует результаты поиска в виде списка HeroCards, отображающих сведения о пакете. Результат используется для отображения результатов поиска в расширении обмена сообщениями.
// 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
};
Возможности адаптивных карточек
Обработчики действий адаптивной карточки app.adaptiveCards
можно зарегистрировать с помощью свойства . Приложение прослушивает сообщения с ключевыми словами static
или dynamic
и возвращает адаптивную карточку StaticMessageHandler
с помощью методов или DynamicMessageHandler
. Приложение также прослушивает запросы из динамического карта поиска, кнопки отправки на адаптивных карточках.
// 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;
Основные возможности
Логика бота для обработки действия
Бот реагирует на входные данные пользователя действием LightsOn
по включению света.
В следующем примере показано, как библиотека ИИ Teams позволяет управлять логикой бота для обработки действия LightsOn
или LightsOff
подключать ее к запросу, используемому с 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";
}
Запрос расширения сообщений
Библиотека ИИ Teams предлагает более интуитивно понятный подход к созданию обработчиков для различных команд запросов расширения сообщений по сравнению с предыдущими итерациями пакета SDK Для Teams Bot Framework. Новый пакет SDK работает вместе с существующим пакетом SDK Для Teams Bot Framework.
Ниже приведен пример того, как можно структурировать код для обработки запроса расширения сообщений для searchCmd
команды .
// 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
};
Намерения действий
Простой интерфейс для действий и прогнозов позволяет ботам реагировать, когда они имеют высокую уверенность в принятии действий. Внешнее присутствие позволяет ботам изучать намерения, использовать запросы на основе бизнес-логики и генерировать ответы.
Благодаря нашей библиотеке ИИ в запросе нужно только очертить действия, поддерживаемые ботом, и предоставить несколько примеров использования этих действий. Журнал бесед помогает в естественном диалоге между пользователем и ботом, например добавить хлопья в список продуктов, а затем добавить кофе, который должен указывать, что кофе должен быть добавлен в список продуктов.
Ниже приведен диалог с помощник ИИ. Помощник ИИ может управлять списками и распознает следующие команды:
- ДЕЛАТЬ
<action> <optional entities>
- СКАЗАТЬ
<response>
Поддерживаются следующие действия:
addItem list="<list name>" item="<text>"
removeItem list="<list name>" item="<text>"
summarizeLists
Все сущности являются обязательными параметрами для действий.
Имена текущих списков:
{{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
Журнал бесед:
{{conversation.(history}}
Текущий запрос:
Human: {{activity.text}}
Имена текущих списков:
{{conversation.listNames}}
ИИ. Логика бота оптимизирована для включения обработчиков для таких действий, как
addItem
иremoveItem
. Это четкое разделение между действиями и запросами, помогающее ИИ выполнять действия и запросы, служит мощным инструментом.
[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";
}
Следующее действие
Platform Docs