Integrar a observabilidade do agente com OTel direto

Este guia orienta-o do ponto a ponto no envio da telemetria do agente para o Agent 365 diretamente através do OpenTelemetry (OTLP/HTTP+JSON). Antes de começar, leia os conceitos de observabilidade do Agent 365 para compreender o modelo, os fluxos de autenticação e as superfícies onde os seus dados são registados.

Importante

O caminho do OTel direto é a exceção, não é a predefinição. Utilize-o apenas se já tiver um pipeline do OpenTelemetry, se a sua arquitetura não puder utilizar o SDK do Agent 365, ou se o seu agente estiver numa linguagem que o SDK ainda não suporta (como Java). Para todos os outros, o caminho recomendado é o Microsoft OpenTelemetry Distro, que oferece um SDK de observabilidade unificado para o Agent 365, Microsoft Foundry, Azure Monitor e muito mais. O SDK de Observabilidade anterior continua a funcionar sem alterações interruptivas, mas já não é recomendado para novas integrações; será disponibilizada uma orientação de migração para os utilizadores existentes do SDK.

Pré-requisitos

Certifique-se de que as seguintes configurações estão em vigor antes de qualquer fluxo de telemetria.

Quem O que é
Administrador do inquilino Inscreva-se no Agent 365 e conceda permissão para a utilização da sua aplicação de agente. Consulte Integrar o Agent 365. Sem um inquilino licenciado, a ingestão é silenciosamente descartada - o pedido retorna 200 OK com partialSuccess: null, mas os dados nunca aparecem a jusante.
Administrador do inquilino Atribua uma licença Microsoft 365 E7 ou Microsoft Agent 365 a pelo menos um utilizador no inquilino. A presença do SKU não é suficiente. A atribuição de uma licença a um utilizador inicia o fluxo de trabalho back-end do Defender que ativa a ingestão. Sem uma licença atribuída, os pedidos devolvem 200 OK com partialSuccess: null e os dados são silenciosamente descartados.
Administrador do inquilino Conceda o consentimento do inquilino. Consulte Conceder acesso aos agentes aos recursos do Microsoft 365. Sem isso, os tokens são emitidos sem a função/âmbito e os pedidos devolvem 403.
A sua equipa de desenvolvimento Registe a sua aplicação (aplicação ou esquema padrão do Microsoft Entra). Consulte Comece a desenvolver com o Agent 365.
A sua equipa de desenvolvimento Adicione Agent365.Observability.OtelWrite em Permissões de API (função de aplicação para S2S, âmbito para delegado). Para os esquemas, consulte Configurar permissões herdáveis. Coordene com a equipa de inclusão do Agent 365 para ativar a permissão.

Receitas de autenticação

Todas as quatro receitas utilizam o ponto final do token padrão do Microsoft Entra:

Campo valor
Ponto final do token https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Recurso (aud no token devolvido) 9b975845-388f-4429-889e-eab1ef63949c (também aceita api://9b975845-388f-4429-889e-eab1ef63949c)
Âmbito do S2S 9b975845-388f-4429-889e-eab1ef63949c/.default
Âmbito do OBO 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

As receitas abaixo mostram o HTTP não processado para maior clareza. Em produção, prefira MicrosoftIdentity.Web ou outra biblioteca MSAL, que processa a atualização e a colocação em cache dos tokens.

De que receita preciso?

O meu modelo de aplicação O meu fluxo OAuth Aceda a
Registo da aplicação do Microsoft Entra padrão S2S (credenciais de cliente) S2S, aplicação do Microsoft Entra padrão
Registo da aplicação do Microsoft Entra padrão OBO (delegado) OBO, aplicação do Microsoft Entra padrão
Identidade do agente derivada do esquema S2S (credenciais de cliente) S2S, identidade do agente derivada do esquema
Identidade do agente derivada do esquema OBO/colega de equipa de IA OBO, identidade do agente derivada do esquema

S2S, aplicação do Microsoft Entra padrão

Um POST para o ponto final do token do inquilino com grant_type=client_credentials. Autentique a aplicação utilizando um segredo do cliente, um certificado (asserção JWT assinada), uma identidade gerida ou uma credencial federada.

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

O token devolvido tem appid/azp = {your-app-id}, roles com Agent365.Observability.OtelWrite e aud = 9b975845-.... Utilize-o na rota /observabilityService/.../traces.

Para a autenticação baseada em certificados, substitua client_secret={secret} por client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}.

S2S, identidade do agente derivada do esquema

