创建或升级用于适用于 Microsoft 365 的 Copilot的消息扩展插件的指南

重要

  • 用于适用于 Microsoft 365 的 Microsoft Copilot的插件处于预览状态,仅适用于 Microsoft Teams 中的Microsoft 365 Chat。
  • 确保适用于 Microsoft 365 的 Copilot可供组织使用。 有两种方法可以获取 Copilot 的开发人员环境:
    • 具有 Copilot 的沙盒 Microsoft 365 租户 (通过 TAP 成员资格) 以有限预览版提供。
    • 具有适用于 Microsoft 365 的 Microsoft Copilot许可证的企业客户生产环境。

Microsoft 365 插件提供与各种 Microsoft 365 产品(如 Teams 和 Outlook)的集成。 集成可帮助用户在外部系统中搜索或创建内容。 消息扩展插件允许适用于 Microsoft 365 的 Microsoft Copilot通过机器人与其他软件和服务的 API 进行交互。 使用 适用于 Microsoft 365 的 Copilot,可以:

  • 搜索以获取最新信息或记录。 例如,最新的事件票证或调查结果。
  • 基于多个记录汇总信息。 例如,汇总与项目 Northwind 相关的所有事件票证。

建议生成或升级现有消息扩展,以在适用于 Microsoft 365 的 Copilot中最大化其有用性和可用性。 消息扩展必须支持一个或多个搜索命令,因为适用于 Microsoft 365 的 Copilot将其识别为可以代表用户执行的技能。 此外,扩展必须满足本文概述的合规性、性能、安全性和用户体验标准。

该图显示了 Microsoft Teams 与 适用于 Microsoft 365 的 Copilot (M365 聊天) 之间的用户体验。

强制性要求

为适用于 Microsoft 365 的 Copilot生成消息扩展插件的要求包括:

定义说明

良好的说明提供清晰简洁的应用功能摘要,并允许适用于 Microsoft 365 的 Copilot有效地发现和执行搜索操作。 当用户输入应用名称和谓词(例如 Find Contoso 票证)时,必须从 适用于 Microsoft 365 的 Copilot (M365 聊天) 调用消息扩展插件。

屏幕截图显示了传递方案,其中包含 M365 Chat 中消息扩展插件的示例提示示例。

屏幕截图显示了一个失败方案,其中没有示例示例提示将消息扩展作为 M365 Chat 中的插件。

确保遵循下表中列出的说明准则:

操作 Reason
反竞争:避免在简短和长说明中使用任何其他插件的名称。
负责任的 AI:避免使用不当或冒犯性的关键字。
提示注入:确保说明不会指导 Copilot 采取绕过应用程序正常功能的操作。 此外,说明不得包含指示它可以用作提示注入代码的符号或文本。 避免使用反复调用应用的短语、函数和代码。

应用说明

长篇和短的应用说明必须清晰明了,并定义了应用的范围。 若要在 适用于 Microsoft 365 的 Copilot 中将应用呈现为插件,请修改应用说明以满足以下插件要求:

  • 长说明必须清楚地说明 适用于 Microsoft 365 的 Copilot 中消息扩展插件的功能和用法。 例如,使用 适用于 Microsoft 365 的 Copilot 中的 Contoso 云搜索和汇总任务。
  • 简短说明必须以自然语言简要描述应用的功能,并且可以包含应用的名称。

下表列出了每个类别的简短说明示例:

说明:创建、搜索、查看票证、bug 和项目。

应用说明示例:

{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.13/MicrosoftTeams.schema.json",
  "version": "1.0.0",
  "manifestVersion": "1.13",
  "id": "2bxxxxc5-5xxx-4xxx-aXXX-94xxxx8919e5",
  "name": {
    "short": "Tasks",
    "full": "Contoso Tasks"
  },
  "description": {
    "short": "Create, search, view tickets, bugs, and projects",
    "full": "Contoso Tasks makes it easy to stay organized. Create, assign, and track tasks individually or collaboratively with your team, and see everything come together in one place."
  },

搜索命令说明

命令说明将用户意向和话语映射到插件内的搜索命令,并且必须基于对用户意向和关键字的分析生成。 搜索命令说明必须:

  • 重点介绍命令以自然语言 (详细列表) 搜索的内容和方式。
  • 包括谓词和同义词(如果适用)。
  • 关注本机应用的搜索功能中可能使用的关键字。

语义说明

semanticDescription 属性用于提供适用于 Microsoft 365 的 Copilot命令的详细说明。 命令的语义说明最多支持 5,000 个字符,并且不会显示在用户界面中。 如果 属性semanticDescription留空,适用于 Microsoft 365 的 Copilot将使用 字段中的信息description。 编写 时, semanticDescription必须包含有关命令的预期值、限制和范围的信息。

属性 semanticDescription 不是必填字段。 但是,如果在 semanticDescription 应用清单中添加,则对简短说明、参数说明和命令说明的现有验证检查也适用于语义说明。

建议查看以下语义说明指南,以提高应用通过 Microsoft Teams Store 提交过程的机会:

  • 避免使用说明性短语,例如“如果用户说 X”、“忽略”、“删除”、“重置”、“新说明”、“以粗体显示答案”或“不打印任何内容”。 [强制修复]
  • 避免使用 URL、表情符号或隐藏字符,例如十六进制、二进制或非常规符号。 [强制修复]
  • 避免语法和标点符号错误。 [强制修复]
  • 避免过于冗长、花朵或营销语言。 [建议的修复]
  • 避免使用“#1”、“amazing”或“best”等最高声明。 [建议的修复]

下表列出了每个类别的命令和语义说明示例:

说明:搜索与 Northwind 相关的高优先级任务,这些任务将于明天完成。

命令说明示例:

"commands": [
        {
          "id": "Search",
          "type": "query",
          "title": "Tasks",
          "description": "Search for high priority tasks related to Northwind that are due tomorrow.",
          "SemanticDescription": "Search for issues, epics, stories, tasks, sub tasks, bugs + additional details."
          "initialRun": true,
          "fetchTask": false,
          "context": [
            "commandBox",
            "compose",
            "message"
          ],

参数说明

每个消息扩展命令支持都有一个相应的“parameters”属性,该属性最多支持五个参数,并且第一个参数必须在消息扩展搜索栏中可见。 参数必须具有良好的说明,该说明必须包含可接受的参数、枚举、首字母缩略词和输出格式的组合。

semanticDescription 属性用于提供 Microsoft Copilot 命令的详细说明。 参数的语义说明最多支持 2,000 个字符,并且不会显示在用户界面中。 如果 属性 semanticDescription 留空,则 Copilot 将使用 字段中的信息 description 。 编写 时, semanticDescription必须包含有关命令的预期值、限制和范围的信息。

良好的参数说明以自然语言和输出格式解释系统的要求。 下面是每个类别的基本和高级搜索请求的几个示例:

基本搜索:搜索与 Northwind 相关的任务。
高级搜索:搜索明天到期的与 Northwind 相关的高优先级任务。

参数说明示例:

"parameters": [
    {
        "name": "Name",
        "title": "Project or Task Name",
        "description": "Project name or task name as keyword.",
        "inputType": "text"
    },
    {
        "name": "Time",
        "title": "Time",
        "description": "Date or number of days for which you need tasks for.",
        "semanticDescription": "Date or number of days for which you need tasks for. Output: Number",
        "inputType": "text"
    },
    {
        "name": "Priority",
        "title": "Priority",
        "description": "Priority of tasks.",
        "semanticDescription": "Priority of tasks. Acceptable values are high, medium, low, NA",
        "inputType": "text"
    }] 

复合言语

注意

M365 聊天不支持通过对话 (TeamsJS v1.x 中称为任务模块) 搜索。

对于 M365 聊天,基于搜索的消息扩展必须支持三个以上的唯一复合话语才能对准确信息执行深度检索。 若要启用复合陈述,必须通过更新 以前称为 Teams 应用清单的应用清单 () ,扩展搜索范围以处理三个或多个搜索参数,并确保满足以下条件:

  • 更新 Web 服务以支持基于多个参数的搜索。 有关如何响应用户请求的详细信息,请参阅 响应搜索命令

  • 适用于 Microsoft 365 的 Copilot可能会为不属于用户话语的参数传递空字符串或 null 值,请更新 Web 服务以处理参数。

  • 消息扩展最多支持 10 个命令 (9 个可用) 并且每个命令都有一个支持最多 5 个参数的相应 parameters 属性。


以下代码是应用清单中定义的多个参数的示例:
"commands": [
                {
                    "id": "inventorySearch",
                    "context": [
                        "compose",
                        "commandBox"
                    ],
                    "description": "Search products by name, category, inventory status, supplier location, stock level",
                    "title": "Product inventory",
                    "type": "query",
                    "parameters": [
                        {
                            "name": "productName",
                            "title": "Product name",
                            "description": "Enter a product name here",
                            "inputType": "text"
                        },
                        {
                            "name": "categoryName",
                            "title": "Category name",
                            "description": "Enter the category of the product",
                            "inputType": "text"
                        },
                        {
                            "name": "inventoryStatus",
                            "title": "Inventory status",
                            "description": "Enter what status of the product inventory. Possible values are 'in stock', 'low stock', 'on order', or 'out of stock'",
                            "inputType": "text"
                        },
                        {
                            "name": "supplierCity",
                            "title": "Supplier city",
                            "description": "Enter the supplier city of product",
                            "inputType": "text"
                        },
                        {
                            "name": "stockQuery",
                            "title": "Stock level",
                            "description": "Enter a range of integers such as 0-42 or 100- (for >100 items). Only use if you need an exact numeric range.",
                            "inputType": "text"
                        }
                    ]
                },
                {
                    "id": "discountSearch",
                    "context": [
                        "compose",
                        "commandBox"
                    ],
                    "description": "Search for discounted products by category",
                    "title": "Discounts",
                    "type": "query",
                    "parameters": [
                        {
                            "name": "categoryName",
                            "title": "Category name",
                            "description": "Enter the category to find discounted products",
                            "inputType": "text"
                        }
                    ]
                },
                {
                    "id": "revenueSearch",
                    "context": [
                        "compose",
                        "commandBox"
                    ],
                    "description": "Find products based on their revenue/period",
                    "title": "Revenue",
                    "type": "query",
                    "parameters": [
                        {
                            "name": "revenueRange",
                            "title": "Revenue range",
                            "description": "Enter 'high' or 'low' or enter a range of integers such as 0-10000 or 5000- using this exact format",
                            "inputType": "text"
                        }
                    ]
                }
            ]

屏幕截图显示了一个传递方案示例,其中 Northwind 应用返回海鲜和库存参数的响应。

搜索参数必须具有可接受的参数、枚举、首字母缩略词和输出格式的良好说明。 有关详细信息和示例,请参阅 参数说明

示例提示

属性 samplePrompts 指导用户如何使用 Copilot 中的各种插件。 Copilot 使用示例提示显示用户的提示。 提示必须能够适应不同的区域设置,并跨不同的命令清除。 适用于 Microsoft 365 的 Copilot的以下区域提供了示例提示:

  • 首次运行体验 (FRE) :当用户首次安装或启用插件时。
  • 提示库或Copilot Lab:当用户寻求有关提示的帮助时。
  • 插件建议:引导用户实现更好的话语。

屏幕截图显示当中的消息扩展插件在 Copilot 中启用时显示的示例提示。

注意

  • 如果应用清单未指定 samplePrompts 属性,则不会显示提示。
  • samplePrompts 应用提交过程中,属性对于应用验证是必需的。
  • 如果为应用定义多个命令,则最多向用户显示三个提示 (前三个命令中的每一个提示) 。 提示会轮换,以跨不同的命令为用户提供一组不同的提示。

建议遵循以下准则,以提高应用通过 Microsoft Teams Store 提交过程的机会:

  • 对于每个命令,插件必须至少有三个提示和最多五个提示。
  • 每个提示符不得超过 128 个字符。
  • 同一插件中的两个命令不能具有相同的提示。
  • 示例提示本质上必须是泛型的,并且不包含自定义引用。 例如,项目名称和任务名称。
  • 所有示例提示都必须正常运行并返回响应。
  • 提示必须与命令相关。

以下代码是应用清单中的 属性的示例 samplePrompts

"composeExtensions": [
	{
		"canUpdateConfiguration": true,
		"botId": "bxxxxxx5-xxxx-xxxx-xxxx-4xxxxxx16599",
		"commands": [
			{
				"id": "orders",
				"title": "Orders",
				"context": [
					"Commandbox",
					"Compose"
				],
				"description": "Search for orders",
				"semanticDescription": "Search for orders",
				"samplePrompts": [
					{
						"text": "Search for all orders"
					},
					{
						"text": "Search for orders related to Contoso"
					},
					{
						"text": "Search for all pending orders"
					},
					{
						"text": "Search for all completed ordered for Fabrikam"
					}
				]
			}
		]
	}
]

自适应卡片响应

消息扩展使用自适应卡片响应用户输入。 消息扩展插件的自适应卡片必须有效运行、显示丰富并满足以下要求:

  • 自适应卡片响应必须包含自适应卡片内容,并预览卡信息作为同一模板的一部分。 [必需]

    屏幕截图显示了示例应用的示例,其中显示了 M365 聊天应用响应在同一响应中包含预览和内容。


    自适应卡片响应模板示例
    {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.5",
        "body": [
          {
            "type": "Container",
            "items": [
              {
                "type": "TextBlock",
                "text": "${companyName}",
                "size": "Medium",
                "wrap": true,
                "style": "heading"
              },
              {
                "type": "TextBlock",
                "text": "${stockExchange} ${stockSymbol}",
                "isSubtle": true,
                "spacing": "None",
                "wrap": true
              },
              {
                "type": "TextBlock",
                "text": "${formattedDate} ${formattedTime}",
                "wrap": true
              }
            ]
          },
          {
            "type": "Container",
            "spacing": "None",
            "items": [
              {
                "type": "ColumnSet",
                "columns": [
                  {
                    "type": "Column",
                    "width": "stretch",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "${currentPrice} ",
                        "size": "ExtraLarge",
                        "wrap": true
                      },
                      {
                        "type": "TextBlock",
                        "text": "${priceChange} ${percentChange}",
                        "color": "${changeColor}",
                        "spacing": "None",
                        "wrap": true
                      }
                    ]
                  },
                  {
                    "type": "Column",
                    "width": "auto",
                    "items": [
                      {
                        "type": "FactSet",
                        "facts": [
                          {
                            "title": "Open",
                            "value": "${openPrice} "
                          },
                          {
                            "title": "High",
                            "value": "${highPrice} "
                          },
                          {
                            "title": "Low",
                            "value": "${lowPrice} "
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ],
        "previewCard": {
          "contentType": "application/vnd.microsoft.card.hero",
          "content": {
            "title": "${companyName}",
            "text": "${stockSymbol}"
          }
        }
      }
    
  • 除了信息的应用徽标、标题、缩略图和标题外,自适应卡片中的数据必须至少表示两条信息。 可以从最常搜索的属性(例如修改的数据、作者、状态和标志)中标识字段。 [必需]

    屏幕截图显示了自适应卡片响应中的信息标题、其他用户字段和操作按钮的示例。

  • 自适应卡片必须在桌面、Web 和移动 (iOS 和 Android) 中呈现。 [必需]

  • 自适应卡片必须包含至少一个操作按钮,但不超过四个操作按钮。 [必需]

    注意

    数据对象不支持操作类型 imBackmessageBack

    建议使用以下操作类型:

    • Action.OpenUrl:打开卡片中的指定 URL。
    • Action.ToggleVisibility:显示或隐藏卡中的一个或多个元素。
    • Action.Execute:收集输入字段,并将其作为请求发送到机器人服务。
    • Action.Submit:使用数据对象中的类型调用打开对话框或 Stageview。

    图形显示了 M365 聊天中自适应卡片响应中的“更新库存”、“重新入库”和“取消补货”操作按钮的示例。

  • 如果用户可以通过对话框、Stageview 或直接从卡更改有关卡的任何信息,我们建议使用自适应卡片来支持通用操作和自动刷新。 [推荐]

  • 自适应卡片必须包含 URL 作为 元数据的一部分,这允许将卡片从一个中心轻松复制到另一个中心。 [推荐]

  • 除缩略图外,自适应卡片中的任何图像都必须具有替换文字。 [推荐]

技术要求

对于要验证、调用和无缝工作的插件,请确保它满足以下条件:

标准 实现
清单版本 应用清单版本必须为 1.13 或更高版本。 [必需]
Microsoft 365 频道 若要让用户从 Outlook 与邮件扩展进行交互,你需要将 Microsoft 365 通道添加到机器人。 有关详细信息,请参阅 添加 Microsoft 365 通道。 [必需]
响应时间 99% 的响应时间不得超过 9 秒,75% 的响应时间不得超过 5 秒,50% 的响应时间不得超过 2 秒。 [必需]
可靠性 应用必须保持 99.9% 的可用性。 例如,如果Microsoft 365 Chat调用插件 1,000 次,它必须提供有意义的响应 999 次。 [必需]
零回归 如果需要重新提交应用进行验证,则之前工作的现有消息扩展功能不得中断。 此要求仅适用于独立软件供应商 (ISV) 应用,不适用于为组织构建的应用。 [必需]
单一登录 (SSO) 如果适用,请更新 SSO Microsoft Entra ID 应用注册。 [推荐]
内容安全策略 如果适用,请修改内容安全策略标头。 [推荐]

重要

如果适用,请根据配置内容安全策略标头 X-Frame-Options 更新 内容安全策略标头

代码示例

示例名称 Description TypeScript
Northwind 清单消息扩展 此示例演示如何在 适用于 Microsoft 365 的 Microsoft Copilot 中使用 Teams 消息扩展作为插件。 View

另请参阅