Integrare l'osservabilità dell'agente con OTel diretto

Questa guida ti accompagna passo dopo passo nell'invio della telemetria dell'agente direttamente ad Agent 365 tramite OpenTelemetry (OTLP/HTTP+JSON). Prima di iniziare, leggi i concetti di osservabilità di Agent 365 per comprendere il modello, i flussi di autenticazione e le superfici in cui arrivano i tuoi dati.

Importante

Il percorso OTel diretto è l'eccezione, non quello predefinito. Utilizza questa modalità solo se disponi già di una pipeline OpenTelemetry, se il tuo framework non può utilizzare l'Agent 365 SDK oppure se il tuo agente è scritto in un linguaggio che l'SDK non supporta ancora (come Java). Per tutti gli altri, il percorso consigliato è Microsoft OpenTelemetry Distro, che offre un SDK di osservabilità unificato su Agent 365, Microsoft Foundry, Monitoraggio di Azure e altro ancora. Il precedente Observability SDK continua a funzionare senza modifiche incompatibili, ma non è più raccomandato per nuove integrazioni; stanno arrivando linee guida sulla migrazione per gli utenti SDK esistenti.

Prerequisiti

Assicurati che le seguenti configurazioni siano impostate prima dell'invio di qualsiasi telemetria.

Chi Informazioni
Amministratore tenant Accedi ad Agent 365 e concedi il consenso per la tua app dell'agente. Vedi Eseguire l'onboarding ad Agent 365. Senza un tenant con licenza, l'inserimento viene interrotto silenziosamente: la richiesta restituisce 200 OK con partialSuccess: null, ma i dati non appaiono mai a valle.
Amministratore tenant Assegna una licenza Microsoft 365 E7 o Microsoft Agent 365 ad almeno un utente nel tenant. La presenza dello SKU non basta. L'assegnazione a un utente avvia il flusso di lavoro backend di Defender che consente l’inserimento. Senza una licenza assegnata, le richieste restituiscono 200 OK con partialSuccess: null e i dati vengono scartati silenziosamente.
Amministratore tenant Concedi il consenso del tenant. Vedi Concedi agli agenti l'accesso alle risorse di Microsoft 365. Senza di esso, i token vengono emessi senza ruolo/scope e le richieste restituiscono 403.
Il tuo team di sviluppo Registra la tua app (app standard Microsoft Entra o progetto). Vedi Introduzione allo sviluppo con Agent 365.
Il tuo team di sviluppo Aggiungere Agent365.Observability.OtelWrite sotto Autorizzazioni API (il ruolo app per S2S, l'ambito per l'accesso delegato). Per i progetti, consulta Configura permessi ereditabili. Coordina con il team di onboarding di Agent 365 per abilitare il permesso.

Ricette di autenticazione

Tutti e quattro i metodi utilizzano l'endpoint del token standard di Microsoft Entra:

Campo Valore
Endpoint token https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Risorsa (aud nel token restituito) 9b975845-388f-4429-889e-eab1ef63949c (accetta anche api://9b975845-388f-4429-889e-eab1ef63949c)
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 chiarezza. In produzione, si consiglia di usare Microsoft.Identity.Web o un'altra libreria MSAL, che gestisce l'aggiornamento dei token e la memorizzazione nella cache.

Quale ricetta mi serve?

Il mio modello di app Il mio flusso OAuth Vai a
Registrazione dell'app Microsoft Entra standard S2S (credenziali del client) S2S, app Microsoft Entra standard
Registrazione dell'app Microsoft Entra standard OBO (delegato) OBO, app Microsoft Entra standard
Identità agente derivata da Blueprint S2S (credenziali del client) S2S, identità agente derivata da Blueprint
Identità agente derivata da Blueprint Assistente IA/OBO OBO, identità agente derivata da Blueprint

S2S, app Microsoft Entra standard

Un POST per l'endpoint del token del tenant con grant_type=client_credentials. Autentica l'app utilizzando un client secret, un certificato (asserzione JWT firmata) o un'identità gestita o una credenziale federata.

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}, roles contenente Agent365.Observability.OtelWrite, e aud = 9b975845-.... Usalo nel percorso /observabilityService/.../traces.

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

S2S, identità dell'agente derivata da Blueprint

