Общие сведения о протоколе активности

Протокол активности — это стандартный коммуникационный протокол, используемый во многих SDK, службах и клиентах Майкрософт. Протокол активности используется в Microsoft 365 Copilot, Microsoft Copilot Studio, Microsoft Teams и Пакете SDK агентов Microsoft 365. Протокол активности определяет структуру Activity и то, как сообщения, события и взаимодействия передаются из канала в ваш код и во все точки между ними. Агенты могут подключаться к одному или нескольким каналам для взаимодействия с пользователями и работы с другими агентами. Протокол активности стандартизирует протокол взаимодействия с любым клиентом, включая клиенты Майкрософт и сторонние клиенты, чтобы не создавать отдельную логику для каждого канала.

Что такое активность?

Activity — это структурированный JSON-объект, который представляет любое взаимодействие между пользователем и вашим агентом. Активности не ограничиваются текстовыми сообщениями. Они могут включать различные виды взаимодействия, такие как события (например, присоединение или выход пользователя для клиентов с поддержкой нескольких пользователей), индикаторы ввода текста, загрузку файлов, действия карточек и пользовательские события, созданные разработчиками.

Каждая активность содержит метаданные о следующем:

  • Кто ее отправил (отправитель)
  • Кто должен ее получить (получатель)
  • Контекст разговора
  • Канал, откуда она происходит
  • Тип взаимодействия
  • Полезные данные

Схема активности — ключевые свойства

В данной спецификации определяется протокол активности: Activity Protocol - Activity. Некоторые ключевые свойства протокола активности:

Свойство Описание
Id Обычно генерируется каналом, если активность инициирована каналом
Type Тип определяет назначение активности, например тип сообщения
ChannelID ChannelID указывает на канал, из которого произошла данная активность. Например: msteams.
From Отправитель активности (который может быть пользователем или агентом)
Recipient Предполагаемый получатель активности
Text Текстовое содержимое сообщения
Attachment Контент, такой как карточки, изображения и файлы

Доступ к данным активности

Для выполнения действий из объекта TurnContext разработчикам необходимо получать доступ к данным внутри активности.

Класс TurnContext есть в каждой языковой версии Пакета SDK агентов Microsoft 365:

Примечание

Фрагменты кода в этой статье написаны на C#. Синтаксис и структура API для версий JavaScript и Python схожи.

TurnContext — ключевой объект, используемый на каждом ходу разговора в Пакете SDK агентов Microsoft 365. Он предоставляет доступ к входящей активности, методам отправки ответов, управлению состоянием диалога и контексту, необходимому для обработки одного хода разговора. Используйте его для поддержания контекста, отправки соответствующих ответов и эффективного взаимодействия с пользователями в их клиенте или канале. Каждый раз, когда ваш агент получает новую активность из канала, Пакет SDK агентов создает новый экземпляр TurnContext и передает его вашим зарегистрированным обработчикам или методам. Этот контекстный объект существует в течение одного хода разговора и автоматически удаляется после его завершения.

Ход определяется как полный цикл сообщения, отправленного клиентом и доставленного вашему коду. Ваш код обрабатывает эти данные и при необходимости может отправить ответ для завершения хода. Этот цикл можно разделить на следующие шаги:

  1. Входящая активность: пользователь отправляет сообщение или выполняет действие, создающее активность.

  2. Ваш код получает активность, а агент обрабатывает ее с помощью TurnContext.

  3. Ваш агент отправляет одну или несколько активностей обратно.

  4. Ход заканчивается, и TurnContext удаляется.

Можно получить доступ к данным из TurnContext, например:

var messageText = turnContext.Activity.Text;
var channelID = turnContext.Activity.ChannelId;

Этот фрагмент кода демонстрирует пример полного хода:

agent.OnActivity(ActivityTypes.Message, async (turnContext, turnState, cancellationToken) =>
{
    var userMessage = turnContext.Activity.Text;
    var response = $"you said: {userMessage}";
    await turnContext.SendActivityAsync(MessageFactory.Text(response), cancellationToken);
});

