Integrar a observabilidade do agente usando o OTel direto

Este guia orienta você de ponta a ponta por meio do envio de telemetria do agente para o Agente 365 diretamente pelo OpenTelemetry (OTLP/HTTP+JSON). Antes de começar, leia os conceitos de observabilidade do Agente 365 para entender o modelo, os fluxos de autenticação e as superfícies em que os dados chegam.

Importante

O caminho OTel direto é a exceção, não o padrão. Use-o somente se você já tiver um pipeline OpenTelemetry, sua estrutura não poderá usar o SDK do Agent 365 ou seu agente estiver em um idioma que o SDK ainda não dá suporte (como Java). Para todos os outros, o caminho recomendado é o Microsoft OpenTelemetry Distro, que fornece um SDK de observabilidade unificado no Agente 365, Microsoft Foundry, Azure Monitor e muito mais. O SDK de Observabilidade anterior continua funcionando sem alterações significativas, mas não é mais recomendado para novas integrações; as diretrizes de migração para usuários existentes do SDK estão chegando.

Pré-requisitos

Verifique se as configurações a seguir estão em vigor antes que qualquer telemetria flua.

Quem What
Administrador de locatários Inscreva-se no Agente 365 e conceda consentimento para seu aplicativo de agente. Consulte Integrar ao Agente 365. Sem um locatário licenciado, a ingestão é silenciosamente descartada – a solicitação retorna 200 OK com partialSuccess: null , mas os dados nunca aparecem downstream.
Administrador de locatários Assign uma licença Microsoft 365 E7 ou Microsoft Agent 365 para pelo menos um usuário no locatário. A SKU presente não é suficiente. A atribuição a um usuário inicia o Defender fluxo de trabalho de back-end que permite a ingestão. Sem uma licença atribuída, as solicitações retornam 200 OK e partialSuccess: null os dados são removidos silenciosamente.
Administrador de locatários Conceda consentimento do locatário. Consulte Grant agents access to Microsoft 365 resources. Sem ele, os tokens são emitidos sem a função/escopo e as solicitações retornam 403.
Sua equipe de desenvolvimento Registre seu aplicativo (aplicativo Microsoft Entra padrão ou blueprint). Consulte Introdução ao desenvolvimento do Agente 365.
Sua equipe de desenvolvimento Adicione Agent365.Observability.OtelWrite em permissões de API (função de aplicativo para S2S, escopo para delegado). Para blueprints, consulte Configurar permissões herdáveis. Coordene com a equipe de integração do Agent 365 para habilitar a permissão.

Receitas de autenticação

Todas as quatro receitas usam o ponto de extremidade de token de Microsoft Entra padrão:

Campo Valor
Ponto de extremidade de token https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Recurso (aud token retornado) 9b975845-388f-4429-889e-eab1ef63949c (também aceita api://9b975845-388f-4429-889e-eab1ef63949c)
Escopo do S2S 9b975845-388f-4429-889e-eab1ef63949c/.default
Escopo do OBO 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

As receitas abaixo mostram HTTP bruto para maior clareza. Em produção, prefira Microsoft. Identity.Web ou outra biblioteca MSAL, que manipula a atualização e o cache de token.

De qual receita eu preciso?

Meu modelo de aplicativo Meu fluxo OAuth Ir para
Registro de aplicativo de Microsoft Entra padrão S2S (credenciais do cliente) S2S, aplicativo standard Microsoft Entra
Registro de aplicativo de Microsoft Entra padrão OBO (delegado) OBO, aplicativo standard Microsoft Entra
Identidade do agente derivado do blueprint S2S (credenciais do cliente) S2S, identidade de agente derivada de blueprint
Identidade do agente derivado do blueprint Equipe de equipe de OBO/IA OBO, identidade de agente derivada de blueprint

Aplicativo S2S, Standard Microsoft Entra

Um POST para o ponto de extremidade de token do locatário com grant_type=client_credentials. Autentique o aplicativo usando um segredo do cliente, um certificado (declaração JWT assinada) ou uma identidade gerenciada ou 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 retornado tem appidazp{your-app-id}/ = , roles contendo Agent365.Observability.OtelWritee .aud = 9b975845-... Use-o na /observabilityService/.../traces rota.

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

S2S, identidade de agente derivada de blueprint

As identidades dos agentes não têm credenciais próprias. O blueprint de identidade do agente contém as credenciais (identidade gerenciada FIC, certificado ou segredo do cliente) e gera tokens em nome de suas identidades de agente filho por meio de uma troca de duas etapas. Para obter mais informações, consulte o fluxo OAuth do aplicativo autônomo.

  1. O blueprint autentica e obtém um token T1federado de troca de identidade:

    • {blueprint-credential} é o token MSI do blueprint, JWT assinado por certificado ou declaração secreta de token de troca – por configuração de blueprint.
    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. As trocas de identidade do T1 agente para o token de recurso de observabilidade do Agente 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 retornado tem appidazp{agent-identity-app-id}/ = , roles contendo Agent365.Observability.OtelWritee .aud = 9b975845-...
    • Use esse token na /observabilityService/.../traces rota.
    • A URL {agentId} é a appId de identidade do agente, não a appId de blueprint.

Aplicativo OBO, Standard Microsoft Entra

Receba o token Tc de entrada do usuário do seu chamador upstream (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 de certificado, substitua client_secret={secret} pelo mesmo client_assertion_type + client_assertion par que no S2S.

O token retornado tem appidazp{your-app-id}/ = , scp contendo Agent365.Observability.OtelWritee .aud = 9b975845-... Use-o na /observability/.../traces rota. Um token de atualização é retornado junto com ele; armazene o cache e reutilize-o em vez de executar novamente a troca em cada chamada.

OBO, identidade de agente derivada de blueprint (incluindo o colega de equipe de IA)

Há três etapas principais para o fluxo em nome do fluxo. Para obter mais informações, consulte os fluxos do Agente OAuth: em nome do fluxo.

  1. Receba o token Tcde usuário. Para um colega de equipe de IA, esse token representa a conta de usuário do próprio agente; caso contrário, ele representa o chamador humano.

  2. O blueprint autentica e obtém T1o mesmo que o fluxo de identidade do agente derivado de blueprint do S2S.

  3. As trocas de identidade do T1 agente e Tc para 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 retornado tem appid = azp{agent-identity-app-id}/, scp contendo Agent365.Observability.OtelWritee representa o usuário do agente. Use-o na /observability/.../traces rota. A URL {agentId} é a appId de identidade do agente, não a appId de blueprint. Um token de atualização é retornado junto com ele; armazene o cache e reutilize-o.

Declarações necessárias no token retornado

Rota S2S (/observabilityService/...) – token somente de aplicativo:

Reclamaçã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 à URL {agentId}
scp Deve estar ausente

Rota delegada (/observability/...) – token delegado pelo usuário (Portador ou PFAT):

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

A rota delegada aceita tokens e MSAuth1.0 PFAT ambosBearer. Os chamadores diretos devem usar Bearer. Se você não souber qual deles tem, use Bearer.

Pontos de conexão

Duas rotas; escolha pela forma como seu serviço se autentica, não pelo que o usuário está fazendo:

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 de URL

  • {tenantId} - o GUID do locatário do cliente. O servidor trata isso como autoritativo; se os intervalos forem definidos microsoft.tenant.id e ele discordar, a solicitação será rejeitada.
  • {agentId} - appId do aplicativo de chamada (também o OAuth client_id). Para identidades derivadas de blueprint, esta é a appId de identidade do agente , não a appId de blueprint. Deve ser igual à declaração appid / azp do token.
  • api-version=1 -Necessário.

Codificação do corpo da solicitação

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

  • traceId (16 bytes) e spanId (8 bytes) são enviados como cadeias de caracteres hexáxe minúsculas.
  • startTimeUnixNano / endTimeUnixNano são cadeias de caracteres que contêm nanossegundos de época unix.
  • kindé o valor de enumeração OTLP inteiro (por exemplo, ); é o número enumerado inteiro (por exemplo1, para ERROROK2 ). status.codeINTERNAL1
  • Todos os valores de atributo são enviados como stringValue.

Forma de resposta

Uma chamada bem-sucedida retorna 200 OK:

{ "partialSuccess": null }

Se alguns intervalos foram rejeitados pelo filtro por intervalo:

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

Os nomes de campo são camelCase no fio. Sempre verifique partialSuccess: um 200 com todos os seus intervalos rejeitados é um resultado real que você deve vir à tona. Os limites e as condições de queda listam os casos de descarte silenciosos em partialSuccess: null que um 200 retorna, apesar de nenhum dado aparecer downstream.

Menor solicitação possível

O teste de ponta a ponta mais simples envia um único invoke_agent intervalo. Este intervalo é o menor corpo que pousa em Microsoft Defender.

Etapa 1. Obtenha um token de portador. Para S2S, use as credenciais do cliente com escopo 9b975845-388f-4429-889e-eab1ef63949c/.default (consulte receitas de autenticação para a receita completa).

Etapa 2. POST um único intervalo:

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

Etapa 3. Espere 200 OK com este corpo:

{ "partialSuccess": null }

Etapa 4. Confirme se os dados foram realmente desembarcados. Um 200 OK não é prova de ingestão; Verificar a ingestão percorre o fluxo de verificação. Em vez disso, para POSTAR um arquivo de corpo salvo, substitua --data @- <<EOF ... EOF por --data @./otlp-request.json.

Exemplo de execução do agente

Um usuário do Microsoft Teams pergunta "Qual é o clima em Seattle?". Seu agente chama uma GetWeather função, pede a uma LLM para formatar a resposta e responde. Essa única execução é de quatro intervalos:

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 intervalo:

Attribute 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

Esses atributos em toda a execução não são propagados automaticamente. Você deve definir gen_ai.conversation.id, microsoft.channel.namee microsoft.session.id em cada intervalo você mesmo.

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

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

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

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

Enviar telemetria

Usando um SDK do OTel

A maioria dos parceiros envia rastreamentos por meio de um SDK do OTel em vez de HTTP enrolado à mão. O SDK manipula o envio em lote, a repetição e a codificação OTLP/HTTP+JSON para você. Defina o ponto de extremidade do exportador e injete o Authorization cabeçalho.

O ponto de extremidade do exportador é a URL de rota em si, incluindo a cadeia de caracteres de consulta:

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

(Use /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.

Manual HTTP

Se você não puder ou não quiser usar um SDK do OTel, crie a solicitação OTLP/HTTP+JSON por conta própria e POSTE-a. A forma do corpo é 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 é um objeto cujos campos necessários são traceId, spanId, , name, kind, startTimeUnixNano, endTimeUnixNano, attributese (para intervalos não raiz) parentSpanId. Consulte pontos de extremidade e codificação do corpo da solicitação para as regras de codificação (tempos codificados em cadeia de caracteres, hex traceId / spanId, inteiro kind / status.code, todos os valores de atributo como stringValue).

O conjunto de atributos a serem definidos em cada intervalo é definido em contratos de mensagem. Consulte a referência de atributo para a lista de atributos completa. Consulte o exemplo de execução do Agente para obter um exemplo de trabalho de ponta a ponta com o token de portador no cabeçalho e o corpo embutido.

Você pode enviar todos os intervalos de uma execução em um único corpo POST (preferencial - uma solicitação, um rastreamento) ou em vários POSTs. O servidor reconstrói a execução detraceId + + parentSpanIdgen_ai.conversation.id, portanto, cada intervalo carrega o suficiente para ser correlacionado de qualquer maneira.

Contratos de mensagem

Esta seção define quais intervalos você pode emitir e quais atributos vão em cada um. Para obter a especificação completa de atributo por atributo, consulte a referência de atributo.

Tipos de operação

Cada intervalo enviado deve ser gen_ai.operation.name definido como um desses quatro valores (sem diferenciar maiúsculas de minúsculas). Qualquer intervalo com um valor ausente ou não reconhecido é silenciosamente descartado e contado em partialSuccess.rejectedSpans.

gen_ai.operation.name Significado Gotcha mais googled
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 em Microsoft Defender exibições de atividade do agente ou no Centro de administração do Microsoft 365. Sem ela, a telemetria só aterrissa em Microsoft Defender busca avançada (CloudAppEvents).
execute_tool Uma chamada de ferramenta/função executada por um agente. --
chat Uma chamada de inferência llm. Use o literal chat, NOT inference.
output_messages Uma mensagem de saída emitida final. --

Hierarquia de intervalo e agrupamento de execução

O Agente 365 reconstrói uma execução do grafo de intervalo OTLP padrão (traceId, spanId, ) parentSpanIdmais os atributos em toda a execução da referência de atributo.

Seis regras:

  1. Sempre definido parentSpanId em cada intervalo não raiz. Sem ela, a estrutura da árvore da execução não pode ser reconstruída.
  2. Reutilizar o mesmo traceId em cada intervalo em uma execução.
  3. Defina gen_ai.conversation.id em cada intervalo com o mesmo valor. Essa é a chave de junção primária para "todos os intervalos nesta execução". Ele não é propagado automaticamente.
  4. Defina microsoft.channel.name em cada intervalo com o mesmo valor. Os intervalos de ferramentas ausentes do canal/conversa só poderão herdá-los de seus pais invoke_agentse o pai estiver na mesma solicitação OTLP, portanto, defina-os em cada intervalo por conta própria.
  5. Defina microsoft.session.id em cada intervalo quando você tiver uma sessão lógica.
  6. Para chamadas de agente para agente em que o agente filho está em uma solicitação separada, reutilize o mesmo gen_ai.conversation.id e use os microsoft.a365.caller.agent.* atributos (consulte referência de atributo) para capturar o contexto do agente de chamador.

A árvore de quatro intervalos no exemplo de execução do Agente é a forma canônica.

Formas de execução comuns

Forma Intervalos para emitir Notes
Chatbot de agente único (sem ferramentas, sem intervalo LLM) Somente um invoke_agent Definir atributos de toda a execução mais gen_ai.input.messages e gen_ai.output.messages. Idêntico à menor solicitação possível.
Agente com ferramentas (mais comum) invoke_agentraiz + chat, execute_toolfilhos output_messages Todas as crianças compartilham a raiz traceId e definem parentSpanId = root.spanId. Todos carregam os mesmos atributos em toda a execução. Veja o exemplo de execução do Agente para obter um exemplo completo.
Agente para agente Cada agente emite seu próprio invoke_agent Reutilize o mesmo gen_ai.conversation.id em ambos os agentes. No destino, invoke_agentdefina gen_ai.execution.type = "Agent2Agent" e os microsoft.a365.caller.agent.* atributos (chamando o agente appId, o nome, o blueprint appId, a ID do usuário e o email). Se o agente de chamada não tiver registro do Entra, use microsoft.a365.caller.agent.platform.id e gen_ai.caller.agent.type , em vez disso.

Lista de verificação de integração

Execute esta lista de verificação antes de ir para a produção.

Categoria Verificação
Auth Seu aplicativo Entra (ou blueprint) está registrado e você pode criar tokens para ele.
Auth Seu aplicativo foi concedido Agent365.Observability.OtelWrite (função de aplicativo para S2S, escopo para delegado).
Auth Cada agente tem sua própria Entra appId como {agentId} na URL. Para identidades derivadas de blueprint, essa appId é a appId de identidade do agente, não a appId de blueprint. Se o agente não tiver nenhum registro do Entra, consulte Escolher valores.
Auth Um administrador de locatários concedeu consentimento para Agent365.Observability.OtelWrite. Sem consentimento, os tokens são emitidos sem a função/escopo e as solicitações são rejeitadas com 403.
Licenciamento Pelo menos um usuário no locatário do cliente tem uma licença Microsoft 365 E7 ou Microsoft Agent 365 atribuída (atribuição, não apenas a presença de SKU no locatário). Sem uma licença atribuída, a ingestão é descartada silenciosamente. Consulte Pré-requisitos.
Intervalos Cada intervalo define o essencial de toda a execução (hierarquia de intervalo e agrupamento de execução).
Intervalos invoke_agent conjunto de intervalos gen_ai.input.messages e gen_ai.output.messages.
Intervalos execute_toolconjunto de intervalosgen_ai.tool.name, gen_ai.tool.type, , gen_ai.tool.call.id, gen_ai.tool.call.arguments. gen_ai.tool.call.result
Intervalos chat spans set gen_ai.request.model e gen_ai.provider.name (e idealmente gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - codificado em cadeia de caracteres).
Intervalos Todos os intervalos não raiz definidos parentSpanId; todos os intervalos em uma execução compartilham o mesmo traceId.
Carga útil O corpo da solicitação é ≤ 1 MB.
Verificação Você analisa partialSuccess todas as rejeições de resposta e log.
Verificação Você executou o fluxo de verificação na verificação da ingestão em relação às primeiras execuções.

Próximas Etapas