使用 API 插件创建声明性代理
通过将作添加到声明性代理,可以允许它检索和更新存储在外部系统中的数据。 将代理连接到组织中使用的外部系统允许使用代理来支持业务流程。 以下部分介绍了使用作扩展声明性代理所涉及的不同元素。
声明性代理
声明性代理可以包括一个或多个作,这些作允许它们与外部系统实时交互。 通过作,代理可以读取和修改存储在外部应用程序中的数据。 作通过 API 插件连接到 API。 代理使用 actions 数组在清单中定义其 作 :
{
"$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.0/schema.json",
"version": "v1.0",
"name": "Il Ristorante",
"description": "Order the most delicious Italian dishes and drinks from the comfort of your desk.",
"instructions": "$[file('instruction.txt')]",
"actions": [
{
"id": "menuPlugin",
"file": "ai-plugin.json"
}
]
}
可以通过将 元素添加到 actions 数组来定义 作 。 每个元素使用 ID 唯一标识作,并使用 文件 属性来引用项目中描述 API 插件的单独插件定义文件。
插件定义
插件定义文件描述了声明性代理用于与 API 通信的 API 插件。 插件定义由几个部分组成,例如基本信息、函数和运行时。
基本信息
每个插件定义文件都包含有关插件的基本信息,例如其名称和说明。 以下代码片段显示了基本插件信息的示例:
{
"$schema": "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.1/schema.json",
"schema_version": "v2.1",
"namespace": "ilristorante",
"name_for_human": "Il Ristorante",
"description_for_human": "See the today's menu and place orders",
"description_for_model": "Plugin for getting the today's menu, optionally filtered by course and allergens, and placing orders",
"functions": [
],
"runtimes": [
],
"capabilities": {
"localization": {},
"conversation_starters": []
}
}
name_for_human和description_for_human属性的内容纯粹是信息性的。 description_for_model 属性很重要,因为代理使用它来确定是否应针对用户的提示调用插件。 如果看到代理未针对特定提示调用插件,则应检查模型说明是否包含代理认为相关的必要信息。
另一个重要属性是命名空间,该 命名空间 是必需的,代理使用该命名空间来消除不同插件的作的歧义。 如果将其删除或提供与架构不匹配的无效值,可能会阻止代理使用插件。 命名空间必须与以下正则表达式 ^[A-Za-z0-9_]+匹配,这意味着它必须包含至少一个字符,例如 A-Z、 a-z、 0-9或 _。 任何其他字符都无效。
函数
插件定义的下一部分是 函数。 函数定义 API 插件可执行的一个或多个 API作,并指示代理如何显示从 API 接收的数据。 以下代码片段显示了一个示例函数:
{
"functions": [
{
"name": "getDishes",
"description": "Returns information about the dishes on the menu. Can filter by course (breakfast, lunch or dinner), name, allergens, or type (dish, drink).",
"capabilities": {
"response_semantics": {
"data_path": "$.dishes",
"properties": {
"title": "$.name",
"subtitle": "$.description"
},
"static_template": {
...trimmed for brevity
}
}
}
}
]
}
每个函数由多个元素组成。
名称
名称唯一地标识 API 插件中的作,并且该作必须与相关 API 规范中的 operationId 完全匹配。 如果指定的名称与任何作都不匹配,Microsoft 365 Agents Toolkit 在生成项目时会引发错误。 如果部署的名称与 operationId 不匹配的函数,则代理无法调用该函数。
说明
代理使用 说明 将函数与用户的提示相匹配。 描述函数时,请务必说明它完成的任务,包括任何变体,例如筛选或排序信息。 如果说明不准确或不完整,则代理无法将其与特定提示进行匹配,并且无法调用 函数。
响应语义
response_semantics 属性指示代理应如何显示从 API 接收的数据。 它由三个属性组成: data_path、 properties 和 static_template。
如果 API 返回复杂的数据结构,并且你希望代理仅显示其特定部分,则使用 data_path 属性指定指向 API 响应相关部分的 JSON 路径表达式。 请考虑以下 API 响应:
{
"dishes": [
{
"id": 1,
"name": "Classic Italian Frittata",
"description": "A fluffy omelette filled with sautéed mushrooms, onions, and melted pecorino, served with a side of roasted cherry tomatoes.",
"image_url": "https://raw.githubusercontent.com/pnp/copilot-pro-dev-samples/main/samples/da-ristorante-api/assets/frittata.jpeg",
"price": 8.99,
"allergens": [
"eggs",
"dairy"
],
"course": "breakfast",
"type": "dish"
},
...trimmed for brevity
]
}
你希望代理显示的数据位于 dishes 属性中,这就是为什么将 data_path 属性设置为 $.dishes JSONPath 表达式,该表达式引用由 $表示的根对象的 dishes 属性。
响应语义的下一部分是 属性。 使用属性,可以告诉代理 API 响应中的哪个数据属性表示项的属性,例如标题、说明或 URL。 当 API 返回多个项时,代理使用语义映射在答复中包含最相关的信息。 请考虑以下语义映射:
{
"response_semantics": {
"properties": {
"title": "$.name",
"subtitle": "$.description"
}
}
}
代理响应时,会生成如下答案:
对于每道菜,代理都包含一个粗体标题,后跟说明。 由于映射不包含 URL 或敏感度标签,因此代理在其响应中不包含它们。
响应语义的最后一部分是 static_template。 使用静态模板定义一个自适应卡片模板,代理应使用该模板来显示来自 API 的数据。
提示
若要详细了解如何将自适应卡片模板与 API 插件配合使用,请参阅本学习模块末尾的“更多资源”部分中 的“使用自适应卡片在声明性代理的 API 插件中显示数据 ”学习模块。
运行时
插件定义的最后一部分是 运行时。 运行时描述插件使用哪些 API,以及哪些函数属于哪个 API。 以下代码片段显示了运行时定义:
{
"type": "OpenApi",
"auth": {
"type": "None"
},
"spec": {
"url": "apiSpecificationFile/ristorante.yml"
},
"run_for_functions": [
"getDishes",
"placeOrder"
]
}
首先定义 API 说明的类型。 目前,API 插件仅支持 OpenAPI。
接下来,定义 API 是匿名的还是需要身份验证。 身份验证类型 None 表示代理可以匿名调用 API。 如果需要与受保护的 API 通信,请相应地更新值,以匹配 API 的身份验证机制。 有关支持的身份验证机制的详细信息,请参阅文档。
提示
若要详细了解如何将 API 插件连接到安全 API,请参阅本学习模块末尾的“更多资源”部分中 的“使用安全 API 验证声明性代理的 API 插件” 学习模块。
在下一个名为 spec 的部分中,提供对本地 API 规范文档的引用,该文档介绍了 API 插件可以使用的 API。 使用 url 属性,可以指定项目中文件的相对路径。
最后一部分是 run_for_functions 属性,它指定哪些指定函数属于此 API。
提示
生成项目时,Microsoft 365 Agents Toolkit 会验证此属性中指定的函数是否与函数节中定义的函数匹配,否则会失败并显示错误。 Microsoft 365 代理工具包检查项目的一致性可提供早期反馈,并帮助你防止难以调试的错误。
API 规范
每个 API 插件的一个重要部分是 API 规范,它提供有关 API 的重要信息,包括:
- API 所在的位置。
- 如果 API 需要身份验证,如果是,则以何种方式进行身份验证。
- API 支持哪些作。
- 对于每个作,需要哪些数据以及响应方式。
当代理加载 API 插件时,它将使用所有这些信息来生成 API 请求、调用 API 并处理其响应。 因此,必须清楚地描述所有参数和属性,以便代理了解如何使用它们来满足用户的请求。
如果计划使用现有 API,请确保仅包含计划在 API 插件中使用的 API 规范部分。 如果包括整个 API 规范,但假设只使用一个或两个作,则使代理更难分析大型 API 规范中的相关信息。
提示
如果需要使用现有 API 规范的一部分,请考虑使用 Hidi。 它是由 Microsoft 构建的工具,可用于轻松提取 API 规范的相关部分以及所有相关实体。 有关详细信息,请参阅本学习模块的末尾。
代理支持 YAML 和 JSON 中的 OpenAPI API 规范。
提示
生成供 API 插件使用的自定义 API 并从本地计算机运行时,需要将其公开到 Internet,以便代理可以调用它。 可以使用 开发隧道 公开 API,这是Microsoft创建的用于在 Internet 上共享本地服务的工具。 如果使用 Microsoft 365 代理工具包通过 API 插件生成代理,它不仅会自动启动开发隧道,还会自动更新 API 规范中的 API URL,使你能够专注于生成解决方案。
如何组合在一起
现在,你已了解具有 API 插件的声明性代理由哪些不同元素组成,接下来让我们看看它们如何组合在一起。 下图显示了不同元素之间的关系。
使用 Microsoft Teams 应用打包和分发代理。 每个 Teams 应用可以包含一个或多个声明性代理,每个代理都针对特定方案进行优化。 代理可以包含零个或多个允许其与外部系统通信的 API 插件,具体取决于其用途。 插件定义一个或多个函数。 每个函数执行一个特定任务,并恰好引用一个 API作。 在函数旁边,API 插件引用一个或多个 API 规范,用于描述它使用的 API。 在其轮次,每个 API 规范定义了插件可以通过其函数使用的一个或多个作。