Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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.
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-
Die Agent-Identität tauscht
T1gegen 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},rolesmitAgent365.Observability.OtelWriteundaud=9b975845-...zurückgegeben. - Verwenden Sie dieses Token auf der
/observabilityService/.../tracesRoute. - Die URL
{agentId}ist die Agent Identity appID, nicht die Blueprint appID.
- Das Token hat
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.
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.Der Blueprint authentifiziert sich und erhält
T1, genauso wie beim S2S-Blueprint-abgeleiteten Agentenidentitäts-Flow.Die Agentenidentität tauscht
T1undTcgegen 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 diemicrosoft.tenant.idfestlegen und keine Übereinstimmung vorliegt, wird die Anforderung abgelehnt. -
{agentId}- die App-ID der aufrufenden Anwendung (auch OAuthclient_id). Bei aus Blueprints abgeleiteten Identitäten ist dies die appID der Agent-Identität, nicht die appID des Blueprints. Muss demappid/azpAnspruch des Tokens entsprechen. -
api-version=1- Erforderlich.
Anforderungstext codieren
Der Textkörper hat die Standardstruktur von OTLP/HTTP+JSON: eine ExportTraceServiceRequest mit resourceSpans → scopeSpans → spans. Beachten Sie folgende Prinzipien:
-
traceId(16 Byte) undspanId(8 Byte) werden als Hex-Zeichenfolgen in Kleinbuchstaben gesendet. -
startTimeUnixNano/endTimeUnixNanosind Zeichenfolgen, die Nanosekunden der Unix-Epoche speichern. -
kindist der ganzzahlige OTLP-Enumerationswert (z. B.1fürINTERNAL);status.codeist die ganzzahlige Enumeration (z. B.1fürOK,2fürERROR). - 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:
-
Immer festlegen
parentSpanIdfür jeden Span, der kein Stammelement ist. Ohne dieses Attribut kann die Baumstruktur der Ausführung nicht rekonstruiert werden. -
Verwenden Sie dieselbe
traceIdüber alle Spans in einer Ausführung hinweg. -
Legen Sie
gen_ai.conversation.idauf 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. -
Legen Sie
microsoft.channel.nameauf jeden Bereich mit dem selben Wert fest. Tool-Spans, in denen der Kanal bzw. die Unterhaltung fehlen, können diese von ihrem übergeordneteninvoke_agentnur dann erben, wenn sich das übergeordnete Element in derselben OTLP-Anforderung befindet. Legen Sie sie daher für jeden Span selbst fest. -
Legen Sie
microsoft.session.idfür jeden Span fest, wenn Sie eine logische Sitzung haben. - Verwenden Sie für Agent-zu-Agent-Aufrufe, bei denen sich der untergeordnete Agent in einer separaten Anforderung befindet, dieselbe
gen_ai.conversation.idwieder, und verwenden Sie diemicrosoft.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.