引文可建立对智能 智能 Microsoft 365 Copilot 副驾驶® 副驾驶®响应准确且扎实的信任。 响应正文自动包含 Copilot 合成响应的引文。 但是,最终用户可能无法打开信息源。 当 Copilot 基于公共 Web 内容的响应时,会自动引用该 URL。
对于来自 模型上下文协议 (MCP) 服务器 或 API 的内容,该内容必须返回最终用户可以打开和查看的 URL。 在插件定义中定义 response_semantics ,以便 Copilot 知道该 URL 在插件响应中的位置,并且可以使用正确的链接使引文可单击。
如果跳过此步骤,响应仍包含引文,但仅包含具有代表性的药丸或图标。 最终用户无法单击并确认站点中的数据。 这就是为什么可点击引文也是发布到应用商店的应用智能 智能 Microsoft 365 Copilot 副驾驶® 副驾驶®代理存储策略要求的原因。
Copilot 还可以从常见字段名称自动推断引文元数据,因此不再需要显式定义 response_semantics。 显式 response_semantics 在提供它们时仍优先。 在使用 动态工具发现时,依赖此动态回退特别有用,因为动态工具发现工具图面可在运行时更改。 有关详细信息,请参阅 动态响应语义。
重要
无需自适应卡片即可获取引文。 仅响应语义( data_path 加上几个 properties 映射)就足以让 Copilot 呈现指向源的可单击引文。
请考虑使用交互式 MCP 应用 来获取除引文之外的丰富 UX。
使用响应语义
插件清单中定义的响应语义充当 MCP 服务器或 API 与 Copilot 之间的协定。
工具返回 JSON。
在 插件清单中:
- 告知 Copilot citable 项在该 JSON 中的位置 (
data_path) 。 - 你告诉 Copilot 每个项上的哪些字段映射到引文的标题、副标题和 URL (
properties) 。
- 告知 Copilot citable 项在该 JSON 中的位置 (
Copilot 为每个项目呈现引文。 用户单击指向源。
如果提供显式 properties 映射,则 Copilot 会按原样使用它们。 仅当不存在这些映射时,动态推理才适用。 有关详细信息,请参阅 动态响应语义。
最低配置
配置 response_semantics 由工具响应的形状驱动,而不是由工具响应的协议驱动。 具有所有工具协议 (MCP、OpenAPI、消息扩展的 Copilot 代理) 使用相同的清单架构。
大多数工具响应分为以下两种形式之一:
- 结果数组 (类似于搜索工具) :该工具返回多个项,其中每个项应成为自己的引文。
- 单个对象 (类似于提取工具) :该工具只返回一个文档或记录,这将成为单个引文。
搜索样式) (结果数组
返回多个项的工具通常在 (或等效) 键下 results 返回数组,如以下示例所示。
{
"results": [
{
"id": "tr-001",
"title": "Forecasting AI adoption in the enterprise (2026)",
"url": "https://www.treyresearch.net/notes/ai-adoption-2026",
"publishedDate": "2026-03-12",
"thumbnailUrl": "https://www.treyresearch.net/assets/trey-research-logo.png"
},
{
"id": "tr-005",
"title": "Enterprise AI spend, deep dive",
"url": "https://www.treyresearch.net/notes/ai-spend",
"publishedDate": "2026-03-28",
"thumbnailUrl": "https://www.treyresearch.net/assets/trey-research-logo.png"
}
]
}
以下示例显示了插件清单中的最小响应语义配置。
"capabilities": {
"response_semantics": {
"data_path": "$.results",
"properties": {
"title": "$.title",
"subtitle": "$.publishedDate",
"url": "$.url"
}
}
}
属性 data_path 指向数组。 每个元素生成其自己的可单击引文。
properties JSONPath 是相对于每个数组元素而不是根元素解析的。
单个对象 (提取样式)
以下示例显示了一个响应,其中包含一条记录(一个文档、一个实体、一个文件)作为一个源引用。
{
"id": "tr-001",
"title": "Forecasting AI adoption in the enterprise (2026)",
"text": "Trey Research surveyed 412 enterprise CIOs across North America and EMEA between January and February 2026. We forecast that 64% of Fortune 500 firms will be running at least one production generative AI workload by end of 2026, up from 38% at the close of 2025...",
"url": "https://www.treyresearch.net/notes/ai-adoption-2026",
"publishedDate": "2026-03-12",
"thumbnailUrl": "https://www.treyresearch.net/assets/trey-research-logo.png",
"metadata": { "source": "trey-research", "category": "AI" }
}
以下示例显示了插件清单中的最小响应语义配置。
"capabilities": {
"response_semantics": {
"data_path": "$",
"properties": {
"title": "$.title",
"subtitle": "$.publishedDate",
"url": "$.url"
}
}
}
data_path设置为 $ 的属性选择根对象作为单个引文项。 每当工具返回一条记录时,这是正确的选择 - 即使记录包含嵌套字段(如 metadata)。
MCP 内容包装器
MCP 工具将其响应包装在一 content 系列 TextContentBlock 项中。 Copilot 将text每个块的字段分析为 JSON,然后针对分析的值应用 。data_path 字符串内 text 的形状是驱动配置(而不是外部 content 包装器)的驱动。
MCP 响应示例
{
"content": [
{
"type": "text",
"text": "{\"id\":\"tr-001\",\"title\":\"Forecasting AI adoption in the enterprise (2026)\",\"url\":\"https://www.treyresearch.net/notes/ai-adoption-2026\"}"
}
]
}
分析程序首先解包 text 有效负载,留下一个对象。 使用 单个对象 配置 ("data_path": "$") 。 返回字段中数组的 text MCP 搜索工具使用 结果配置数组 (data_path: "$.results") 。
动态响应语义 (零配置回退)
仅当工具稳定且不变时,显式 response_semantics 才有效。 通常情况并非如此:基于第三方 MCP 服务器构建的连接器会频繁更新其工具,因此,随着服务器的发展,你必须使清单保持同步。 当服务器更改但清单未更改时,结构化地面会无提示地回退到原始文本和引文停止呈现。
当清单省略显式 properties 映射时,Copilot 会根据已知别名的优先级列表扫描每个结果对象来推断引文字段。 这种零配置回退对于 动态工具发现特别有用,因为动态工具发现无法将清单固定到固定工具图面。
字段别名
对于每个引文字段,Copilot 按优先级顺序检查以下别名,并使用找到的第一个匹配项。
| 引文字段 | 优先级顺序) (别名 |
|---|---|
| URL |
display_url, displayUrl, web_url, webUrl, url, citation_url, citationUrl, reference_url, referenceUrl, website_url, websiteUrl, web_link, webLink, link, href |
| 标题 |
display_title, displayTitle, title, name, display_name, displayName, web_title, webTitle, subject, heading, caption |
| 副标题 |
subtitle, description, summary, snippet, source, provider, site_name, siteName, highlight |
| 缩略图 |
thumbnail_url, thumbnailUrl, thumbnail, image_url, imageUrl, logo_url, logoUrl, icon_url, iconUrl |
| 结果数组 |
results, items, data, value, records, entries |
解决规则
- URL 是硬性要求。 如果未找到非空 URL,则 Copilot 将跳过 元素并发出任何引文。
- 如果没有游戏别名,游戏将回退到主机名。
- 副标题和缩略图是机会性的。 Copilot 在识别匹配字段时包括它们,否则将忽略它们。
示例
如果 MCP 工具返回以下响应,则无需显式定义 response_semantics 。 Copilot 从已知别名推断引文字段。
{
"isError": false,
"content": [
{
"type": "text",
"text": "<stringified results>"
}
]
}
字段 text 包含字符串化的结果:
{
"results": [
{
"url": "https://example.com/result1",
"title": "Result 1",
"subtitle": "Subtitle for Result 1"
},
{
"url": "https://example.com/result2",
"title": "Result 2",
"subtitle": "Subtitle for Result 2"
}
]
}
由于 results、 url、 title和 subtitle 都匹配已知的别名,因此 Copilot 会为每个项目呈现可单击的引文。 任何等效别名在其位置工作 - 例如, items 或 data 而不是 results、 或 webUrlhref 而不是 url。
引文属性
以下属性可用于引文。 所有值都是针对 所选的一项的 data_path相对 JSONPath 表达式。
| 属性 | 必需 | 功能 |
|---|---|---|
title |
是 (实际上) | 引文的可单击标题。 |
subtitle |
否 | 第二行 - 日期、作者、类别。 |
url |
是 (实际上) | 单击时引文导航的位置。 必须是返回源的规范链接。 |
thumbnail_url |
否 | 与引文一起显示的小图像。 |
注意
如果 url 缺少 ,则引文不可单击。 缺少此属性是开发人员看到非功能性引文的常见原因。
设置 data_path
属性 data_path 是 JSONPath (RFC 9535) 表达式。 使用不正确的 JSONPath 表达式是引文未显示的最常见原因之一。
| 如果你的响应如下所示... | 使用此 data_path |
|---|---|
{ "results": [ ... ] } |
$.results |
{ "content": [ { "results": [ ... ] } ] } (MCP 样式的嵌套) |
$.content[0].results |
| 根目录中的单个对象 (没有数组包装器) | $ |
{ "content": [ { "type": "text", "text": "<stringified JSON>" } ] } (原始 MCP) |
$如果内部 JSON 具有数组,则为 根,或$.results |
提示
平展数组。 例如,多级嵌套数组 (, $.content[0].results[0].items) 是最有可能以无提示方式失败的架构模式。 如果拥有工具响应形状,则返回一个平面 results: [...] 数组。
超越响应语义
作为第一个首选项, 请考虑向 代理添加丰富的 UI 小组件。 此方法面向未来且 AI 原生,可实现更智能、更自适应和无缝的交互。
仅当需要以下条件之一时,才在需要以下条件之一时,添加自适应卡作为最后手段:
- 引文的自定义视觉布局单独 (多列、图像横幅、格式化文本块) 或引文卡正文中呈现的多个字段, (标题、副标题和 URL) 。
- 默认“单击引文”行为之外的操作按钮 (例如 ,
Action.Execute多按钮工具栏) 。
对于绝大多数引文方案(“显示源,让我单击”)完全跳过自适应卡片。 它们增加了复杂性,更难调试,并且默认引文 UI 干净且与 Copilot 的其余部分保持一致。
使用自适应卡片的示例
"response_semantics": {
"data_path": "$.content[1].results",
"properties": {
"title": "$.title",
"subtitle": "$.publishedDate",
"url": "$.url"
},
"staticTemplate": {
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": "${title}",
"weight": "bolder",
"size": "medium"
},
{
"type": "TextBlock",
"text": "${subtitle}",
"isSubtle": true
},
{
"type": "TextBlock",
"text": "${text}",
"wrap": true
}
],
"selectAction": {
"type": "OpenUrl",
"url": "${url}"
}
}
}
${title}请注意 、 ${subtitle}和 ${url} 标记 - 这些标记由前面显示的相同properties映射填充。 自适应卡片是响应语义之上的 表示层 ;它不会替换它。
故障排除清单
如果未显示引文,请使用以下清单。
- 是否
data_path指向正确的节点? 将工具的原始 JSON 响应粘贴到 JSONPath 测试器中,并确认表达式返回预期的数组或对象。 - 每个项是否都有一个非空
url? 缺少 URL 会导致不可单击的引文。 - 对于 MCP 工具,字段
text是否在有效的 JSON 内TextContentBlock? 手动分析它以确认。 - 架构是否平整? 如果有深层嵌套的数组,请尝试返回单个平面数组。
- 你是否声明
response_semantics了每个函数 (插件清单中的) 而不是插件根目录中的函数capabilities? 必须将它限定为 函数。