Agent-Einblick mithilfe von direct OTel integrieren

Dieser Leitfaden führt Sie von Anfang bis Ende durch das Senden der Agententelemetrie direkt über OpenTelemetry (OTLP/HTTP+JSON) an Agent 365. Bevor Sie beginnen, lesen Sie die Einblick-Konzepte von Agent 365, um das Modell, die Authentifizierungsflüsse und die Ziele zu verstehen, in denen Ihre Daten landen.

Wichtig

Der direkte OTel-Pfad ist die Ausnahme, nicht der Standard. Nutzen Sie diesen Weg nur, wenn Sie bereits eine OpenTelemetry-Pipeline haben, Ihr Framework das Agent 365 SDK nicht verwenden kann oder Ihr Agent in einer Sprache geschrieben ist, die das SDK noch nicht unterstützt (z. B. Java). Für alle anderen ist der empfohlene Weg die Microsoft OpenTelemetry Distro, die ein einheitliches Einblick-SDK über Agent 365, Microsoft Foundry, Azure Monitor und mehr bereitstellt. Das frühere Einblick-SDK funktioniert weiter ohne Breaking Changes, ist aber nicht mehr der empfohlene Weg für neue Integrationen; Migrationsleitfaden für vorhandene SDK-Benutzer werden bereitgestellt.

Voraussetzungen

Stellen Sie sicher, dass die folgenden Konfigurationen vorhanden sind, bevor Telemetrie übertragen wird.

Wer Funktion
Mandantenadmin Registrieren Sie sich für Agent 365 und erteilen Sie Ihrer Agenten-App die Zustimmung. Siehe Onboarding bei Agent 365. Ohne lizenzierten Mandanten wird die Erfassung stillschweigend verworfen – die Anforderung gibt 200 OK mit partialSuccess: null zurück, aber die Daten tauschen in nachgelagerten Systemen nie auf.
Mandantenadmin Weisen Sie mindestens einem Benutzer im Mandant eine Microsoft 365 E7- oder Microsoft Agent 365-Lizenz zu. Dass die SKU vorhanden ist, reicht nicht aus. Die Zuweisung an einen Benutzer startet den Defender-Backend-Workflow, der die Aufnahme ermöglicht. Ohne zugewiesene Lizenz geben Anforderungen 200 OK mit partialSuccess: null zurück, und Daten werden stillschweigend verworfen.
Mandantenadmin Mandantenadministratoreinwilligung erteilen. Siehe Agenten Zugriff auf Microsoft 365-Ressourcen gewähren. Ohne diese Zustimmung werden Token ohne Rolle/Berechtigungsumfang ausgegeben und Anfragen geben 403 zurück.
Ihr Entwicklerteam Registrieren Sie Ihre App (Standard-Microsoft Entra-App oder Blueprint). Siehe Erste Schritte mit Agent 365 Entwicklung.
Ihr Entwicklerteam Fügen Sie Agent365.Observability.OtelWrite unter API-Berechtigungen hinzu (App-Rolle für S2S, Berechtigungsbereich für Delegierte). Für Blueprints siehe Vererbbare Berechtigungen konfigurieren. Stimmen Sie sich mit dem Agent 365 Onboarding-Team ab, um die Berechtigung zu aktivieren.

Authentifizierungsrezepte

Alle vier Methoden verwenden den Standard-Microsoft Entra-Token-Endpunkt:

Feld Wert
Tokenendpunkt https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Ressource (aud im zurückgegebenen Token) 9b975845-388f-4429-889e-eab1ef63949c (akzeptiert auch api://9b975845-388f-4429-889e-eab1ef63949c)
S2S-Umfang 9b975845-388f-4429-889e-eab1ef63949c/.default
OBO-Umfang 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

Die untenstehenden Rezepte zeigen rohes HTTP zur Klarheit. Für den produktiven Einsatz empfiehlt es sich, Microsoft.Identity.Web oder eine andere MSAL-Bibliothek zu verwenden, die das Aktualisieren und Zwischenspeichern von Tokens übernimmt.

Welches Rezept brauche ich?

Mein App-Modell Mein OAuth-Flow Gehe zu
Standard Microsoft Entra-App-Registrierung S2S (Client-Anmeldeinformationen) S2S, standardmäßige Microsoft Entra-App
Standard Microsoft Entra-App-Registrierung OBO (delegiert) OBO standardmäßige Microsoft Entra-App
Blueprint-abgeleitete Agentenidentität S2S (Client-Anmeldeinformationen) S2S, Blueprint-abgeleitete Agentenidentität
Blueprint-abgeleitete Agentenidentität OBO / KI-Teamkollege OBO, Blueprint-abgeleitete Agentenidentität

S2S, standardmäßige Microsoft Entra-App

Ein POST an den Token-Endpunkt des Mandants mit grant_type=client_credentials. Authentifizieren Sie die App, indem Sie ein Client-Geheimnis, ein Zertifikat (signierte JWT-Assertion) oder eine verwaltete Identität oder föderierte Zugangsdaten verwenden.

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

Das Token hat appid/azp = {your-app-id}, roles mit Agent365.Observability.OtelWrite und aud = 9b975845-... zurückgegeben. Verwenden Sie es auf der /observabilityService/.../traces Route.

Bei zertifikatsbasierter Authentifizierung ersetzen Sie client_secret={secret} durch client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}.

S2S, Blueprint-abgeleitete Agentenidentität

Agent-Identitäten besitzen keine eigenen Anmeldeinformationen. Der Blueprint für die Agent-Identität enthält die Anmeldeinformationen (FIC für verwaltete Identitäten, Zertifikat oder geheimen Clientschlüssel) und stellt Token im Auftrag der untergeordneten Agent-Identitäten über einen zweistufigen Austausch bereit. Weitere Informationen finden Sie in OAuth-Flow für autonome Apps.

  1. Der Blueprint authentifiziert sich und erhält ein föderiertes Identitätsaustausch-Token T1:

    • {blueprint-credential} ist der MSI-Token des Blueprints, eine zertifikatssignierte JWT oder eine geheime Exchange-Token-Assertion – gemäß Blueprint-Konfiguration.
    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. Die Agent-Identität tauscht T1 gegen das Ressourcentoken für Agent 365 Einblick ein:

    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
    
    • Das Token hat appid/azp = {agent-identity-app-id}, roles mit Agent365.Observability.OtelWrite und aud = 9b975845-... zurückgegeben.
    • Verwenden Sie dieses Token auf der /observabilityService/.../traces Route.
    • Die URL {agentId} ist die Agent Identity appID, nicht die Blueprint appID.

OBO, standardmäßige Microsoft Entra-App

Empfangen Sie das eingehende Token Tc des Nutzers von Ihrem Upstream-Aufrufer (Bearer oder PFAT) und tauschen Sie es dann aus:

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

Für die Zertifikatsauthentifizierung ersetzen Sie client_secret={secret} durch das gleiche client_assertion_type + client_assertion-Paar wie bei S2S.

Das Token hat appid/azp = {your-app-id}, scp mit Agent365.Observability.OtelWrite und aud = 9b975845-... zurückgegeben. Verwenden Sie es auf der /observability/.../traces Route. Ein Aktualisierungstoken wird mitgeliefert; speichern Sie es im Cache und verwenden Sie es wieder, anstatt den Austausch bei jedem Aufruf erneut durchzuführen.

OBO, Blueprint-abgeleitete Agentenidentität (einschließlich KI-Teammitglied)

