使用直接 OTel 集成智能体可观测性

本指南将端到端演练通过 OpenTelemetry (OTLP/HTTP+JSON) 直接将智能体遥测数据发送到 Agent 365。 开始前,请阅读 Agent 365 可观测性概念,以了解模型、身份验证流以及数据所进入的平台。

重要提示

直接 OTel 路径属于例外情况,并非默认路径。 仅当您已经拥有 OpenTelemetry 管道、您的框架无法使用 Agent 365 SDK,或您的智能体采用 SDK 尚不支持的语言(例如 Java)时,才使用该路径。 对于其他用户,推荐的路径是 Microsoft OpenTelemetry 发行版,它跨 Agent 365、Microsoft Foundry、Azure Monitor 等提供统一可观测性 SDK。 较早的可观测性 SDK 继续运行,没有中断性变更,但不再是新集成的推荐路径;面向现有 SDK 用户的迁移指南即将发布。

必备条件

请确保在任何遥测数据流动之前,已完成以下配置。

用户 内容
租户管理员 注册 Agent 365 并为您的智能体应用授予同意。 请参阅加入 Agent 365。 如果没有许可的租户,引入将静默丢弃 - 请求返回 200 OK,其中 partialSuccess: null,但数据永远不会在下游显示。
租户管理员 向租户中的至少一个用户分配 Microsoft 365 E7 或 Microsoft Agent 365 许可证。 仅存在该 SKU 是不够的。 分配到用户会启动 Defender 后端工作流,该工作流启用引入。 如果没有分配的许可证,请求返回 200 OK,其中 partialSuccess: null,并且数据会静默丢弃。
租户管理员 授予租户同意。 请参阅向智能体授予对 Microsoft 365 资源的访问权限。 若缺少该 SKU,生成的令牌将不包含角色/作用域,且请求将返回 403
您的开发团队 注册应用(标准 Microsoft Entra 应用或蓝图)。 请参阅 Agent 365 开发入门
您的开发团队 API 权限 下添加 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.OtelWriteaud = 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 流

  1. 蓝图获取联合标识交换令牌 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
    
  2. 智能体身份将 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.OtelWriteaud = 9b975845-...
    • /observabilityService/.../traces 路由上使用该令牌。
    • URL {agentId}智能体身份 appId,而非蓝图 appId。

OBO,标准 Microsoft Entra 应用

从上游调用方接收用户的传入令牌 Tc(Bearer 或 PFAT),然后进行交换:

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.OtelWriteaud = 9b975845-...。 在 /observability/.../traces 路由上使用它。 同时返回一个刷新令牌;将其缓存并重用,而不是每次调用时都重新运行交换。

OBO,蓝图派生的智能体标识(包括 AI 队友)

“代表”流主要包括三个步骤。 有关更多信息,请参阅智能体 OAuth 流:代表流

  1. 接收用户令牌 Tc。 对于 AI 团队成员,此令牌代表智能体自身用户账户;否则,它代表人类调用者。

  2. 蓝图获取 T1 并进行身份验证,与 S2S 蓝图派生的智能体标识流相同。

  3. 智能体标识针对委派的资源令牌交换 T1Tc

    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/...) - 用户委托令牌(Bearer 或 PFAT):

