Общие сведения о библиотеке ИИ Teams
Библиотека ИИ Teams поддерживает JavaScript и упрощает создание ботов, которые могут взаимодействовать с Microsoft Teams. Это также упрощает миграцию существующих ботов для использования функций на основе ИИ. Он поддерживает перенос сообщений, расширения сообщений и адаптивных карточек в новый формат. Вы также можете обновить существующие приложения Teams с помощью этих функций.
Ранее вы использовали пакет SDK BotBuilder для создания ботов для Teams. Библиотека ИИ Teams предназначена для упрощения этого процесса и включает поддержку ИИ. Изначально вы можете обновить бот без ИИ, но после обновления он может подключаться к ИИ или крупным языковым моделям (LLM), доступным в библиотеке ИИ.
С помощью библиотеки ИИ Teams можно сосредоточиться на:
- Общие сведения о роли обработчика действий в управлении беседами.
- Разработка логики бота для интеллектуальных ответов.
- Интеграция обработки естественного языка (NLP) для преобразования намерений пользователей в действия.
Обработчики действий
Библиотека ИИ Teams поддерживает следующие обработчики действий:
- Отправка или получение сообщения
- Возможности расширения сообщений (ME)
- Возможности адаптивных карточек
Необходимо использовать библиотеку ИИ для формирования шаблонов бота и обработчиков адаптивных карточек в исходный файл. В последующих разделах мы использовали примеры из библиотеки ИИ , чтобы объяснить каждую возможность и путь к миграции.
Отправка или получение сообщения
Вы можете отправлять и получать сообщения с помощью 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 настройте обработчик запросов расширений сообщений, расширив методы обработчика. Приложение прослушивает действия поиска и касания элементов. Он форматирует результаты поиска как карточки главного героя, отображая сведения о пакете, и отображает их в расширении обмена сообщениями.
// 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.
Ниже приведен пример структуры кода для обработки запроса расширения сообщения для 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
};
Намерения действий
Простой интерфейс для действий и прогнозов позволяет ботам уверенно реагировать. Внешнее присутствие помогает ботам изучать намерения, использовать запросы на основе бизнес-логики и генерировать ответы. С помощью библиотеки ИИ Teams в командной строке описываются действия бота и приводятся примеры.
Журнал бесед обеспечивает естественный диалог, например добавление хлопьев в список продуктов, а затем добавление кофе, указывающее, что кофе должен быть добавлен в список.
Ниже приведен диалог с помощник ИИ. ИИ помощник может управлять списками и распознает следующие команды:
- ДЕЛАТЬ
<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 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