Es gibt drei Hauptschritte des On-Behalf-Of-Flusses. Weitere Informationen finden Sie unter Agent OAuth-Flow: Im Auftrag von Flow.

  1. Empfangen Sie das Benutzertoken Tc. Für ein KI-Teammitglied steht dieses Token für das eigene Benutzerkonto des Agenten; andernfalls steht es für den menschlichen Anrufer.

  2. Der Blueprint authentifiziert sich und erhält T1, genauso wie beim S2S-Blueprint-abgeleiteten Agentenidentitäts-Flow.

  3. Die Agentenidentität tauscht T1 und Tc gegen ein delegiertes Ressourcentoken aus:

    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
    

Das zurückgegebene Token hat appid/azp = {agent-identity-app-id}, scp containing Agent365.Observability.OtelWrite und zeigt den Benutzer des Agents an. Verwenden Sie es auf der /observability/.../traces Route. Die URL {agentId} ist die Agent Identity appID, nicht die Blueprint appID. Ein Refresh-Token wird zusätzlich zurückgegeben; speichern Sie es im Cache und verwenden Sie es erneut.

Erforderliche Claims im zurückgegebenen Token

S2S-Route (/observabilityService/...) - Nur-App-Token:

Anspruch Erforderlicher Wert
aud 9b975845-388f-4429-889e-eab1ef63949c (oder api://9b975845-...)
roles Muss Agent365.Observability.OtelWrite enthalten
appid (v1) oder azp (v2) Muss mit der URL {agentId} übereinstimmen
scp Darf nicht vorhanden sein

Delegierte Route (/observability/...) - Benutzerdelegiertes Token (Bearer oder PFAT):

Anspruch Erforderlicher Wert
aud 9b975845-388f-4429-889e-eab1ef63949c (oder api://9b975845-...)
scp Muss Agent365.Observability.OtelWrite enthalten
appid / azp Muss mit der URL {agentId} übereinstimmen

Die delegierte Route akzeptiert sowohl Bearer als auch MSAuth1.0 PFAT Token. Direkte Aufrufer sollten Bearer verwenden. Falls Sie nicht wissen, welches Sie haben, verwenden Sie Bearer.

Endpunkte

Zwei Routen; wählen Sie anhand der Art, wie Ihr Dienst authentifiziert wird, nicht danach, was der Benutzer tut:

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

Header:

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

URL-Parameter

  • {tenantId} – Kundenmandanten-GUID. Der Server behandelt dies als maßgeblich; wenn Ihre Spans die microsoft.tenant.id festlegen und keine Übereinstimmung vorliegt, wird die Anforderung abgelehnt.
  • {agentId} - die App-ID der aufrufenden Anwendung (auch OAuth client_id). Bei aus Blueprints abgeleiteten Identitäten ist dies die appID der Agent-Identität, nicht die appID des Blueprints. Muss dem appid / azp Anspruch des Tokens entsprechen.
  • api-version=1 - Erforderlich.

Anforderungstext codieren

Der Textkörper hat die Standardstruktur von OTLP/HTTP+JSON: eine ExportTraceServiceRequest mit resourceSpansscopeSpansspans. Beachten Sie folgende Prinzipien:

  • traceId (16 Byte) und spanId (8 Byte) werden als Hex-Zeichenfolgen in Kleinbuchstaben gesendet.
  • startTimeUnixNano / endTimeUnixNano sind Zeichenfolgen, die Nanosekunden der Unix-Epoche speichern.
  • kind ist der ganzzahlige OTLP-Enumerationswert (z. B. 1 für INTERNAL); status.code ist die ganzzahlige Enumeration (z. B. 1 für OK, 2 für ERROR).
  • Alle Attributwerte werden im Format stringValue übertragen.

Antwortstruktur

Ein erfolgreicher Aufruf gibt 200 OK zurück:

{ "partialSuccess": null }

Falls einige Spans vom span-spezifischen Filter abgelehnt wurden:

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

Feldnamen werden bei der Übertragung in camelCase geschrieben. Immer überprüfen partialSuccess: Eine 200 mit allen abgelehnten Spans ist ein echtes Ergebnis, das Sie anzeigen müssen. Grenzen und Bedingungen für das Verwerfen listet die Fälle stillschweigenden Verwerfens auf, in denen 200 mit partialSuccess: null zurückgegeben wird, obwohl nachgelagert keine Daten erscheinen.

Kleinstmögliche Anfrage

Der einfachste End-to-End-Test sendet einen einzelnen invoke_agent Span. Dieser Span ist der kleinste Textkörper, der in Microsoft Defender landet.

Schritt 1. Rufen Sie ein Bearer-Token ab. Verwenden Sie für S2S Clientanmeldeinformationen mit dem Bereich 9b975845-388f-4429-889e-eab1ef63949c/.default (siehe Authentifizierungsrezepte für das vollständige Rezept).

Schritt 2. POST einen einzelnen 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

Schritt 3. Mit diesem Textkörper erwarten wir 200 OK:

{ "partialSuccess": null }

Schritt 4. Prüfen Sie, ob die Daten tatsächlich gelandet sind. Ein 200 OK ist kein Beweis für die Aufnahme; Die Verifizierung der Aufnahme läuft durch den Verifikationsfluss. Um stattdessen eine gespeicherte Textdatei zu veröffentlichen, ersetzen Sie --data @- <<EOF ... EOF durch --data @./otlp-request.json.

Agent-Ausführungsbeispiel

Ein Benutzer auf Microsoft Teams fragt: „Wie ist das Wetter in Seattle?“. Ihr Agent ruft eine GetWeather Funktion auf, bittet ein LLM, die Antwort zu formatieren, und antwortet. Diese einzelne Ausführung umfasst vier 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

Ausführungsweite Attribute, die für jeden Span festgelegt sind:

Attribut Beispielwert
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

Wichtig

Diese laufweiten Attribute werden nicht automatisch weitergegeben. Sie müssen gen_ai.conversation.id, microsoft.channel.name und microsoft.session.id auf jedem Bereich selbst festlegen.

Bereich A: invoke_agent (Wurzel)

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

Bereich B: chat (LLM-Aufruf)

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

Senden von Telemetrie an

Verwendung eines OTel SDK

Die meisten Partner senden Ablaufverfolgungen über ein OTel-SDK statt über selbst implementiertes HTTP. Das SDK übernimmt das Batching, die Wiederholungsversuche und die OTLP/HTTP+JSON-Codierung. Setzen Sie den Exporter-Endpunkt und fügen Sie den Authorization Header hinzu.

Der Exporter-Endpunkt ist die Route-URL selbst, einschließlich der Abfrage-Zeichenfolge:

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

(Verwenden Sie /observability/... statt /observabilityService/... für die delegierte Route.)

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

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

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

Paket: OpenTelemetry.Exporter.OpenTelemetryProtocol.

HTTP manuell

Wenn Sie kein OTel-SDK verwenden können oder möchten, erstellen Sie die OTLP/HTTP+JSON-Anfrage selbst und senden Sie sie per POST. Die Körperform wird durch die OpenTelemetry OTLP/HTTP+JSON-Spezifikation definiert:

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

Jedes <span> ist ein Objekt, dessen erforderliche Felder traceId, spanId, name, kind, startTimeUnixNano, endTimeUnixNano, attributes und (für Nicht-Wurzelspans) parentSpanId sind. Siehe Endpunkte und Textkörper-Codierung anfordern für die Kodierregeln (zeichenkettenkodierte Zeiten, hexadezimale traceId / spanId, ganzzahlige kind / status.code, alle Attributwerte als stringValue).

Die Attribute, die für jeden Bereich gesetzt Greifen Sie auf die Copilot Studio Kit App zu, sind in Nachrichtenverträge definiert. Siehe Attributreferenz für die vollständige Attributliste. Unter Agent-Ausführungsbeispiel finden Sie ein End-to-End-Arbeitsbeispiel mit dem Bearertoken in der Kopfzeile und dem Textkörper inline.

Sie können alle Spans einer Ausführung in einem einzelnen POST-Textkörper (bevorzugt – eine Anforderung, eine Ablaufverfolgung) oder über mehrere POSTs senden. Der Server rekonstruiert den Lauf anhand von traceId + parentSpanId + gen_ai.conversation.id, damit jeder Bereich genug trägt, um in jede Richtung korreliert zu werden.

Meldungs-Verträge

In diesem Abschnitt wird definiert, welche Spans Sie erzeugen können und welche Attribute jeweils zu ihnen gehören. Die vollständige Attributspezifikation finden Sie in der Attributreferenz.

Vorgangstypen

Für jeden von Ihnen gesendeten Span muss gen_ai.operation.name einen dieser vier Werte aufweisen (Groß-/Kleinschreibung wird nicht beachtet). Alle Spans mit einem fehlenden oder nicht erkannten Wert werden im Hintergrund gelöscht und bei partialSuccess.rejectedSpans mitgezählt.

gen_ai.operation.name Bedeutung Meistgegoogelter Fallstrick
invoke_agent Ein Aufruf eines Agenten. Der „Stamm“ einer Agent-Ausführung. Erforderlich, damit die Ausführung in den Microsoft Defender Agent-Aktivitätsansichten oder im Microsoft 365 Admin Center angezeigt wird. Ohne dies landet die Telemetrie nur in Microsoft Defender Advanced Hunting (CloudAppEvents).
execute_tool Ein Tool- oder Funktionsaufruf, der von einem Agenten ausgeführt wird. --
chat An LLM-Ableitungsaufrufe. Verwenden Sie das wörtliche chat, NICHT inference.
output_messages Eine letzte ausgesendete Ausgabemeldung. --

Siehe Bereichs-Hierarchie und Ausführungsgruppierung

Agent 365 rekonstruiert eine Ausführung aus dem Standard-OTLP-Bereichs-Graph (traceId, spanId, parentSpanId) plus den laufweiten Attributen aus der Attributreferenz.

Sechs Regeln:

  1. Immer festlegen parentSpanId für jeden Span, der kein Stammelement ist. Ohne dieses Attribut kann die Baumstruktur der Ausführung nicht rekonstruiert werden.
  2. Verwenden Sie dieselbe traceId über alle Spans in einer Ausführung hinweg.
  3. Legen Sie gen_ai.conversation.id auf jeden Bereich mit dem selben Wert. Dies ist der primäre Verknüpfungsschlüssel für „alle Spans in dieser Ausführung“. Es wird nicht automatisch propagiert.
  4. Legen Sie microsoft.channel.name auf jeden Bereich mit dem selben Wert fest. Tool-Spans, in denen der Kanal bzw. die Unterhaltung fehlen, können diese von ihrem übergeordneten invoke_agentnur dann erben, wenn sich das übergeordnete Element in derselben OTLP-Anforderung befindet. Legen Sie sie daher für jeden Span selbst fest.
  5. Legen Sie microsoft.session.id für jeden Span fest, wenn Sie eine logische Sitzung haben.
  6. Verwenden Sie für Agent-zu-Agent-Aufrufe, bei denen sich der untergeordnete Agent in einer separaten Anforderung befindet, dieselbe gen_ai.conversation.id wieder, und verwenden Sie die microsoft.a365.caller.agent.*-Attribute (siehe Attributreferenz), um den Kontext des aufrufenden Agents zu erfassen.

Die Struktur aus vier Spans im Agent-Ausführungsbeispiel ist die kanonische Form.

Allgemeine Ausführungsformen

Form Auszugebende Spans Notizen
Einzelagent-Chatbot (keine Tools, kein LLM-Bereich) Nur ein invoke_agent Setzen Sie ausführungsweite Attribute plus gen_ai.input.messages und gen_ai.output.messages. Identisch mit der kleinstmöglichen Anfrage.
Agent mit Werkzeugen (am gebräuchlichsten) invoke_agent Stamm + chat, execute_tool, output_messages untergeordnete Elemente Alle untergeordneten Elemente verwenden die traceId des Stammelements und legen parentSpanId = root.spanId fest. Alle tragen dieselben ausführungsweiten Attribute. Siehe Agent Ausführungsbeispiel für ein vollständiges Beispiel.
Agent-zu-Agent Jeder Agent sendet sein eigenes invoke_agent aus Verwenden Sie denselben gen_ai.conversation.id für beide Agenten. Legen Sie für den invoke_agent des Ziels gen_ai.execution.type = "Agent2Agent" und die microsoft.a365.caller.agent.*-Attribute fest (die appId des aufrufenden Agents, den Namen, die Blueprint-appId, die Benutzer-ID und die E-Mail-Adresse). Wenn der aufrufende Agent keine Entra-Registrierung hat, verwenden Sie microsoft.a365.caller.agent.platform.id und gen_ai.caller.agent.type stattdessen.

Onboarding-Checkliste

Gehen Sie diese Checkliste durch, bevor Sie in den Produktivbetrieb gehen.

Kategorie Überprüfen
-Authentifizierung Die Entra-App (oder der Blueprint) ist registriert und es können Token dafür generiert werden.
-Authentifizierung Ihrer App wurde Agent365.Observability.OtelWrite zugewiesen (App-Rolle für S2S, Umfang für delegierte Aktionen).
Authentifizierung Jeder Agent hat seine eigene Entra appID, wie {agentId} in der URL angegeben. Bei aus Blueprints abgeleiteten Identitäten ist dies die appID der Agent-Identität, nicht die appID des Blueprints. Wenn der Agent keine Entra-Registrierung hat, siehe Werte auswählen.
Authentifizierung Ein Mandantenadministrator hat Zustimmung für Agent365.Observability.OtelWrite erteilt. Ohne Zustimmung werden Token ohne Rolle oder Berechtigungsbereich generiert und Anfragen werden mit 403 abgelehnt.
Lizenzierung Mindestens ein Benutzer im Kundenmandant hat eine Microsoft 365 E7- oder Microsoft Agent 365-Lizenz zugewiesen (Zuweisung, nicht nur Vorhandensein der SKU im Tenant). Ohne zugewiesene Lizenz wird die Erfassung stillschweigend verworfen. Siehe Voraussetzungen.
Spans Jeder Span definiert die ausführungsweiten Grundlagen (Span-Hierarchie und Ausführungsgruppierung).
Spans invoke_agent-Spans legen gen_ai.input.messages und gen_ai.output.messages fest.
Spans execute_tool-Spans legen gen_ai.tool.name, gen_ai.tool.type, gen_ai.tool.call.id, gen_ai.tool.call.arguments, gen_ai.tool.call.result fest.
Spans chat-Spans legen gen_ai.request.model und gen_ai.provider.name fest (und idealerweise gen_ai.usage.input_tokens / gen_ai.usage.output_tokens – als Zeichenfolge codiert).
Spans Alle Nicht-Stamm-Spans legen parentSpanId fest; alle Spans in einer Ausführung haben dieselbe traceId.
Payload Der Anforderungskörper ist ≤ 1 MB.
Verifizierung Sie parsen partialSuccess bei jeder Antwort und Ablehnungen werden protokolliert.
Verifizierung Sie haben den Verifizierungsprozess im Abschnitt Überprüfungserfassung mit Ihren ersten Durchläufen ausgeführt.

Nächste Schritte,

  • Attributreferenz – Spezifikation pro Attribut und Leitfaden zur Wertauswahl.
  • Fehlerbehebung – Überprüfung der Erfassung, häufige Fallstricke und Fehlerantworten.