声明 所需的值
aud 9b975845-388f-4429-889e-eab1ef63949c(或 api://9b975845-...
scp 必须包含 Agent365.Observability.OtelWrite
appid / azp 必须等效于 URL {agentId}

委派的路由接受 BearerMSAuth1.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。 服务器将此视为权威值;如果您的数据段设置 microsoft.tenant.id,但它不同意,请求将遭到拒绝。
  • {agentId} - 调用应用程序的 appId(也称为 OAuth client_id)。 对于蓝图派生的标识,这是智能体标识 appId,而不是蓝图 appId。 必须与令牌的 appid / azp 声明相等。
  • api-version=1 - 必需。

请求正文编码

正文采用标准 OTLP/HTTP+JSON 格式:一个 ExportTraceServiceRequest 包含 resourceSpansscopeSpansspans。 牢记以下详细信息:

  • traceId(16 个字节)和 spanId(8 个字节)以小写的十六进制字符串形式发送。
  • startTimeUnixNano / endTimeUnixNano 是包含 Unix epoch 纳秒的字符串
  • kind 是整数 OTLP 枚举值(例如对于 INTERNAL1);status.code 是整数枚举(例如对于 OK1,对于 ERROR2)。
  • 所有属性值都以 stringValue 形式发送。

回复结构

成功的调用返回 200 OK

{ "partialSuccess": null }

如果某些数据段被按数据段过滤器拒绝:

{
  "partialSuccess": {
    "rejectedSpans": 2,
    "errorMessage": "Dropped 2 non-A365 span(s) ..."
  }
}

传输中的字段名称采用驼峰命名法。 务必检查 partialSuccess:所有数据段均被拒绝但返回 200 状态码是真实可能的结果,必须予以显示。 限制与丢弃条件列出了无声丢弃的情况,即尽管下游未出现数据,但仍返回 200 状态码并包含 partialSuccess: null

可能的最小请求

最简单的端到端测试发送单个 invoke_agent 数据段。 此数据段是最终进入 Microsoft Defender 的最小数据主体。

第 1 步。 获取持有者令牌。 对于 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

每个数据段上设置全局属性:

属性 示例值
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

重要提示

这些运行范围属性会自动传播。 您必须在每个数据段上自行设置 gen_ai.conversation.idmicrosoft.channel.namemicrosoft.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 请求并对其执行 POST 操作。 正文结构由 OpenTelemetry OTLP/HTTP+JSON 规范定义:

{
  "resourceSpans": [{
    "resource":  { "attributes": [ ... ] },          // optional
    "scopeSpans": [{
      "scope":  { "name": "<your-instrumentation>", "version": "1.0.0" },
      "spans":  [ <span>, <span>, ... ]
    }]
  }]
}

每个 <span> 都是一个对象,其必填字段包括 traceIdspanIdnamekindstartTimeUnixNanoendTimeUnixNanoattributes 和(对于非根数据段)parentSpanId。 有关编码规则(字符串编码的时间、十六进制 traceId / spanId、整数 kind / status.code 以及作为 stringValue 的所有属性值),请参阅终结点请求正文编码

要在每个数据段上设置的属性集均在消息合同中定义。 有关完整的属性列表,请参阅属性引用。 请参阅 智能体运行示例,获取包含标头中 Bearer 令牌和内联正文的端到端工作示例。

您可以在一个 POST 正文(首选 - 一个请求、一个跟踪)中或跨多个 POST 发送一次运行的所有数据段。 服务器从 traceId + parentSpanId + gen_ai.conversation.id 重新构建运行,因此每个数据的都具有足够的信息以实现关联,无论采用哪种方式。

消息合同

本部分定义可以发送哪些数据段,以及每个数据段应包含哪些属性。 有关完整的按属性规范,请参阅属性引用

操作类型

您发送的每个数据段都必须将 gen_ai.operation.name 设置为以下四个值之一(不区分大小写)。 任何缺少值或值无法识别的数据段将被静默丢弃,并计入 partialSuccess.rejectedSpans

gen_ai.operation.name 含义 最常搜索的问题
invoke_agent 智能体的调用。 智能体运行的“根”。 这是运行信息出现在 Microsoft Defender 智能体活动视图或 Microsoft 365 管理中心中的必要条件。 若缺少此项,遥测数据仅会记录在 Microsoft Defender 高级搜寻功能中 (CloudAppEvents)。
execute_tool 智能体所执行的工具/函数调用。 --
chat 一次 LLM 推理调用。 使用文字 chat,而不是 inference
output_messages 最终发送的输出消息。 --

数据段层次结构与运行分组

Agent 365 通过标准 OTLP 数据段图 (traceId, spanId, parentSpanId) 以及属性参考中全运行范围的属性来重建运行。

六个规则:

  1. 在每个非根数据段上始终设置 parentSpanId。 若缺少此信息,则无法重建运行的树形结构。
  2. 在一次运行的所有数据段中重用相同的 traceId
  3. 使用相同值在每个数据段上设置 gen_ai.conversation.id。 这是“此运行中的所有数据段”的主要连接键。 它会自动传播。
  4. 使用相同值在每个数据段上设置 microsoft.channel.name。 缺少通道/对话的工具数据段invoke_agent当其父节点位于同一 OTLP 请求中时,才可从父节点继承这些信息,因此请务必在每个数据段上自行设置这些属性。
  5. 在有逻辑会话时,在每个数据段上设置 microsoft.session.id
  6. 对于子智能体位于单独请求中的智能体到智能体调用,请重用相同的 gen_ai.conversation.id 并使用 microsoft.a365.caller.agent.* 属性(请参阅属性引用)以捕获呼叫方智能体上下文。

智能体运行示例中的四个数据段树是规范的结构。

常见运行结构

形状 需发出的数据段 说明
单个智能体聊天机器人(无工具,无 LLM 数据段) 仅一个 invoke_agent 设置运行级属性以及 gen_ai.input.messagesgen_ai.output.messages。 与可能的最小请求完全相同。
带有工具的智能体(最常见) invoke_agent 根节点 + chatexecute_tooloutput_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.idgen_ai.caller.agent.type

入职检查清单

在进入生产之前检查此清单。

类别 检查
身份验证 您的 Entra 应用(或蓝图)已注册,并且您可以为其获取令牌。
身份验证 您的应用已获授 Agent365.Observability.OtelWrite(S2S 的应用角色,委托模式下的作用域)。
身份验证 每个智能体都有自己的 Entra appId,就像 URL 中的 {agentId} 一样。 对于蓝图派生的身份,该 appId 是智能体身份的 appId,而非蓝图的 appId。 如果智能体没有 Entra 注册,请参阅选取值
身份验证 租户管理员已为 Agent365.Observability.OtelWrite 授予同意。 若未获得同意,将不带角色/作用域签发令牌,且请求将被 403 拒绝。
许可 客户租户中至少有一名用户被分配了 Microsoft 365 E7 或 Microsoft Agent 365 许可证(需为已分配状态,而非仅在租户中存在 SKU)。 若未分配许可证,数据摄取将被静默丢弃。 请参阅先决条件
数据段 每个数据段都定义了整个运行范围内的基本要素(数据段层次结构和运行分组)。
数据段 invoke_agent 数据段集 gen_ai.input.messagesgen_ai.output.messages
数据段 execute_tool 数据段集 gen_ai.tool.namegen_ai.tool.typegen_ai.tool.call.idgen_ai.tool.call.argumentsgen_ai.tool.call.result
数据段 chat数据段集 gen_ai.request.modelgen_ai.provider.name(理想情况下还包括 gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - 字符串编码)。
数据段 所有非根数据段都设置 parentSpanId;运行中的所有数据段都共享相同的 traceId
有效载荷 请求正文为 ≤ 1 MB。
验证 您在每个回复中分析 partialSuccess,并记录拒绝情况。
验证 您已在验证摄入中针对您的首次运行执行了验证流程。

后续步骤