Le identità degli agenti non dispongono di credenziali proprie. 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à degli agenti figlio tramite uno scambio in due fasi. Per ulteriori informazioni, consulta Flusso OAuth dell'app autonoma.

  1. Il blueprint esegue l'autenticazione e ottiene un token di scambio di identità federato T1:

    • {blueprint-credential} è il token MSI del blueprint, il token JWT firmato con certificato o l'asserzione exchange-token segreto, 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 scambia T1 per il token di risorsa 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}, roles contenente Agent365.Observability.OtelWrite, e aud = 9b975845-....
    • Usa questo token sulla route /observabilityService/.../traces.
    • L'URL {agentId} è l'appId dell'identità dell'agente, non l'appId del blueprint.

OBO, app Microsoft Entra standard

Ricevi il token in ingresso Tc dell'utente dal tuo chiamante upstream (Bearer o PFAT), quindi effettua lo scambio:

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 tramite certificato, sostituisci client_secret={secret} con la stessa coppia client_assertion_type + client_assertion come in S2S.

Il token restituito ha appid/azp = {your-app-id}, scp contenente Agent365.Observability.OtelWrite, e aud = 9b975845-.... Usalo nel percorso /observability/.../traces. Viene restituito anche un refresh token; memorizzalo e riutilizzalo invece di ripetere lo scambio ad ogni chiamata.

OBO, identità dell'agente derivata dal progetto (incluso assistente AI)

Esistono tre passaggi principali del flusso On-Behalf-Of. Per altre informazioni, vedi Flussi OAuth dell'agente: per conto del flusso.

  1. Ricevi il token utente Tc. Per un assistente AI, questo token rappresenta l'account utente proprio dell'agente; altrimenti, rappresenta il chiamante umano.

  2. Il progetto si autentica e ottiene T1, come nel flusso di identità dell'agente S2S derivato dal progetto.

  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 che contiene Agent365.Observability.OtelWrite e rappresenta l'utente dell'agente. Usalo nel percorso /observability/.../traces. L'URL {agentId} è l'appId dell'identità dell'agente, non l'appId del blueprint. Viene restituito anche un token di aggiornamento; memorizzalo e riutilizzalo.

Attestazioni richieste sul token restituito

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