As identidades dos agentes não têm credenciais próprias. O esquema de identidade do agente detém as credenciais (identidade gerida FIC, certificado ou segredo do cliente) e gera tokens em nome das suas identidades de agentes de elemento subordinado através de uma troca em dois passos. Para obter mais informações, consulte fluxo OAuth de aplicação autónoma.

  1. O esquema autentica-se e obtém um token de troca de identidade federada T1:

    • {blueprint-credential} corresponde ao token MSI do esquema, ao JWT assinado por certificado ou à asserção de token de troca secreta - por configuração de esquema.
    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. A identidade do agente troca T1 pelo token de recurso de Observabilidade do 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
    
    • O token devolvido tem appid/azp = {agent-identity-app-id}, roles com Agent365.Observability.OtelWrite e aud = 9b975845-....
    • Utilize este token na rota /observabilityService/.../traces.
    • O URL {agentId} é o appId da identidade do agente, não o appId do esquema.

OBO, aplicação do Microsoft Entra padrão

Receba o token de entrada do utilizador Tc do seu chamador de origem (Portador ou PFAT) e, em seguida, troque-o:

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

Para autenticação por certificado, substitua client_secret={secret} pelo mesmo par client_assertion_type + client_assertion do S2S.

O token devolvido tem appid/azp = {your-app-id}, scp com Agent365.Observability.OtelWrite e aud = 9b975845-.... Utilize-o na rota /observability/.../traces. É devolvido um token de atualização juntamente com o token; coloque-o em cache e reutilize-o em vez de executar a troca novamente a cada chamada.

OBO, identidade do agente derivada do esquema (incluindo o colega de equipa de IA)

Existem três passos principais no fluxo On-Behalf-Of. Para mais informações, consulte Fluxos OAuth de agente: fluxo On-Behalf-Of.

  1. Receba o token de utilizador Tc. Para um colega de equipa de IA, este token representa a conta de utilizador do próprio agente; caso contrário, representa o chamador humano.

  2. O esquema autentica-se e obtém T1, conforme o fluxo de identidade do agente derivado do esquema S2S.

  3. A identidade do agente troca T1 e Tc por um token de recurso delegado:

    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
    

O token devolvido tem appid/azp = {agent-identity-app-id}, scp com Agent365.Observability.OtelWrite, e representa o utilizador do agente. Utilize-o na rota /observability/.../traces. O URL {agentId} é o appId da identidade do agente, não o appId do esquema. Um token de atualização é devolvido juntamente com o mesmo; coloque-o em cache e reutilize-o.

Afirmações obrigatórias sobre o token devolvido

Rota S2S (/observabilityService/...) - token apenas da aplicação:

Afirmação Valor necessário
aud 9b975845-388f-4429-889e-eab1ef63949c (ou api://9b975845-...)
roles Deve conter Agent365.Observability.OtelWrite
appid (v1) ou azp (v2) Deve ser igual ao URL {agentId}
scp Deve estar ausente

Rota delegada (/observability/...) - token delegado pelo utilizador (Portador ou PFAT):

Afirmação Valor necessário
aud 9b975845-388f-4429-889e-eab1ef63949c (ou api://9b975845-...)
scp Deve conter Agent365.Observability.OtelWrite
appid / azp Deve ser igual ao URL {agentId}

A rota delegada aceita ambos os tokens Bearer e MSAuth1.0 PFAT. Os chamadores diretos devem utilizar Bearer. Se não souber qual tem, utilize Bearer.

Pontos finais

Duas rotas; selecione com base na forma como o seu serviço se autentica, e não no que o utilizador está a fazer:

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

Cabeçalhos:

Authorization: Bearer <token>      # or MSAuth1.0 ... for delegated PFAT
Content-Type: application/json

Parâmetros do URL

  • {tenantId} - o GUID do inquilino do cliente. O servidor considera este valor como autoritativo; se os seus spans definirem microsoft.tenant.id e houver divergência, o pedido será rejeitado.
  • {agentId} - o appId da aplicação de chamada (também o OAuth client_id). Para identidades derivadas do esquema, trata-se do appId da identidade do agente, não do appId do esquema. Deve corresponder à afirmação appid / azp do seu token.
  • api-version=1 - obrigatório.

Codificação do corpo do pedido

O corpo segue a forma OTLP/HTTP+JSON padrão: um ExportTraceServiceRequest com resourceSpansscopeSpansspans. Tenha em mente os seguintes detalhes:

  • traceId (16 bytes) e spanId (8 bytes) são enviados como cadeias hexa em minúsculas.
  • startTimeUnixNano / endTimeUnixNano are cadeias que representam nanossegundos da época Unix.
  • kind é o valor inteiro da enumeração OTLP (por exemplo, 1 para INTERNAL); status.code é o valor inteiro de uma enumeração (por exemplo, 1 para OK, 2 para ERROR).
  • Todos os valores dos atributos são enviados como stringValue.

Forma da resposta

Uma chamada bem-sucedida devolve 200 OK:

{ "partialSuccess": null }

Se alguns spans tiverem sido rejeitados pelo filtro individual de spans:

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

Os nomes dos campos são transmitidos em camelCase. Verificar sempre partialSuccess: um 200 com todos os seus spans rejeitados é um resultado real que deve ser apresentado. Limites e condições de descarte detalham os casos de descarte silencioso em que um 200 é devolvido com partialSuccess: null apesar de nenhum dado aparecer a jusante.

Pedido mínimo possível

O teste de ponto a ponto mais simples envia um único span invoke_agent. Este span é o menor corpo que chega ao Microsoft Defender.

Passo 1. Obtenha um token de Portador. Para S2S, utilize credenciais do cliente com o âmbito 9b975845-388f-4429-889e-eab1ef63949c/.default (consulte Receitas de autenticação para a receita completa).

Passo 2. POST um único span:

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

Passo 3. Espere 200 OK com este corpo:

{ "partialSuccess": null }

Passo 4. Confirme se os dados foram realmente ingeridos. Um 200 OK não é prova de ingestão; A verificação da ingestão percorre o fluxo de verificação. Para efetuar um POST de um ficheiro de corpo guardado, substitua --data @- <<EOF ... EOF por --data @./otlp-request.json.

Exemplo de execução do agente

Um utilizador do Microsoft Teams pergunta: "Qual é a previsão do tempo em Seattle?". O seu agente invoca uma função GetWeather, pede a um LLM para formatar a resposta e responde. Essa única execução consiste em quatro spans:

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

Atributos em toda a execução definidos em cada span:

Atributo Valor de exemplo
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

Importante

Estes atributos em toda a execução não são propagados automaticamente. É necessário definir gen_ai.conversation.id, microsoft.channel.name e microsoft.session.id manualmente em cada span.

Span A: invoke_agent (raiz)

{
  "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 */
  ]
}

Span B: chat (chamada 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 */
  ]
}

