Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Важно!
Подключаемые модули поддерживаются только в качестве действий внутри декларативных агентов. Они не включены в Microsoft 365 Copilot.
Подключаемые модули API могут использовать шаблоны ответов адаптивной карточки для улучшения ответа, который Microsoft 365 Copilot создает на основе ответа, полученного от API. Адаптивная карточка отображает цитаты в сгенерированном ответе.
Подключаемые модули API могут определить шаблон ответа адаптивной карточки двумя способами: как статический шаблон, определенный в манифесте подключаемого модуля, или как динамический шаблон, возвращаемый как часть отклика API. Разработчики подключаемого модуля определяют шаблоны с помощью схемы адаптивной карточки в сочетании с языком шаблонов адаптивных карточек.
Статические шаблоны ответов
Статические шаблоны ответов — хороший выбор, если API всегда возвращает элементы одного типа, а формат адаптивной карточки не нужно часто менять. Определите статический шаблон в static_template свойстве response_semantics объекта в манифесте плагина, как показано в следующем примере.
"functions": [
{
"name": "GetBudgets",
"description": "Returns details including name and available funds of budgets, optionally filtered by budget name",
"capabilities": {
"response_semantics": {
"data_path": "$",
"properties": {
"title": "$.name",
"subtitle": "$.availableFunds"
},
"static_template": {
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "Container",
"$data": "${$root}",
"items": [
{
"type": "TextBlock",
"text": "Name: ${if(name, name, 'N/A')}",
"wrap": true
},
{
"type": "TextBlock",
"text": "Available funds: ${if(availableFunds, formatNumber(availableFunds, 2), 'N/A')}",
"wrap": true
}
]
}
]
}
}
}
},
]
- Установите
response_semantics.data_pathдля свойства значение. This value is a [JSONPath query](https://www.rfc-editor.org/rfc/rfc9535) that indicates that the root of the JSON response contains the relevant data. Thestatic_template.body["$data"]property value is${$root}, which is Adaptive Card template language syntax to override any prior data scoping and break back to the root. Setting this value isn't strictly needed, since thedata_path' уже установлено в корневой каталог. - Свойство
textпервогоTextBlockиспользует синтаксис${if(name, name, 'N/A')}шаблона адаптивной карточки. Это ссылка на свойствоnameв ответе API. Функцияifопределяет, что еслиnameимеет значение, использовать это значение, в противном случае — использоватьN/A. - Свойство
textвторойTextBlockиспользует синтаксис${if(availableFunds, formatNumber(availableFunds, 2), 'N/A')}шаблона адаптивной карточки. Это ссылка на свойствоavailableFundsв ответе API. ФункцияformatNumberпреобразует число в строку с двумя десятичными знаками.
Рассмотрим этот статический шаблон и следующий ответ API.
[
{
"name": "Fourth Coffee lobby renovation",
"availableFunds": 12000
}
]
В результате этой комбинации будет создана следующая адаптивная карточка.
Шаблоны динамических ответов
Шаблоны динамических ответов являются хорошим выбором, если ваш API возвращает несколько типов. Динамические шаблоны позволяют назначать шаблон ответа каждому возвращаемому элементу. Один или несколько динамических шаблонов возвращаются как часть ответа API, а элементы данных в ответе указывают, какой шаблон следует использовать.
Чтобы использовать динамические шаблоны, укажите, какое свойство элементов данных указывает шаблон в свойстве response_semantics.properties.template_selector в манифесте подключаемого модуля API, как показано в этом примере.
{
"name": "GetTransactions",
"description": "Returns details of transactions identified from filters like budget name or category. Multiple filters can be used in combination to refine the list of transactions returned",
"capabilities": {
"response_semantics": {
"data_path": "$.transactions",
"properties": {
"template_selector": "$.displayTemplate"
}
}
}
}
В этом примере свойству data_path присвоено значение $.transactions, что указывает на то, что данные для карт находятся в свойстве transactions в корне ответа API. Свойству template_selector присвоено значение $.displayTemplate, что указывает на то, что свойство каждого элемента в массиве transactions , указывающее используемый шаблон, является свойством displayTemplate .
Свойство, указанное свойством template_selector , содержит запрос JSONPath для поиска шаблона элемента в ответе.
Рассмотрим этот шаблон и следующий ответ API.
{
"transactions": [
{
"budgetName": "Fourth Coffee lobby renovation",
"amount": -2000,
"description": "Property survey for permit application",
"expenseCategory": "permits",
"displayTemplate": "$.templates.debit"
},
{
"budgetName": "Fourth Coffee lobby renovation",
"amount": -7200,
"description": "Lumber and drywall for lobby",
"expenseCategory": "materials",
"displayTemplate": "$.templates.debit"
},
{
"budgetName": "Fourth Coffee lobby renovation",
"amount": 5000,
"description": "Additional funds to cover cost overruns",
"expenseCategory": null,
"displayTemplate": "$.templates.credit"
}
],
"templates": {
"debit": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"size": "medium",
"weight": "bolder",
"color": "attention",
"text": "Debit"
},
{
"type": "FactSet",
"facts": [
{
"title": "Budget",
"value": "${budgetName}"
},
{
"title": "Amount",
"value": "${formatNumber(amount, 2)}"
},
{
"title": "Category",
"value": "${if(expenseCategory, expenseCategory, 'N/A')}"
},
{
"title": "Description",
"value": "${if(description, description, 'N/A')}"
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
},
"credit": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"size": "medium",
"weight": "bolder",
"color": "good",
"text": "Credit"
},
{
"type": "FactSet",
"facts": [
{
"title": "Budget",
"value": "${budgetName}"
},
{
"title": "Amount",
"value": "${formatNumber(amount, 2)}"
},
{
"title": "Description",
"value": "${if(description, description, 'N/A')}"
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
}
}
- Свойство
transactionsв ответе содержит массив элементов. - Свойство
templatesявляется объектом, каждое свойство которого содержит шаблон адаптивной карточки. - Для
displayTemplateкаждого объекта в массивеtransactionsзадано значение или$.templates.debit$.templates.credit.
Сочетание манифеста этого подключаемого модуля и отклика API приводит к созданию следующих адаптивных карточек.
Запрет пустых адаптивных карточек, если массив в ответе API пуст
Адаптивные карточки могут отображаться пустыми, если свойство массива в ответе API пустое и шаблон не включает условную логику для обработки этого сценария.
В следующем примере показан ответ API, в котором recommendations массив не содержит элементов:
{"answer":"","recommendations":[],"followUpMessage":""}
В этом случае:
- В массиве "рекомендации" нет элементов.
- Шаблон адаптивной карточки пытается пройти по массиву, не проверяя, доступны ли данные.
Чтобы предотвратить отрисовку пустой карты, привяжите шаблон к правильному свойству массива и добавьте условную логику для управления отрисовкой.
Привяжите к массиву с помощью следующей команды data_path:
"data_path": "$.recommendations"
Перебирать объекты только при наличии данных:
{ "type": "ColumnSet", "$data": "${$root}", "$when": "${title != null && title != ''}" }
При необходимости предоставьте резервный текст, когда массив пуст:
{ "type": "TextBlock", "text": "No recommendations available", "$when": "${length($root) == 0}" }
Совет
Всегда проверяйте data_path и включайте $when условия для пустых массивов, чтобы избежать появления пустых адаптивных карточек.
Совместное использование статических и динамических шаблонов
Плагины могут сочетать использование как статических, так и динамических шаблонов. В этом сценарии статический шаблон действует как шаблон по умолчанию, который используется, если у элемента нет template_selector свойства или его значение не разрешается в шаблон в ответе API.
Добавление доменов в манифест приложения
Добавьте все домены, используемые адаптивной картой, в раздел validDomains манифеста приложения.
- При использовании
Action.OpenUrl, не забудьте включить домен целевого URL-адреса вvalidDomainsсвойство. Если домена нет в списке, Teams отображает сообщение URL-адрес может вести к ненадежному содержимому. - Домен URL-адресов изображений, возвращаемых подключаемым модулем API или декларативным агентом в ответе адаптивной карточки, должен быть указан в свойстве
validDomains. Если домена нет в списке, Microsoft 365 Copilot не отображает изображение.
Убедитесь в том, что адаптивные карточки реагируют в концентраторах Microsoft 365 Copilot
Адаптивные карточки должны быть спроектированы так, чтобы они реагировали на поверхности различных размеров. Такая конструкция обеспечивает удобное взаимодействие с пользователем независимо от используемого устройства или платформы. Для этого проверьте адаптивные карты в различных центрах Microsoft 365 Copilot, включая Teams, Word и PowerPoint. Кроме того, проверьте различную ширину окна просмотра, сократив и расширив пользовательский интерфейс Copilot. Этот процесс гарантирует оптимальную работу адаптивных карточек и предоставление единого интерфейса на всех платформах. Примените следующие рекомендации.
- По возможности избегайте использования многоколоночных макетов. Макеты с одним столбцом, как правило, хорошо отображаются даже в самых узких окнах просмотра.
- Не размещайте текст и изображение в одной строке, если только это не маленький значок или аватар.
- Не назначайте фиксированную ширину элементам внутри адаптивной карточки. Вместо этого позвольте им изменять размер в соответствии с шириной окна просмотра. Однако вы можете назначить фиксированную ширину небольшим изображениям, таким как значки и аватары.
Связанные материалы
- Конструктор адаптивных карточек для проектирования и тестирования адаптивных карточек в визуальном средстве.
- Документация по адаптивным карточкам
- Ссылка на манифест подключаемого модуля