Attestazione Valore richiesto
aud 9b975845-388f-4429-889e-eab1ef63949c (o api://9b975845-...)
roles Deve contenere Agent365.Observability.OtelWrite
appid (v1) o azp (v2) Deve corrispondere all’URL {agentId}
scp Deve essere assente

Instradamento delegato (/observability/...): token delegato dall'utente (Bearer o PFAT):

Attestazione Valore richiesto
aud 9b975845-388f-4429-889e-eab1ef63949c (o api://9b975845-...)
scp Deve contenere Agent365.Observability.OtelWrite
appid / azp Deve corrispondere all’URL {agentId}

La route delegata accetta sia i token Bearer che MSAuth1.0 PFAT. I chiamanti diretti dovrebbero usare Bearer. Se non sai quale hai, usa Bearer.

Endpoint

Due route: scegli in base a come il tuo servizio si autentica, non a ciò che fa l'utente:

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} - l'appId dell'applicazione chiamante (anche come OAuth client_id). Per le identità derivate da blueprint, si tratta dell'appId dell'identità dell'agente, non dell'appId del progetto. Deve corrispondere all'attestazione appid / azp del tuo token.
  • api-version=1 - obbligatorio.

Codifica del corpo della richiesta

Il corpo ha la forma standard OTLP/HTTP+JSON: un ExportTraceServiceRequest con resourceSpansscopeSpansspans. Tieni presente i seguenti dettagli:

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

Struttura della risposta

Una chiamata di successo restituisce 200 OK:

{ "partialSuccess": null }

Se alcuni span sono stati rifiutati dal filtro per span:

{
  "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 eliminazione elenca i casi di eliminazione silenziosa in cui viene restituito un 200 con partialSuccess: null nonostante nessun dato sia disponibile a valle.

Richiesta minima possibile

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

Passaggio 1. Ottieni un token di connessione. Per S2S, usa le credenziali del client con ambito 9b975845-388f-4429-889e-eab1ef63949c/.default (vedi 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. Conferma che i dati sono effettivamente arrivati. Un 200 OK non è una prova di inserimento; La verifica dell'inserimento illustra il flusso di verifica. Per inviare un file del corpo salvato tramite POST, sostituisci --data @- <<EOF ... EOF con --data @./otlp-request.json.

Esempio di esecuzione dell’agente

Un utente su Microsoft Teams chiede: "Che tempo c'è a Seattle?". Il tuo agente chiama una funzione GetWeather, 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:

Attributo 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 gen_ai.conversation.id, microsoft.channel.name, e microsoft.session.id su ogni span.

Span A: invoke_agent (radice)

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

Intervallo 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 dei dati di telemetria

Uso di un SDK OTel

La maggior parte dei partner invia tracce attraverso un SDK OTel piuttosto che tramite richieste HTTP manuali. L'SDK gestisce batching, retry e la codifica OTLP/HTTP+JSON per te. Imposta l'endpoint dell’esportatore e inserisci l'intestazione Authorization.

L'endpoint dell'esportatore è l'URL della route, comprensivo della stringa di query:

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

Usa /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.

HTTP manuale

Se non puoi o non vuoi usare un SDK OTel, crea la richiesta OTLP/HTTP+JSON manualmente e inviala tramite POST. La struttura del corpo è definita dalla specifica OpenTelemetry OTLP/HTTP+JSON:

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

Ciascun <span> è un oggetto i cui campi obbligatori sono traceId, spanId, name, kind, startTimeUnixNano, endTimeUnixNano, attributes e, per gli span non radice, parentSpanId. Vedi Endpoint e Codifica del corpo della richiesta per le regole di codifica (tempi codificati per stringa, esadecimale traceId / spanId, intero kind / status.code, tutti i valori di attributi come stringValue).

L'insieme degli attributi da impostare su ciascuna span è definito in Contratti di messaggi. Vedi Riferimento agli attributi per l'elenco completo degli attributi. Fai riferimento ad Esempio di esecuzione dell'agente per un esempio di lavoro end-to-end con il token di connessione nell'intestazione e nel corpo inline.

Puoi inviare tutti gli span di un run in un unico corpo POST (preferito - una richiesta, una traccia) oppure tramite 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 messaggi

Questa sezione definisce quali span è possibile emettere e quali attributi applicare a ciascuno. Per la specifica completa attributo per attributo, vedi il Riferimento agli attributi.

Tipi di operazione

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

gen_ai.operation.name Significato Trucco più cercato su Google
invoke_agent Un'invocazione di un agente. La "radice" di un'esecuzione dell'agente. Necessaria affinché l'esecuzione venga visualizzata nelle viste attività dell'agente di Microsoft Defender o nell'interfaccia di amministrazione di Microsoft 365. Senza di essa, la telemetria si trova solo nella ricerca avanzata di Microsoft Defender (CloudAppEvents).
execute_tool Una chiamata a uno strumento o funzione eseguita da un agente. --
chat Chiamata di inferenza LLM. Usa il valore letterale chat, NON inference.
output_messages Un messaggio di output finale emesso. --

Gerarchia degli span e raggruppamento delle esecuzioni

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 radice. Senza di esso, la struttura ad albero della run non può essere ricostruita.
  2. Riutilizza lo stesso traceId in ogni span di un'esecuzione.
  3. Imposta gen_ai.conversation.id su ogni span con lo stesso valore. Si tratta della chiave di unione primaria per "tutti gli intervalli in questa esecuzione". Non viene propagato automaticamente.
  4. Imposta microsoft.channel.name su ogni span 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. Imposta microsoft.session.id su ogni intervallo quando si dispone di una sessione logica.
  6. Per le chiamate da agente ad agente in cui l'agente figlio si trova in una richiesta separata, riutilizza lo stesso gen_ai.conversation.id e usa gli attributi microsoft.a365.caller.agent.* (consulta Riferimento agli attributi) per acquisire il contesto dell'agente chiamante.

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

Forme di esecuzione comuni

Forma Intervalli da generare Note
Chatbot ad agente singolo (nessuno strumento, nessuno span LLM) Solo un invoke_agent Impostare gli attributi a livello di esecuzione più gen_ai.input.messages e gen_ai.output.messages. Identico alla richiesta più piccola possibile.
Agente con strumenti (il più comune) Radice invoke_agent + 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. Consulta l'esempio di esecuzione dell'agente per un esempio completo.
Da agente ad agente Ogni agente emette il proprio invoke_agent Riutilizza lo stesso gen_ai.conversation.id per entrambi gli agenti. In 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, usa microsoft.a365.caller.agent.platform.id e gen_ai.caller.agent.type.

Elenco di controllo di onboarding

Esegui questo elenco di controllo prima di passare alla produzione.

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

Passaggi successivi