Span 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 */
  ]
}

Span 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 */
  ]
}

Envio de telemetria

Utilização de um SDK OTel

A maioria dos parceiros envia rastreios através de um SDK OTel em vez de HTTP manualmente. O SDK processa criação de batches, as repetições e a codificação OTLP/HTTP+JSON. Defina o ponto final do exportador e injeta o cabeçalho Authorization.

O ponto final do exportador é o próprio URL da rota, incluindo a cadeia de consulta:

https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1

(Utilize /observability/... em vez de /observabilityService/... para a rota delegada.)

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}"},
)

Pacote: 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}` },
});

Pacote: @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;
    }));

Pacote: OpenTelemetry.Exporter.OpenTelemetryProtocol.

HTTP manual

Se não puder ou não quiser utilizar um SDK OTel, crie manualmente o pedido OTLP/HTTP+JSON e envie-o via POST. A forma da mensagem é definida pela especificação OTLP/HTTP+JSON do OpenTelemetry:

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

Cada <span> é um objeto cujos campos obrigatórios são traceId, spanId, name, kind, startTimeUnixNano, endTimeUnixNano, attributes e, (para spans não raiz), parentSpanId. Consulte Pontos finais e Codificação do corpo do pedido para as regras de codificação (tempos codificados em cadeia, traceId / spanId hex, kind / status.code número inteiro, todos os valores de atributos como stringValue).

O conjunto de atributos a definir em cada span está definido em Contratos de mensagens. Consulte Referência de atributos para obter uma lista completa de atributos. Consulte o Exemplo de execução do agente para obter um exemplo funcional de ponto a ponto com o token de Portador no cabeçalho e o corpo inline.

Pode enviar todos os spans de uma execução num único corpo POST (preferencial — um pedido, um rastreio) ou em vários POSTs. O servidor reconstrói a execução a partir de traceId + parentSpanId + gen_ai.conversation.id, por isso cada span contém informação suficiente para ser correlacionado de qualquer forma.

Contratos de mensagens

Esta secção especifica quais os spans que pode emitir e quais atributos devem ser incluídos em cada um. Para obter a especificação completa atributo a atributo, consulte a Referência de atributos.

Tipos de operação

Cada span que enviar deve ter gen_ai.operation.name definido para um destes quatro valores (insensível a maiúsculas e minúsculas). Qualquer span com um valor em falta ou não reconhecido é silenciosamente descartado e contabilizado em partialSuccess.rejectedSpans.

gen_ai.operation.name Significado A ideia mais pesquisada no Google
invoke_agent Uma invocação de um agente. A "raiz" de uma execução de agente. Necessário para que a execução apareça nas vistas de atividades do agente do Microsoft Defender ou no centro de administração do Microsoft 365. Sem isso, a telemetria só é registada na procura avançada do Microsoft Defender (CloudAppEvents).
execute_tool Uma chamada de ferramenta / função realizada por um agente. --
chat Uma chamada de inferência de LLM. Utilize o chat literal, NÃO inference.
output_messages Uma mensagem de saída final emitida. --

Hierarquia de spans e agrupamento de execuções

O Agent 365 reconstrói uma execução a partir do grafo padrão de spans OTLP (traceId, spanId, parentSpanId) mais os atributos em toda a execução provenientes da Referência de atributos.

Seis regras:

  1. Defina sempre parentSpanId em cada span não raiz. Sem isso, a estrutura em árvore da execução não pode ser reconstruída.
  2. Reutilize o mesmo traceId em cada span de uma execução.
  3. Defina gen_ai.conversation.id em cada span com o mesmo valor. Esta é a chave principal de junção para "todos os spans nesta execução". Não é propagado automaticamente.
  4. Defina microsoft.channel.name em cada span com o mesmo valor. Os spans de ferramentas que não têm o canal/conversa podem herdá-los do seu elemento principal invoke_agentapenas se o elemento principal estiver no mesmo pedido OTLP, por isso defina-os em cada span manualmente.
  5. Defina microsoft.session.id todos os spans quando tiver uma sessão lógica.
  6. Para chamadas entre agentes em que o agente de elemento subordinado está num pedido separado, reutilize o mesmo gen_ai.conversation.id e utilize os atributos microsoft.a365.caller.agent.* (consulte Referência de atributos) para capturar o contexto entre o chamador e o agente.

A árvore de quatro spans no exemplo de execução do agente é a forma canónica.

Formas comuns de execução

Forma Spans a emitir Notas
Chatbot de agente único (sem ferramentas, sem span de LLM) Só um invoke_agent Defina atributos em toda a execução mais gen_ai.input.messages e gen_ai.output.messages. Idêntico ao Menor pedido possível.
Agente com ferramentas (mais comum) raiz invoke_agent + chat, elementos subordinados execute_tool, output_messages Todos os elementos subordinados partilham os traceId da raiz e definem parentSpanId = root.spanId. Todos têm os mesmos atributos em toda a execução. Consulte Exemplo de execução do agente para obter um exemplo completo.
Agente para agente Cada agente emite o seu próprio invoke_agent Reutilize o mesmo gen_ai.conversation.id em ambos os agentes. No invoke_agent de destino, defina gen_ai.execution.type = "Agent2Agent" e os atributos microsoft.a365.caller.agent.* (appId do agente de chamada, nome, appId do esquema, ID de utilizador e e-mail). Caso o agente de chamada não tenha registo no Entra, utilize microsoft.a365.caller.agent.platform.id e gen_ai.caller.agent.type em alternativa.

Lista de verificação de inclusão

Siga esta lista de verificação antes de iniciar a produção.

Categoria Verificar
Autenticação A sua aplicação (ou esquema) do Entra está registada e pode emitir tokens.
Autenticação A sua aplicação recebeu Agent365.Observability.OtelWrite (função de aplicação para S2S, âmbito para delegado).
Autenticação Cada agente tem o seu próprio appId do Entra como {agentId} no URL. Para as identidades derivadas do esquema, trata-se do appId de identidade do agente, não do appId do esquema. Se o agente não tiver registo no Entra, consulte Selecionar valores.
Autenticação Um administrador do inquilino concedeu consentimento para Agent365.Observability.OtelWrite. Sem consentimento, os tokens são emitidos sem a função/âmbito e os pedidos são rejeitados com 403.
Licenciamento Pelo menos um utilizador no inquilino do cliente tem uma licença Microsoft 365 E7 ou Microsoft Agent 365 atribuída (atribuição, não apenas presença do SKU no inquilino). Sem uma licença atribuída, a ingestão é ignorada silenciosamente. Veja Pré-requisitos.
Spans Cada span define os elementos essenciais para toda a execução (Hierarquia de spans e agrupamento de execuções).
Spans Os spans invoke_agent definem gen_ai.input.messages e gen_ai.output.messages.
Spans Os spans execute_tool definem gen_ai.tool.name, gen_ai.tool.type, gen_ai.tool.call.id, gen_ai.tool.call.arguments, gen_ai.tool.call.result.
Spans Os spans chat definem gen_ai.request.model e gen_ai.provider.name (e idealmente gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - codificados como cadeia).
Spans Todos os spans não raiz definem parentSpanId; todos os spans numa execução partilham o mesmo traceId.
Payload O corpo do pedido é ≤ 1 MB.
Verificação Analisa partialSuccess em cada resposta e regista as rejeições.
Verificação Executou o fluxo de verificação na Verificação da ingestão em relação às suas primeiras execuções.

Passos seguintes