Внутри класса TurnContext обычно содержится следующая ключевая информация:

  • Activity: основной способ получения информации из активности
  • Adapter: канальный адаптер, который создал объект Activity
  • TurnState: состояние хода

Типы действий

Тип активности определяет, какие требования или ожидания предъявляются к клиентам, пользователям и агентам.

К ним относятся:

  • Сообщение
  • ConversationUpdate
  • Событие
  • Вызов
  • Ввод с клавиатуры

Сообщение

Распространенным типом активности является Message (тип объекта Activity). Этот тип объекта Activity тип может включать текст, вложения и предлагаемые действия.

agent.OnActivity(ActivityTypes.Message, async (turnContext, turnState, cancellationToken) =>
{
    var userMessage = turnContext.Activity.Text;
    var response = $"you said: {userMessage}";
    await turnContext.SendActivityAsync(MessageFactory.Text(response), cancellationToken);
});

ConversationUpdate

Тип ConversationUpdate объекта Activity уведомляет вашего агента, когда участники присоединяются к разговору или покидают его. Не все клиенты поддерживают данное уведомление, однако Microsoft Teams поддерживает его.

Следующий фрагмент кода приветствует новых участников в разговоре:

agent.OnActivity(ActivityTypes.ConversationUpdate, async (turnContext turnState, cancellationToken) =>
{
    var membersAdded = turnContext.Activity.MembersAdded
    if (membersAdded != null)
    {
        foreach (var member in membersAdded)
        {
            if (member.Id != turnContext.Activity.Recipient.Id)
            {
                await turnContext.SendActivityAsync(MessageFactory.Text($"Welcome {member.Name}!"), cancellationToken);
            }
        }
    }
})

События

Тип Event объекта Activity представляет собой пользовательское событие, которое каналы или клиенты используют для отправки структурированных данных вашему агенту. Эти данные не предопределены в Activityструктуре полезных данных.

Вам нужно создать метод или обработчик маршрута для конкретного типа Event. Затем управляйте нужной логикой, основываясь на следующем:

  • Имя: имя события или идентификатор от клиента
  • Значение: полезные данные события, обычно представляющие собой объект JSON
agent.OnActivity(ActivityTypes.Event, async (turnContext turnState, cancellationToken) =>
{
    var eventName = turnContext.Activity.Name;
    var eventValue = turnContext.Activity.Value;

    // custom event (E.g. a switch on eventName)
});

Вызов

Тип Invoke объекта Activity — это особый тип активности, который клиент инициирует у агента для выполнения команды или операции. Это не просто сообщение. Примеры таких видов активностей часто встречаются в Microsoft Teams для task/fetch и task/submit. Не все каналы поддерживают данные типы активностей.

Ввод с клавиатуры

Тип Typing объекта Activity — это категория активности, указывающая на то, что кто-то печатает сообщение в беседе. Такую активность часто можно увидеть в диалогах между людьми, например в клиенте Microsoft Teams. Активности типа Typing поддерживаются не во всех клиентах. В частности, активности ввода текста не поддерживает Microsoft 365 Copilot.

await turnContext.SendActivityAsync(new Activity { Type = ActivityTypes.Typing }, cancellationToken); 
await Task.Delay(2000);
await turnContext.SendActivityAsync(MessageFactory.Text("Here is your answer..."), cancellationToken);

Создание и отправка активностей

Для отправки ответов TurnContext предоставляет несколько методов для отправки ответов пользователю.

agent.OnActivity(ActivityTypes.Message, async (turnContext, turnState, cancellationToken))
{
    await turnContext.SendActivityAsync("hello!", cancellationToken: CancellationToken); // uses string directly
    await turnContext.SendActivityAsync(MessageFactory.Text("Hello"), cancellationToken); // uses Message Factory
    await turnContext.SendActivitiesAsync(activities, cancellationToken); // send multiple activities in an Activity array
}

Работа с вложениями

