本指南逐步讲解如何直接通过 OpenTelemetry(OTLP/HTTP+JSON)将代理遥测数据发送到 Agent 365。 在开始之前,请阅读 Agent 365 可观测性概念 来了解模型、身份验证流和数据表面。
Important
直接 OTel 路径是异常,而不是默认值。 仅在以下情况下才使用它:你已经有 OpenTelemetry 管道、你的框架无法使用 Agent 365 SDK,或者你的代理使用的是 SDK 尚未支持的语言(例如 Java)。 对于其他人,建议的路径是 Microsoft OpenTelemetry Distro,它跨 Agent 365、Microsoft Foundry、Azure Monitor 等提供统一的可观测性 SDK。 较早的 可观测性 SDK 将继续工作,无需重大更改,但不再建议进行新的集成;即将推出现有 SDK 用户的迁移指南。
先决条件
在任何遥测数据传输开始之前,请确保以下配置均已设置妥当。
| 谁 | What |
|---|---|
| 租户管理员 | 注册 Agent 365,并为您的代理应用授予同意。 请参阅 Agent 365 入门。 如果没有已获许可的租户,数据引入会被静默丢弃——请求会返回 200 OK 和 partialSuccess: null,但数据永远不会在下游出现。 |
| 租户管理员 |
分配 Microsoft 365 E7 或 Microsoft Agent 365 许可证给租户中的至少一位用户。 存在的 SKU 是不够的。 分配给用户会启动启用引入的Defender后端工作流。 如果没有分配的许可证,请求将返回 200 OK , partialSuccess: null 并且数据会以无提示方式删除。 |
| 租户管理员 | 授予租户同意。 请参阅 授予代理访问 Microsoft 365 资源的权限。 如果没有它,签发的令牌将不包含角色/作用域,请求会返回 403。 |
| 开发团队 | 注册应用(标准Microsoft Entra应用或蓝图)。 请参阅 Agent 365 开发入门。 |
| 开发团队 | 在 Agent365.Observability.OtelWrite下添加(S2S 的应用角色、委派的范围)。 有关蓝图,请参阅 “配置可继承的权限”。 与 Agent 365 入门支持团队协调,以启用该权限。 |
身份验证范例
所有四种方案都使用标准的 Microsoft Entra 令牌终结点:
| 领域 | Value |
|---|---|
| 令牌终结点 | https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token |
资源(aud 在返回的令牌中) |
9b975845-388f-4429-889e-eab1ef63949c (也接受 api://9b975845-388f-4429-889e-eab1ef63949c) |
| S2S 范围 | 9b975845-388f-4429-889e-eab1ef63949c/.default |
| OBO 范围 | 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite |
以下示例为便于说明,展示了原始 HTTP。 在生产环境中,首选 Microsoft。Identity.Web 或其他 MSAL 库,用于处理令牌刷新和缓存。
我需要哪种食谱?
| 我的应用模型 | 我的 OAuth 流程 | 跳转到 |
|---|---|---|
| 标准Microsoft Entra应用注册 | S2S(客户端凭证) | S2S、标准Microsoft Entra应用 |
| 标准Microsoft Entra应用注册 | OBO(委派) | OBO,标准 Microsoft Entra 应用程序 |
| 从蓝图派生的代理身份 | S2S(客户端凭据) | S2S,源自蓝图的代理标识 |
| 源自蓝图的代理身份 | OBO /AI 团队成员 | OBO,基于蓝图派生的代理身份标识 |
S2S、标准Microsoft Entra应用
向租户的令牌端点发送一次包含 grant_type=client_credentials 的 POST 请求。 使用客户端密码、证书(已签名的 JWT 断言)或托管标识或联合凭据对应用进行身份验证。
POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={your-app-id}
&scope=9b975845-388f-4429-889e-eab1ef63949c%2F.default
&client_secret={secret}
&grant_type=client_credentials
返回的令牌包含appid/azp = {your-app-id}、roles包含Agent365.Observability.OtelWrite和 。aud = 9b975845-... 在 /observabilityService/.../traces 路由上使用它。
对于基于证书的身份验证,请替换为 client_secret={secret}client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}。
S2S、源自蓝图的代理标识
代理标识本身没有认证信息。 代理标识蓝图持有凭据(托管标识 FIC、证书或客户端密码),并通过两步交换代表其子代理标识生成令牌。 有关详细信息,请参阅 自治应用 OAuth 流。
该蓝图进行身份验证并获取联合身份交换令牌
T1:-
{blueprint-credential}是蓝图配置中指定的 MSI 令牌、经证书签名的 JWT 或机密交换令牌断言,具体取决于蓝图配置。
POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded client_id={blueprint-app-id} &scope=api%3A%2F%2FAzureADTokenExchange%2F.default &fmi_path={agent-identity-app-id} &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer &client_assertion={blueprint-credential} &grant_type=client_credentials-
代理身份用
T1换取 Agent 365 可观测性资源令牌:POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded client_id={agent-identity-app-id} &scope=9b975845-388f-4429-889e-eab1ef63949c%2F.default &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer &client_assertion={T1} &grant_type=client_credentials- 返回的令牌包含
appid/azp={agent-identity-app-id}、roles包含Agent365.Observability.OtelWrite和 。aud=9b975845-... - 在
/observabilityService/.../traces路由上使用此令牌。 - URL
{agentId}对应的是 代理身份 appId,而不是蓝图 appId。
- 返回的令牌包含
OBO,标准 Microsoft Entra 应用
从上游调用方(Bearer 或 PFAT)接收用户的传入令牌 Tc ,然后交换它:
POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={your-app-id}
&scope=9b975845-388f-4429-889e-eab1ef63949c%2FAgent365.Observability.OtelWrite
&client_secret={secret}
&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion={Tc}
&requested_token_use=on_behalf_of
对于证书身份验证,请将 client_secret={secret} 替换为与 S2S 中相同的 client_assertion_type + client_assertion 对。
返回的令牌包含appid/azp = {your-app-id}、scp包含Agent365.Observability.OtelWrite和 。aud = 9b975845-... 在 /observability/.../traces 路由上使用它。 同时返回刷新令牌;缓存并重复使用它,而不是在每次调用时重新运行交换。
OBO,基于蓝图生成的代理身份标识(包括 AI 队友)
代理流有三个主要步骤。 有关详细信息,请参阅 代理 OAuth 流:代表流。
接收用户令牌
Tc。 对于 AI 协作者,此令牌表示该代理自身的用户帐户;否则,它表示人类调用方。蓝图进行身份验证并获取
T1,与 S2S 蓝图派生的代理标识流相同。代理身份交换
T1和Tc以换取委派资源令牌:POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded client_id={agent-identity-app-id} &scope=9b975845-388f-4429-889e-eab1ef63949c%2FAgent365.Observability.OtelWrite &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer &client_assertion={T1} &grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer &assertion={Tc} &requested_token_use=on_behalf_of
返回的令牌具有appid/azp = {agent-identity-app-id},其中scp包含Agent365.Observability.OtelWrite,并表示该代理的用户。 在 /observability/.../traces 路由上使用它。 URL {agentId} 是 代理标识 appId,而不是蓝图 appId。 同时返回刷新令牌;缓存并重复使用它。
返回的令牌中的必需声明
S2S 路由 (/observabilityService/...) - 仅限应用的令牌:
| 索赔 | 所需的值 |
|---|---|
aud |
9b975845-388f-4429-889e-eab1ef63949c (或 api://9b975845-...) |
roles |
必须包含 Agent365.Observability.OtelWrite |
appid (v1) 或 azp (v2) |
必须与 URL 相同 {agentId} |
scp |
必须不存在 |
委托路由(/observability/...) - 用户委托令牌(持有者令牌或 PFAT):
| 索赔 | 所需的值 |
|---|---|
aud |
9b975845-388f-4429-889e-eab1ef63949c (或 api://9b975845-...) |
scp |
必须包含 Agent365.Observability.OtelWrite |
appid / azp |
必须等于网址 {agentId} |
委托路由同时接受 Bearer 和 MSAuth1.0 PFAT 令牌。 直接调用者应使用 Bearer。 如果你不知道你拥有哪一个,请使用 Bearer。
端点
两种路径;请根据 您的服务 如何进行身份验证来选择,而不是根据用户正在执行什么操作:
POST https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 # S2S
POST https://agent365.svc.cloud.microsoft/observability/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1 # OBO
标题
Authorization: Bearer <token> # or MSAuth1.0 ... for delegated PFAT
Content-Type: application/json
URL 参数
-
{tenantId}- 客户租户的 GUID。 服务器将其视为最终依据;如果你的 span 设置了microsoft.tenant.id,而服务器不认可这一点,请求就会被拒绝。 -
{agentId}- 调用应用程序的 appId (也是 OAuthclient_id)。 对于源自蓝图的标识,这里指的是 代理标识 的 appId,而不是蓝图的 appId。 必须等于你的令牌中的appid/azp声明。 -
api-version=1-必填。
请求正文编码
请求体采用标准的 OTLP/HTTP+JSON 格式:即带有 resourceSpans → scopeSpans → spans 的 ExportTraceServiceRequest。 请记住以下详细信息:
-
traceId(16 字节)和spanId(8 字节)作为小写十六进制字符串发送。 -
startTimeUnixNano/endTimeUnixNano是包含 Unix 纪元纳秒时间戳的 字符串。 -
kind是整数 OTLP 枚举值(例如1表示INTERNAL);status.code是整数枚举值(例如1表示OK,2表示ERROR)。 - 所有属性值都以
stringValue的形式发送。
响应形状
成功的调用返回 200 OK:
{ "partialSuccess": null }
如果每个范围筛选器拒绝了某些范围:
{
"partialSuccess": {
"rejectedSpans": 2,
"errorMessage": "Dropped 2 non-A365 span(s) ..."
}
}
字段名称是网络上的 camelCase。
始终检查 partialSuccess:返回 200 但所有 span 都被拒绝,确实是一种可能发生的结果,你必须明确提示出来。
限制和丢弃条件列出了静默丢弃的情形:返回 200 并带有 partialSuccess: null,但下游没有出现任何数据。
最小可能的请求
最简单的端到端测试发送单个 invoke_agent 范围。 此 span 是进入 Microsoft Defender 的最小主体。
步骤 1。 获取 Bearer 令牌。 对于 S2S,请使用作用域为 9b975845-388f-4429-889e-eab1ef63949c/.default 的客户端凭据(完整指南请参阅 身份验证指南)。
步骤 2。 POST 单个跨度:
TOKEN="$(./get-token.sh)"
TENANT_ID="<customer-tenant-guid>"
AGENT_ID="<your-agent-app-id>"
curl -i -X POST \
"https://agent365.svc.cloud.microsoft/observabilityService/tenants/${TENANT_ID}/otlp/agents/${AGENT_ID}/traces?api-version=1" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
--data @- <<EOF
{
"resourceSpans": [{
"scopeSpans": [{
"scope": { "name": "my-instrumentation", "version": "1.0.0" },
"spans": [{
"traceId": "0102030405060708090a0b0c0d0e0f10",
"spanId": "1111111111111111",
"parentSpanId": "",
"name": "invoke_agent",
"kind": 1,
"startTimeUnixNano": "1736175600000000000",
"endTimeUnixNano": "1736175601500000000",
"status": { "code": 1 },
"attributes": [
{ "key": "gen_ai.operation.name", "value": { "stringValue": "invoke_agent" } },
{ "key": "gen_ai.agent.id", "value": { "stringValue": "${AGENT_ID}" } },
{ "key": "gen_ai.agent.name", "value": { "stringValue": "MyAgent" } },
{ "key": "microsoft.a365.agent.blueprint.id", "value": { "stringValue": "${AGENT_ID}" } },
{ "key": "gen_ai.conversation.id","value": { "stringValue": "conv-001" } },
{ "key": "microsoft.channel.name","value": { "stringValue": "web" } },
{ "key": "user.id", "value": { "stringValue": "<entra-user-objectid>" } },
{ "key": "client.address", "value": { "stringValue": "10.1.2.80" } },
{ "key": "server.address", "value": { "stringValue": "myagent.example.com" } },
{ "key": "server.port", "value": { "stringValue": "443" } },
{ "key": "gen_ai.input.messages", "value": { "stringValue": "[{\"role\":\"user\",\"content\":\"hi\"}]" } },
{ "key": "gen_ai.output.messages","value": { "stringValue": "[{\"role\":\"assistant\",\"content\":\"hello\"}]" } }
]
}]
}]
}]
}
EOF
步骤 3。 应为 200 OK,正文如下:
{ "partialSuccess": null }
步骤 4. 确认数据确实已落地。 200 OK 并不能证明已完成摄取;验证摄取介绍了验证流程。 若要改为 POST 已保存的正文文件,请将 --data @- <<EOF ... EOF 替换为 --data @./otlp-request.json。
代理运行示例
Microsoft Teams上的用户询问“西雅图天气怎么样?” 你的智能体调用 GetWeather 函数,要求 LLM 格式化答案,然后作出回复。 该单次运行包含四个区段:
graph TD
A["<b>invoke_agent</b> · spanId=A · parentSpanId=∅<br/><i>root - the run itself</i>"]
B["<b>chat</b> · spanId=B · parentSpanId=A<br/><i>LLM picks the tool / formats reply</i>"]
C["<b>execute_tool</b> · spanId=C · parentSpanId=A<br/><i>the GetWeather call</i>"]
D["<b>output_messages</b> · spanId=D · parentSpanId=A<br/><i>final reply emitted to the user</i>"]
A --> B
A --> C
A --> D
在每个跨度上设置的全运行范围属性:
| Attribute | 示例值 |
|---|---|
traceId |
0102030405060708090a0b0c0d0e0f10 |
gen_ai.conversation.id |
19:abc@thread.tacv2 |
microsoft.session.id |
session-1234 |
microsoft.channel.name |
msteams |
gen_ai.agent.id |
<AGENT_APP_ID> |
gen_ai.agent.name |
WeatherBot |
microsoft.a365.agent.blueprint.id |
<BLUEPRINT_APP_ID> |
user.id |
<entra-user-objectid> |
client.address |
10.1.2.80 |
server.address |
weatherbot.example.com |
server.port |
443 |
Important
这些运行范围的属性 不会 自动传播。 你必须在每个 span 上自行设置 gen_ai.conversation.id、microsoft.channel.name 和 microsoft.session.id。
范围 A: invoke_agent (根)
{
"traceId": "0102030405060708090a0b0c0d0e0f10",
"spanId": "1111111111111111",
"parentSpanId": "",
"name": "invoke_agent",
"kind": 1,
"startTimeUnixNano": "1736175600000000000",
"endTimeUnixNano": "1736175601500000000",
"status": { "code": 1 },
"attributes": [
{ "key": "gen_ai.operation.name", "value": { "stringValue": "invoke_agent" } },
{ "key": "gen_ai.execution.type", "value": { "stringValue": "HumanToAgent" } },
{ "key": "gen_ai.input.messages", "value": { "stringValue": "[{\"role\":\"user\",\"content\":\"What's the weather in Seattle?\"}]" } },
{ "key": "gen_ai.output.messages", "value": { "stringValue": "[{\"role\":\"assistant\",\"content\":\"It's 65F and partly cloudy in Seattle.\"}]" } },
{ "key": "user.email", "value": { "stringValue": "alice@contoso.com" } }
/* plus all the run-wide attributes listed above */
]
}
区间 B:chat(LLM 调用)
{
"traceId": "0102030405060708090a0b0c0d0e0f10",
"spanId": "2222222222222222",
"parentSpanId": "1111111111111111",
"name": "chat",
"kind": 1,
"startTimeUnixNano": "1736175600200000000",
"endTimeUnixNano": "1736175600900000000",
"status": { "code": 1 },
"attributes": [
{ "key": "gen_ai.operation.name", "value": { "stringValue": "chat" } },
{ "key": "gen_ai.request.model", "value": { "stringValue": "gpt-4o" } },
{ "key": "gen_ai.provider.name", "value": { "stringValue": "openai" } },
{ "key": "gen_ai.usage.input_tokens", "value": { "stringValue": "42" } },
{ "key": "gen_ai.usage.output_tokens", "value": { "stringValue": "23" } }
/* plus all the run-wide attributes */
]
}
范围 C: execute_tool
{
"traceId": "0102030405060708090a0b0c0d0e0f10",
"spanId": "3333333333333333",
"parentSpanId": "1111111111111111",
"name": "execute_tool",
"kind": 1,
"startTimeUnixNano": "1736175600950000000",
"endTimeUnixNano": "1736175601200000000",
"status": { "code": 1 },
"attributes": [
{ "key": "gen_ai.operation.name", "value": { "stringValue": "execute_tool" } },
{ "key": "gen_ai.tool.name", "value": { "stringValue": "GetWeather" } },
{ "key": "gen_ai.tool.type", "value": { "stringValue": "function" } },
{ "key": "gen_ai.tool.call.id", "value": { "stringValue": "call-001" } },
{ "key": "gen_ai.tool.call.arguments", "value": { "stringValue": "{\"location\":\"Seattle\"}" } },
{ "key": "gen_ai.tool.call.result", "value": { "stringValue": "{\"tempF\":65,\"condition\":\"partly cloudy\"}" } }
/* plus all the run-wide attributes */
]
}
范围 D: output_messages
{
"traceId": "0102030405060708090a0b0c0d0e0f10",
"spanId": "4444444444444444",
"parentSpanId": "1111111111111111",
"name": "output_messages",
"kind": 1,
"startTimeUnixNano": "1736175601400000000",
"endTimeUnixNano": "1736175601500000000",
"status": { "code": 1 },
"attributes": [
{ "key": "gen_ai.operation.name", "value": { "stringValue": "output_messages" } },
{ "key": "gen_ai.output.messages", "value": { "stringValue": "[{\"role\":\"assistant\",\"content\":\"It's 65F and partly cloudy in Seattle.\"}]" } }
/* plus all the run-wide attributes */
]
}
发送遥测数据
使用 OTel SDK
大多数合作伙伴通过 OTel SDK 发送追踪数据,而不是使用自行编写的 HTTP 实现。 SDK 会为你处理批处理、重试和 OTLP/HTTP+JSON 编码。 设置导出程序终结点并注入 Authorization 标头。
导出程序终结点是路由 URL 本身,包括查询字符串:
https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1
(对于委托路由,请使用 /observability/... 而不是 /observabilityService/...。)
Python
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
exporter = OTLPSpanExporter(
endpoint="https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1",
headers={"Authorization": f"Bearer {token}"},
)
包: opentelemetry-exporter-otlp-proto-http.
Node.js/TypeScript
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
const exporter = new OTLPTraceExporter({
url: "https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1",
headers: { Authorization: `Bearer ${token}` },
});
包:@opentelemetry/exporter-trace-otlp-http。
.NET
using OpenTelemetry.Exporter;
services.AddOpenTelemetry().WithTracing(b => b
.AddOtlpExporter(o =>
{
o.Endpoint = new Uri("https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1");
o.Headers = $"Authorization=Bearer {token}";
o.Protocol = OtlpExportProtocol.HttpJson;
}));
包:OpenTelemetry.Exporter.OpenTelemetryProtocol。
手动 HTTP
如果不能或不想使用 OTel SDK,请自行生成 OTLP/HTTP+JSON 请求并发布它。 消息体结构由 OpenTelemetry OTLP/HTTP+JSON 规范定义:
{
"resourceSpans": [{
"resource": { "attributes": [ ... ] }, // optional
"scopeSpans": [{
"scope": { "name": "<your-instrumentation>", "version": "1.0.0" },
"spans": [ <span>, <span>, ... ]
}]
}]
}
每个 <span> 都是一个对象,其必填字段为 traceId、spanId、name、kind、startTimeUnixNano、endTimeUnixNano、attributes,以及(对于非根跨度)parentSpanId。 有关编码规则(以字符串编码的时间值、十六进制traceId / spanId、整数kind / status.code以及所有属性值均为stringValue),请参阅端点和请求正文编码。
要在每个跨度上设置的属性集在 消息协定中定义。 有关完整属性列表,请参阅属性参考。 请参阅 Agent 运行示例,查看一个端到端的可运行示例,其中 Bearer 令牌位于请求头中,正文以内联方式提供。
可以在单个 POST 正文(首选 - 一个请求、一个跟踪)或多个 POST 中发送运行的所有跨度。 服务器根据 traceId + parentSpanId + gen_ai.conversation.id 重建该次运行,因此每个跨度都包含足够的信息,可进行双向关联。
消息协定
本节定义了可以生成哪些 span,以及每个 span 应包含哪些属性。 有关完整的逐项属性规范,请参阅 属性参考。
操作类型
你发送的每个 span 都必须带有设为以下四个值之一的 gen_ai.operation.name(不区分大小写)。 任何缺失值或值无法识别的跨度都会被静默丢弃,并计入 partialSuccess.rejectedSpans 中。
gen_ai.operation.name |
含义 | 谷歌搜索量最高的常见陷阱 |
|---|---|---|
invoke_agent |
调用代理。 代理运行的“root”。 | 这是运行记录显示在 Microsoft Defender 代理活动视图或 Microsoft 365 管理中心中所必需的。 没有它,遥测数据只会进入 Microsoft Defender 高级搜寻(CloudAppEvents)。 |
execute_tool |
代理执行的工具/函数调用。 | -- |
chat |
一次 LLM 推理调用。 |
使用字面量 chat,而不是 inference。 |
output_messages |
最终发出的输出信息。 | -- |
跨层次结构并运行分组
Agent 365 根据标准 OTLP 跨度图(traceId, spanId, parentSpanId)以及 属性参考中的整个运行属性重建一次运行。
六个规则:
-
始终在每个非根跨度上设置
parentSpanId。 如果没有它,则无法重新构造运行树结构。 -
在一次运行中的每个跨度中重复使用相同的
traceId -
在每个 span 上将
gen_ai.conversation.id设置为相同的值。 这是“此运行中的所有跨度”的主联接键。 它不会自动传播。 -
将每个 span
microsoft.channel.name都设置为相同的值。 缺少 channel / conversation 的工具 spaninvoke_agent只有在父 span 位于同一 OTLP 请求中时,才能从其继承这些属性,因此请你在每个 span 上自行设置它们。 -
如果存在逻辑会话,请在每个 span 上设置
microsoft.session.id。 - 对于子代理位于单独请求中的代理间调用,请复用同一个
gen_ai.conversation.id,并使用microsoft.a365.caller.agent.*属性(请参阅 属性参考)来捕获调用方代理的上下文。
代理运行示例中的四跨树是规范形状。
常见运行形状
| 形状 | 要输出的跨度 | 备注 |
|---|---|---|
| 单代理聊天机器人 (无工具,无 LLM 范围) | 仅限一个invoke_agent |
设置整个运行的属性,以及 gen_ai.input.messages 和 gen_ai.output.messages。 与 最小可能的请求相同。 |
| 使用工具的代理 (最常见的) |
invoke_agent根 + chat、execute_tool、output_messages子项 |
所有子项共享根项的 traceId 和 parentSpanId = root.spanId 集合。 它们都具有整个运行范围内相同的属性。 有关完整示例,请参阅 代理运行示例 。 |
| 代理到代理 | 每个代理都会发出自己的invoke_agent |
在两个代理之间复用同一个 gen_ai.conversation.id。 在目标的 invoke_agent 上,设置 gen_ai.execution.type = "Agent2Agent" 以及 microsoft.a365.caller.agent.* 属性(调用代理的 appId、名称、蓝图 appId、用户 ID 和电子邮件)。 如果调用代理没有 Entra 注册,请改用 microsoft.a365.caller.agent.platform.id 和 gen_ai.caller.agent.type。 |
载入清单
在部署到生产环境之前,请先逐项检查这份清单。
| 类别 | 检查 |
|---|---|
| 身份验证 | 你的 Entra 应用(或蓝图)已注册,你现在可以为其生成令牌。 |
| 身份验证 | 你的应用已被授予 Agent365.Observability.OtelWrite (S2S 的应用角色,委派的范围)。 |
| 身份验证 | 每个代理都有自己的 Entra appId ,如 {agentId} URL 中所示。 对于从蓝图派生的标识,该 appId 是代理标识的 appId,而不是蓝图的 appId。 如果代理没有 Entra 注册,请参阅 选取值。 |
| 身份验证 | 租户管理员已为 Agent365.Observability.OtelWrite 授予同意。 未经同意,令牌在没有角色/作用域的情况下颁发,请求将被拒绝 403。 |
| 许可 | 客户租户中至少有一个用户已分配 Microsoft 365 E7 或 Microsoft Agent 365 许可证(指已将许可证分配给用户,而不只是租户中存在该 SKU)。 如果没有分配许可证,数据引入将被静默丢弃。 请参阅 先决条件。 |
| 跨度 | 每个 Span 都会设置整个运行范围内的关键基础信息(Span 层级结构和运行分组)。 |
| 跨度 |
invoke_agent 跨度集合 gen_ai.input.messages 和 gen_ai.output.messages。 |
| 跨度 |
execute_tool跨度集gen_ai.tool.name、gen_ai.tool.type、gen_ai.tool.call.id、gen_ai.tool.call.arguments、gen_ai.tool.call.result。 |
| 跨度 |
chat跨度集gen_ai.request.model和gen_ai.provider.name(理想情况下gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - 以字符串编码)。 |
| 跨度 | 所有非根跨度都设置 parentSpanId;一次运行中的所有跨度共享相同的 traceId。 |
| 负载 | 请求正文不超过 1 MB。 |
| 验证 | 你在每次响应时都解析 partialSuccess,并记录拒绝情况。 |
| 验证 | 你在首次运行时执行了 验证数据摄取 中的验证流程。 |