Integrare l'osservabilità dell'agente con OTel diretto

Questa guida ti accompagna, dall’inizio alla fine, nell’invio della telemetria dell’agente ad Agent 365 direttamente tramite OpenTelemetry (OTLP/HTTP+JSON). Prima di iniziare, leggere Concetti di osservabilità di Agent 365 per comprendere il modello, i flussi di autenticazione e le superfici dei dati.

Importante

Il percorso OTel diretto è l'eccezione, non l'impostazione predefinita. Usarlo solo se si dispone già di una pipeline OpenTelemetry, il framework non può usare Agent 365 SDK o l'agente si trova in un linguaggio non ancora supportato dall'SDK, ad esempio Java. Per tutti gli altri utenti, il percorso consigliato è Microsoft OpenTelemetry Distro, che fornisce un SDK di osservabilità unificato in Agent 365, Microsoft Foundry, Monitoraggio di Azure e altro ancora. Il precedente Observability SDK continua a funzionare senza modifiche di rilievo, ma non è più consigliato per le nuove integrazioni; verranno fornite indicazioni sulla migrazione per gli utenti dell'SDK esistenti.

Prerequisiti

Verificare che le configurazioni seguenti siano presenti prima di qualsiasi flusso di telemetria.

Chi What
Amministratore tenant Registrarsi ad Agent 365 e fornire il consenso per l'app dell'agente. Vedi Introduzione ad Agent 365. Senza un tenant con licenza, l'inserimento viene eliminato automaticamente. La richiesta restituisce 200 OK con partialSuccess: null ma i dati non vengono mai visualizzati a valle.
Amministratore tenant Assegna una licenza Microsoft 365 E7 o Microsoft Agent 365 ad almeno un utente del tenant. La sola presenza dello SKU non è sufficiente. L'assegnazione a un utente avvia il flusso di lavoro back-end Defender che abilita l'inserimento. Senza una licenza assegnata, le richieste restituiscono 200 OK con partialSuccess: null e i dati vengono scartati senza alcuna notifica.
Amministratore tenant Concedere il consenso del tenant. Vedere Concedere agli agenti l'accesso alle risorse di Microsoft 365. Senza di esso, i token vengono emessi senza il ruolo/ambito e le richieste restituiscono 403.
Il team di sviluppo Registra la tua app (app Microsoft Entra standard o blueprint). Vedere Introduzione allo sviluppo di Agent 365.
Il team di sviluppo Aggiungere Agent365.Observability.OtelWrite sotto Autorizzazioni API (il ruolo app per S2S, l'ambito per l'accesso delegato). Per i progetti modello, vedere Configurare le autorizzazioni ereditabili. Coordinarsi con il team di onboarding di Agent 365 per abilitare l'autorizzazione.

Ricette di autenticazione

Tutte e quattro le ricette usano l'endpoint standard del token di Microsoft Entra:

Campo Value
Punto di accesso https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Risorsa (aud nel token restituito) 9b975845-388f-4429-889e-eab1ef63949c (accetta api://9b975845-388f-4429-889e-eab1ef63949canche )
Ambito S2S 9b975845-388f-4429-889e-eab1ef63949c/.default
Ambito OBO 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

Le ricette seguenti mostrano HTTP non elaborato per maggiore chiarezza. Nell'ambiente di produzione, preferire Microsoft. Identity.Web o un'altra libreria MSAL, che gestisce l'aggiornamento e la memorizzazione nella cache dei token.

Quale ricetta ho bisogno?

Modello di app personale Il mio flusso OAuth Vai a
Registrazione dell'app standard Microsoft Entra S2S (credenziali del client) S2S, app Microsoft Entra standard
Registrazione dell'app standard Microsoft Entra OBO (delegato) OBO, app Microsoft Entra standard
Identità dell'agente derivata da blueprint S2S (credenziali client) S2S, identità dell'agente derivato da Blueprint
Identità dell'agente derivata da blueprint OBO/compagno di squadra di intelligenza artificiale OBO, identità dell'agente derivata da Blueprint

S2S, app Microsoft Entra standard

Un POST per l'endpoint del token del tenant con grant_type=client_credentials. Autenticare l'app usando un segreto client, un certificato (asserzione JWT firmata) o un'identità gestita o credenziali federate.

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

Il token restituito ha appid/azp = {your-app-id}, contenente roles, Agent365.Observability.OtelWrite e .aud = 9b975845-... Usalo sul percorso /observabilityService/.../traces.

Per l'autenticazione basata su certificato, sostituire client_secret={secret} con client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}.

S2S, identità dell'agente derivato da Blueprint

Le identità degli agenti non hanno credenziali specifiche. Il modello di identità dell'agente contiene le credenziali (FIC dell'identità gestita, certificato o segreto client) e genera token per conto delle sue identità figlie dell'agente tramite uno scambio in due fasi. Per altre informazioni, consulta il flusso OAuth per app autonome.

  1. Il progetto autentica e ottiene un token T1di scambio di identità federato:

    • {blueprint-credential} è il token MSI del blueprint, il JWT firmato con certificato o l'asserzione exchange-token secret, in base alla configurazione del 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. L'identità dell'agente viene scambiata T1 con il token di risorsa di Agent 365 Observability:

    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
    
    • Il token restituito ha appid/azp = {agent-identity-app-id}, contenente roles, Agent365.Observability.OtelWrite e .aud = 9b975845-...
    • Usa questo token sul percorso /observabilityService/.../traces.
    • L'URL {agentId} è l'id appId dell'identità dell'agente, non l'appId del progetto.

OBO, app Microsoft Entra standard

Ricevere il token Tc in ingresso dell'utente dal chiamante upstream (Bearer o PFAT), quindi scambiarlo:

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

Per l'autenticazione del certificato, sostituire client_secret={secret} con la stessa client_assertion_type + client_assertion coppia di in S2S.

Il token restituito ha appid/azp = {your-app-id}, contenente scp, Agent365.Observability.OtelWrite e .aud = 9b975845-... Usalo sul percorso /observability/.../traces. Un token di aggiornamento viene restituito insieme; memorizzare nella cache e riutilizzarlo invece di riesecuzione dello scambio in ogni chiamata.

OBO, identità dell'agente derivata da Blueprint (incluso il teammate IA)

Esistono tre passaggi principali del flusso on-behalf-of. Per altre informazioni, vedere Flussi OAuth dell'agente: per conto del flusso.

  1. Ricevi il token utente Tc. Per un collega di intelligenza artificiale, questo token rappresenta il proprio account utente dell'agente; in caso contrario, rappresenta il chiamante umano.

  2. Il blueprint esegue l'autenticazione e ottiene T1, come avviene nel flusso di identità dell'agente derivato dal blueprint S2S.

  3. L'identità dell'agente scambia T1 e Tc con un token di risorsa delegato:

    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
    

Il token restituito ha appid/azp = {agent-identity-app-id}, scp contenente Agent365.Observability.OtelWritee rappresenta l'utente dell'agente. Usalo sul percorso /observability/.../traces. L'URL {agentId} è l'appId dell'identità dell'agente, non l'appId del blueprint. Un token di aggiornamento viene restituito insieme; memorizzare nella cache e riutilizzarlo.

Attestazioni richieste nel token restituito

Percorso S2S (/observabilityService/...) - token solo applicazione:

Richiesta di rimborso Valore obbligatorio
aud 9b975845-388f-4429-889e-eab1ef63949c (o api://9b975845-...)
roles Deve contenere Agent365.Observability.OtelWrite
appid (v1) o azp (v2) Deve essere uguale a URL {agentId}
scp Deve essere assente

Route delegata (/observability/...) - token delegato dall'utente (Bearer o PFAT):

Richiesta di rimborso Valore obbligatorio
aud 9b975845-388f-4429-889e-eab1ef63949c (o api://9b975845-...)
scp Deve contenere Agent365.Observability.OtelWrite
appid / azp Deve essere uguale a URL {agentId}

Il percorso delegato accetta sia i token Bearer sia i token MSAuth1.0 PFAT. I chiamanti diretti devono usare Bearer. Se non si sa quale si ha, utilizzare Bearer.

Endpoint

Due percorsi; scegliere in base al modo in cui il servizio esegue l'autenticazione, non in base alle operazioni che l'utente sta eseguendo:

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

Intestazioni:

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

Parametri URL

  • {tenantId} : GUID del tenant del cliente. Il server considera questo come autorevole; se l'intervallo è impostato microsoft.tenant.id e non è d'accordo, la richiesta viene rifiutata.
  • {agentId} - appId dell'applicazione chiamante (anche OAuth client_id). Per le identità derivate dal blueprint, questo è l'appId dell'identità agente, non l'appId del blueprint. Deve corrispondere al claim appid / azp del tuo token.
  • api-version=1 -Obbligatorio.

Codifica del corpo della richiesta

Il corpo ha la struttura standard OTLP/HTTP+JSON: un ExportTraceServiceRequest con resourceSpansscopeSpansspans. Tenere presenti i dettagli seguenti:

  • traceId (16 byte) e spanId (8 byte) vengono inviati come stringhe esadecimale minuscole.
  • startTimeUnixNano / endTimeUnixNano sono stringhe contenenti nanosecondi dell'epoca Unix.
  • kind è il valore intero dell'enumerazione OTLP (ad esempio 1 per INTERNAL); status.code è l'enumerazione intera (ad esempio 1 per OK, 2 per ERROR).
  • Tutti i valori degli attributi vengono inviati come stringValue.

Forma della risposta

Una chiamata riuscita restituisce 200 OK:

{ "partialSuccess": null }

Se alcuni intervalli sono stati rifiutati dal filtro per singolo intervallo:

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

I nomi dei campi sono in camelCase nel formato trasmesso. Controlla sempre partialSuccess: un 200 con tutti i segmenti rifiutati è un risultato reale che devi segnalare. Limiti e condizioni di scarto elenca i casi di scarto silenzioso in cui viene restituito un codice 200 con partialSuccess: null, sebbene non compaiano dati a valle.

Richiesta più piccola possibile

Il test end-to-end più semplice invia un singolo invoke_agent span. Questo intervallo è la più piccola entità che arriva in Microsoft Defender.

Passaggio 1: Ottenere un Bearer token. Per S2S, usare le credenziali client con ambito 9b975845-388f-4429-889e-eab1ef63949c/.default (vedere Ricette di autenticazione per la ricetta completa).

Passaggio 2: POST un singolo intervallo:

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

Passaggio 3. Prevedere 200 OK con questo corpo:

{ "partialSuccess": null }

Passaggio 4: Verificare che i dati siano effettivamente atterrati. Un 200 OK non è una prova di inserimento; La verifica dell'inserimento illustra il flusso di verifica. Per eseguire invece il POST di un file del corpo salvato, sostituisci --data @- <<EOF ... EOF con --data @./otlp-request.json.

Esempio di esecuzione dell'agente

Un utente su Microsoft Teams chiede "Qual è il meteo a Seattle?". L'agente chiama una GetWeather funzione, chiede a un LLM di formattare la risposta e risponde. L'esecuzione singola è di quattro intervalli:

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

Attributi a livello di esecuzione impostati in ogni intervallo:

Attribute Valore di esempio
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

Questi attributi a livello di esecuzione non vengono propagati automaticamente. Devi impostare manualmente gen_ai.conversation.id, microsoft.channel.name e microsoft.session.id in ogni span.

Span A: invoke_agent (root)

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

Invio di dati di telemetria

Uso di un SDK OTel

La maggior parte dei partner invia tracce tramite un SDK OTel anziché usare un’implementazione HTTP scritta manualmente. L'SDK gestisce automaticamente l'invio in batch, i tentativi e la codifica OTLP/HTTP+JSON. Impostare l'endpoint di esportazione e inserire l'intestazione Authorization .

L'endpoint dell'esportatore coincide con l'URL del percorso stesso, inclusa la stringa di query:

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

Usare /observability/... invece di /observabilityService/... per la route delegata.

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

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

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

Pacchetto: OpenTelemetry.Exporter.OpenTelemetryProtocol.

Manuale HTTP

Se non è possibile o non si vuole usare un SDK OTel, compilare manualmente la richiesta OTLP/HTTP+JSON e PUBBLICArla. La struttura del body è definita dalla specifica OpenTelemetry OTLP/HTTP+JSON:

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

Ogni <span> è un oggetto i cui campi obbligatori sono traceId, spanId, name, kind, startTimeUnixNano, endTimeUnixNano, attributes e (per gli span non radice) parentSpanId. Consulta Endpoints e Codifica del corpo della richiesta per le regole di codifica (orari codificati come stringhe, esadecimale traceId / spanId, interi kind / status.code, tutti i valori degli attributi come stringValue).

Il set di attributi da impostare su ogni intervallo è definito nei contratti di messaggio. Vedere Informazioni di riferimento sugli attributi per l'elenco completo degli attributi. Fare riferimento all'esempio di esecuzione di Agent per un esempio di lavoro end-to-end con il token Bearer nell'intestazione e il corpo inline.

È possibile inviare tutti gli intervalli di un'esecuzione in un singolo corpo POST (preferibile, una richiesta, una traccia) o tra più POST. Il server ricostruisce l'esecuzione da traceId + parentSpanId + gen_ai.conversation.id, quindi ogni span contiene informazioni sufficienti per poter essere correlato in entrambe le direzioni.

Contratti di messaggio

Questa sezione definisce quali span è possibile emettere e quali attributi applicare a ciascuno. Per le specifiche complete, attributo per attributo, consulta il riferimento degli attributi.

Tipi di operazione

Ogni span inviato deve avere gen_ai.operation.name impostato su uno di questi quattro valori (senza distinzione tra maiuscole e minuscole). Qualsiasi intervallo con un valore mancante o non riconosciuto viene eliminato automaticamente e conteggiato in partialSuccess.rejectedSpans.

gen_ai.operation.name Meaning L’insidia più cercata su Google
invoke_agent Un'invocazione di un agente. La "radice" di un'esecuzione dell'agente. Necessario affinché l'esecuzione venga visualizzata nelle visualizzazioni dell'attività dell'agente di Microsoft Defender o nell'interfaccia di amministrazione di Microsoft 365. In assenza di questo, i dati di telemetria confluiscono solo in Ricerca avanzata di Microsoft Defender (CloudAppEvents).
execute_tool Una chiamata di strumento/funzione eseguita da un agente. --
chat Una chiamata di inferenza LLM. Usare il valore letterale chat, NON inference.
output_messages Messaggio di output finale emesso. --

Gerarchia estesa ed esecuzione del raggruppamento

Agent 365 ricostruisce un'esecuzione dal grafico dell'intervallo OTLP standard (traceId, spanId, parentSpanId) più gli attributi a livello di esecuzione del riferimento attributo.

Sei regole:

  1. Imposta sempre parentSpanId su ogni span non root. Senza di esso, la struttura ad albero della run non può essere ricostruita.
  2. Riutilizza lo stesso traceId in ogni segmento di una sequenza.
  3. Impostata gen_ai.conversation.id su ogni intervallo con lo stesso valore. Si tratta della chiave di join primaria per "tutti gli intervalli in questa esecuzione". Non viene propagata automaticamente.
  4. Impostata microsoft.channel.name su ogni intervallo con lo stesso valore. Gli span dello strumento in cui mancano il canale o la conversazione possono ereditarli dallo span padre invoke_agentsolo se il padre si trova nella stessa richiesta OTLP, quindi impostali manualmente su ogni span.
  5. Impostare microsoft.session.id su ogni intervallo quando si dispone di una sessione logica.
  6. Per le chiamate da agente a agente in cui l'agente figlio è in una richiesta separata, riutilizzare lo stesso gen_ai.conversation.id e usare gli attributi microsoft.a365.caller.agent.* (vedere riferimento degli attributi) per catturare il contesto dell'agente chiamante.

L'albero a quattro intervalli nell'esempio di esecuzione di Agent è la forma canonica.

Forme di esecuzione comuni

Forma Intervalli da generare Notes
Chatbot con agente singolo (senza strumenti, nessun intervallo LLM) Un invoke_agent solo Impostare gli attributi a livello di esecuzione più gen_ai.input.messages e gen_ai.output.messages. Identica alla richiesta più piccola possibile.
Agente con strumenti (più comuni) invoke_agent radice + chat, execute_tool, output_messages figli Tutti gli elementi figlio condividono il valore traceId della radice e impostano parentSpanId = root.spanId. Tutti contengono gli stessi attributi a livello di esecuzione. Vedere Esempio di esecuzione dell'agente per un esempio completo.
Da agente a agente Ogni agente genera il proprio invoke_agent Riutilizza lo stesso gen_ai.conversation.id per entrambi gli agenti. Nel invoke_agent di destinazione, imposta gen_ai.execution.type = "Agent2Agent" e gli attributi microsoft.a365.caller.agent.* (appId dell'agente chiamante, nome, modello appId, ID utente ed e-mail). Se l'agente chiamante non ha una registrazione Entra, utilizzare invece microsoft.a365.caller.agent.platform.id e gen_ai.caller.agent.type.

Checklist di inserimento

Consulta questa lista di controllo prima di passare in produzione.

Categoria Seleziona
Aut L'app Entra (o il progetto) è registrata ed è possibile coniare i token.
Aut Alla tua app sono stati concessi Agent365.Observability.OtelWrite (ruolo applicativo per S2S, ambito per autorizzazioni delegate).
Aut Ogni agente ha il proprio ID app di Entra come {agentId} nell'URL. Per le identità derivate dal blueprint, quell'appId è l'appId dell'identità dell'agente, non l'appId del blueprint. Se l'agente non dispone di una registrazione in Entra, vedi Scelta dei valori.
Aut Un amministratore del tenant ha concesso il consenso per Agent365.Observability.OtelWrite. Senza il consenso, i token vengono emessi senza il ruolo/ambito e le richieste vengono rifiutate con 403.
Licenze Almeno un utente nel tenant del cliente ha una licenza Microsoft 365 E7 o Microsoft Agent 365 assegnata (assegnazione, non solo presenza di SKU nel tenant). Senza una licenza assegnata, l'inserimento viene eliminato automaticamente. Vedere Prerequisiti.
Copertura Ogni span imposta gli elementi essenziali comuni all’intera esecuzione (gerarchia degli span e raggruppamento delle esecuzioni).
Copertura invoke_agent intervalli impostati gen_ai.input.messages e gen_ai.output.messages.
Copertura execute_tool insieme di intervalli gen_ai.tool.name, gen_ai.tool.type, gen_ai.tool.call.id, gen_ai.tool.call.arguments, gen_ai.tool.call.result.
Copertura chat insieme di intervalli gen_ai.request.model e gen_ai.provider.name (e idealmente gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - codificati come stringa).
Copertura Tutti gli span non radice hanno lo stesso parentSpanId; tutti gli span in una sequenza condividono lo stesso traceId.
Payload Il corpo della richiesta è ≤ 1 MB.
Verifica Analizzi partialSuccess su ogni risposta e registri i rifiuti nei log.
Verifica Hai eseguito il flusso di verifica in Verifica dell'acquisizione rispetto alle tue prime esecuzioni.

Passaggi successivi