Агенты часто работают с вложениями, которые отправляют пользователи (или даже другие агенты). Клиент отправляет активность Message, включающую вложение (это не отдельный тип активности). Ваш код должен обработать получение сообщения с вложением, прочитать метаданные и безопасно получить файл по URL-адресу, предоставленному клиентом. Обычно вы переносите файл в свое хранилище.

Получение вложения

Следующий код показывает, как получить вложение.

agent.OnActivity(ActivityTypes.Message, async(turnContext, turnState, cancellationToken)) =>
{
    var activity = turnContext.Activity;
    if (activity.Attachments != null && activity.Attachments.Count > 0)
    {
        foreach (var attachment in activity.Attachments)
        {
            // get metadata as required e.g. attachment.ContextType or attachment.ContentUrl
            // use the URL to securely download the attachment and complete your business logic
        };
    }
}

Обычно, чтобы получить документ, связанный с вложением, клиент отправляет аутентифицированный запрос GET для получения реального содержимого. У каждого адаптера есть свой способ получить эти данные. Например, Teams, OneDrive и т.п. Также важно понимать, что такие URL-адреса обычно имеют короткий срок действия, поэтому не стоит считать, что они будут действительны долгое время. Именно из-за этого ограничения стоит использовать собственное хранилище, если вам нужно будет обратиться к содержимому позже.

Цитаты

Важно понимать, что Attachment и Citation — это не один и тот же тип объекта. Клиенты, такие как Microsoft Teams, обрабатывают цитаты по-разному. Они используют свойство Entities объектаActivity. Вы можете добавить цитаты с помощью activity.Entities.Add и добавить новый объект Entity с конкретным определением Citation в зависимости от вашего клиента. Он сериализуется как JSON-объект, который клиент затем десериализует в зависимости от способа его отображения в клиенте. По сути, вложения — это сообщения, а цитаты могут ссылаться на вложения и являются еще одним объектом, отправляемым в составе полезных данных Entities из Activity.

Учет специфики каналов

Пакет SDK агентов Microsoft 365 построен как хаб, который разработчики используют для создания агентов, способных работать с любым клиентом, включая поддерживаемые нами клиенты. Он предоставляет разработчикам инструменты для создания собственного канального адаптера на основе одного и того же фреймворка. Эта архитектура предоставляет разработчикам широкий спектр возможностей при работе с агентами и обеспечивает расширяемость для клиентов, которые могут подключаться к этому хабу, включая такие Microsoft Teams, Slack и т. д.

Разные каналы имеют разные возможности и ограничения.

Вы можете определить канал, из которого вы получили активность, проверив свойство channelId в Activity.

Каналы включают специфические данные, которые не соответствуют стандартным полезным данным Activity, используемым во всех каналах. Вы можете получить доступ к этим данным из свойства TurnContext.[Activity.ChannelData](/dotnet/api/microsoft.agents.core.models.activity.channeldata), приведя их к переменным для использования в своем коде.

В следующих разделах приведены рекомендации по работе с распространенными клиентами.

Microsoft Teams

  • Поддерживает насыщенные адаптивные карточки с расширенными функциями.
  • Поддерживает обновления и удаление сообщений.
  • Имеет специфические данные канала для функций Teams, таких как упоминания и информация о собраниях.
  • Поддерживает активности Invoke для модулей задач.

Microsoft 365 Copilot

  • В основном ориентирована на активности Message.
  • Поддерживает цитаты и ссылки в ответах.
  • Требует потоковых ответов.
  • Ограниченная поддержка насыщенных карточек и адаптивных карточек.

Веб-чат/DirectLine

Веб-чат — это HTTP-протокол, который агенты могут использовать для общения по HTTPS.

  • Полная поддержка всех типов активностей.
  • Поддерживает пользовательские данные канала.

Каналы, предоставляемые не Майкрософт

К таким каналам относятся Slack, Facebook и другие.

  • Поддержка отдельных типов активностей может быть ограничена.
  • Карточки могут отрисовываться по-другому или не поддерживаться.
  • Всегда сверяйтесь с документацией по конкретному каналу.

Следующие шаги