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 Schritt für Schritt durch den gesamten Prozess des Sendens von Agent-Telemetrie an Agent 365 direkt über OpenTelemetry (OTLP/HTTP+JSON). Bevor Sie beginnen, lesen Sie die Konzepte der Agent 365-Observierbarkeit , um das Modell zu verstehen, die Authentifizierungsflüsse und die Oberflächen, in die Ihre Daten gelangen.
Important
Der direkte OTel-Pfad ist die Ausnahme, nicht der Standardwert. Verwenden Sie sie nur, wenn Sie bereits über eine OpenTelemetry-Pipeline verfügen, kann Ihr Framework das Agent 365 SDK nicht verwenden, oder Ihr Agent befindet sich in einer Sprache, die das SDK noch nicht unterstützt (z. B. Java). Für alle anderen ist der empfohlene Pfad der Microsoft OpenTelemetry Distro, der ein einheitliches Observability SDK für Agent 365, Microsoft Foundry, Azure Monitor und vieles mehr bereitstellt. Das frühere Observability SDK funktioniert weiterhin, ohne Änderungen zu unterbrechen, wird jedoch nicht mehr für neue Integrationen empfohlen. Migrationsleitfaden für vorhandene SDK-Benutzer werden bereitgestellt.
Prerequisites
Stellen Sie sicher, dass die folgenden Konfigurationen eingerichtet sind, bevor Telemetriedaten übertragen werden.
| Wer | What |
|---|---|
| Mandantenadministrator | Registrieren Sie sich für Agent 365, und erteilen Sie Ihrer Agent-App die Zustimmung. Weitere Informationen finden Sie unter Einführung in 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. |
| Mandantenadministrator |
Weisen Sie mindestens einem Benutzer im Mandanten eine Microsoft 365 E7- oder eine Microsoft Agent 365-Lizenz zu. Die vorhandene SKU reicht nicht aus. Die Zuweisung zu einem Benutzer startet den Defender Back-End-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 Grant Agents Zugriff auf Microsoft 365 Ressourcen. Andernfalls werden Token ohne Rolle/Bereich ausgegeben, und Anfragen geben 403 zurück. |
| Ihr Entwicklerteam | Registrieren Sie Ihre App (Standard-Microsoft Entra App oder Blueprint). Weitere Informationen finden Sie unter "Erste Schritte mit der Agent 365-Entwicklung". |
| Ihr Entwicklerteam | Fügen Sie Agent365.Observability.OtelWrite unter API-Berechtigungen hinzu (App-Rolle für S2S, Berechtigungsbereich für delegierte Berechtigungen). Informationen zu Blueprints finden Sie unter Konfigurieren vererbbarer Berechtigungen. Stimmen Sie sich mit dem Agent 365-Onboarding-Team ab, um die Berechtigung zu aktivieren. |
Authentifizierungsrezepte
Alle vier Rezepte verwenden den standardmäßigen Microsoft Entra Tokenendpunkt:
| 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-Geltungsbereich | 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite |
Die nachstehenden Rezepte zeigen unformatiertes HTTP zur Übersichtlichkeit. Bevorzugen Sie in der Produktion Microsoft. Identity.Web oder eine andere MSAL-Bibliothek, die die Tokenaktualisierung und -zwischenspeicherung verarbeitet.
Welches Rezept benötige ich?
| Mein App-Modell | Mein OAuth-Fluss | Gehe zu |
|---|---|---|
| Standard-Microsoft Entra-App-Registrierung | S2S (Clientanmeldeinformationen) | S2S, Standard Microsoft Entra App |
| Standard-Microsoft Entra-App-Registrierung | OBO (delegiert) | OBO, Standard Microsoft Entra App |
| Vom Blueprint abgeleitete Agentidentität | S2S (Clientanmeldeinformationen) | S2S, Vom Blueprint abgeleitete Agentidentität |
| Vom Blueprint abgeleitete Agentidentität | OBO / KI-Teammitglied | OBO, Vom Blueprint abgeleitete Agentidentität |
S2S, Standard Microsoft Entra App
Ein POST an den Tokenendpunkt des Mandanten mit grant_type=client_credentials. Authentifizieren Sie die App mithilfe eines geheimen Clientschlüssels, eines Zertifikats (signierter JWT-Assertion) oder einer verwalteten Identität oder Verbundanmeldeinformationen.
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 zurückgegebene Token enthält appid/azp = {your-app-id}, roles enthält Agent365.Observability.OtelWriteund .aud = 9b975845-... Verwenden Sie es auf der /observabilityService/.../traces-Route.
Ersetzen Sie für die zertifikatbasierte Authentifizierung client_secret={secret} durch client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}.
S2S, Vom Blueprint abgeleitete Agentidentitä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 unter OAuth-Ablauf für eigenständige Apps.
Der Blueprint authentifiziert sich und ruft ein Verbundidentitätsaustauschtoken
T1ab:-
{blueprint-credential}ist das MSI-Token, das zertifikatsignierte JWT oder die geheime Exchange-Token-Assertion des Blueprints – je nach 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 Observability 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 zurückgegebene Token enthält
appid/azp={agent-identity-app-id},rolesenthältAgent365.Observability.OtelWriteund .aud=9b975845-... - Verwenden Sie dieses Token auf der
/observabilityService/.../tracesRoute. - Die URL
{agentId}ist die Agent-Identitäts-appId, nicht die Blueprint-AppId.
- Das zurückgegebene Token enthält
OBO, standardmäßige Microsoft Entra-App
Empfangen Sie das eingehende Token Tc des Benutzers von Ihrem upstream-Aufrufer (Bearer oder PFAT), und tauschen Sie es 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
Ersetzen Sie bei der Zertifikatauthentifizierung client_secret={secret} durch dasselbe client_assertion_type + client_assertion-Paar wie bei S2S.
Das zurückgegebene Token enthält appid/azp = {your-app-id}, scp enthält Agent365.Observability.OtelWriteund .aud = 9b975845-... Verwenden Sie sie auf der /observability/.../traces Route. Zusätzlich wird ein Refresh-Token zurückgegeben; speichern Sie es im Cache und verwenden Sie es wieder, anstatt den Austauschvorgang bei jedem Aufruf erneut auszuführen.
OBO, Vom Blueprint abgeleitete Agentidentität (einschließlich KI-Teamkollegen)
Es gibt drei Hauptschritte des On-Behalf-Of-Flusses. Weitere Informationen finden Sie unter "Agent OAuth flows: On behalf of flow".
Empfangen des Benutzertokens
Tc. Für einen KI-Teamkollegen stellt dieses Token das eigene Benutzerkonto des Agenten dar; andernfalls stellt sie den menschlichen Aufrufer dar.Das Blueprint authentifiziert sich und ruft
T1ab, genauso wie der aus dem S2S-Blueprint abgeleitete Agent-Identitätsfluss.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 enthält appid/azp = {agent-identity-app-id}, scp enthält Agent365.Observability.OtelWriteund stellt den Benutzer des Agents dar. Verwenden Sie es für die /observability/.../traces-Route. Die URL {agentId} ist die Agent-Identitäts-appId, nicht die Blueprint-AppId. Daneben wird ein Aktualisierungstoken zurückgegeben; zwischenspeichern und wiederverwenden.
Erforderliche Ansprüche für das zurückgegebene 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 URL entsprechen {agentId} |
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 gleich URL {agentId} sein |
Die delegierte Route akzeptiert sowohl Bearer- als auch MSAuth1.0 PFAT-Token. Direkte Anrufer sollten verwenden Bearer. Wenn Sie nicht wissen, welches Sie haben, verwenden Sie Bearer.
Endpoints
Zwei Routen; wählen Sie aus, wie Sich Ihr Dienst authentifiziert, nicht durch die Aktionen des Benutzers:
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
Kopfzeilen:
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 appId 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 mit demappid/azpClaim Ihres Tokens übereinstimmen. -
api-version=1- erforderlich.
Kodierung des Anfragetexts
Der Textkörper hat die Standardstruktur von OTLP/HTTP+JSON: eine ExportTraceServiceRequest mit resourceSpans → scopeSpans → spans. Beachten Sie die folgenden Details:
-
traceId(16 Byte) undspanId(8 Byte) werden als hexadezimale Zeichenfolgen in Kleinbuchstaben gesendet. -
startTimeUnixNano/endTimeUnixNanosind Zeichenfolgen , die Unix-Epochen-Nanosekunden enthalten. -
kindist der ganzzahlige OTLP-Enumerationswert (z. B.1fürINTERNAL);status.codeist die ganzzahlige Enumeration (z. B.1fürOK,2fürERROR). - Alle Attributwerte werden als
stringValuegesendet.
Antwortform
Ein erfolgreicher Aufruf gibt folgendes zurück 200 OK:
{ "partialSuccess": null }
Wenn einige Textspannen durch den Filter pro Textspanne 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.
Kleinste mögliche Anforderung
Der einfachste End-to-End-Test sendet eine einzelne invoke_agent Spanne. 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. Eine einzelne Spanne per POST senden:
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. Bestätigen Sie, dass die Daten tatsächlich gelandet sind. Ein 200 OK ist kein Nachweis für die Erfassung; Erfassung verifizieren erläutert den Verifizierungsablauf. Um stattdessen eine gespeicherte Body-Datei zu POSTEN, ersetzen Sie --data @- <<EOF ... EOF durch --data @./otlp-request.json.
Agent-Ausführungsbeispiel
Ein Benutzer auf Microsoft Teams fragt "Was ist das Wetter in Seattle?". Ihr Agent ruft eine GetWeather Funktion auf, bittet ein LLM, die Antwort zu formatieren, und antwortet. Dieser einzelne Lauf umfasst vier Abschnitte:
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:
| Merkmal | 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 |
Important
Diese laufweiten Attribute werden nicht automatisch verteilt. Sie müssen gen_ai.conversation.id, microsoft.channel.name und microsoft.session.id für jeden Span selbst festlegen.
Span 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 */
]
}
Span 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
Verwenden eines OTel-SDK
Die meisten Partner senden Ablaufverfolgungen über ein OTel-SDK statt über selbst implementiertes HTTP. Das SDK übernimmt für Sie die Stapelverarbeitung, Wiederholungsversuche und die OTLP/HTTP+JSON-Kodierung. Legen Sie den Exporter-Endpunkt fest und fügen Sie den Authorization-Header ein.
Der Exporterendpunkt ist die Routen-URL selbst, einschließlich der Abfragezeichenfolge:
https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1
(Verwenden Sie /observability/... anstelle von /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 Struktur des Nachrichtentexts 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> Objekt ist ein Objekt, dessen erforderliche Felder sind traceId, , spanId, name, kind, startTimeUnixNano, endTimeUnixNano, , und attributes(für Nicht-Stamm-Spans) parentSpanId. Siehe Endpunkte und Kodierung des Anforderungstexts für die Kodierungsregeln (als Zeichenfolge kodierte Zeitangaben, Hex traceId / spanId, Ganzzahlen kind / status.code, alle Attributwerte als stringValue).
Der Satz von Attributen, die für jeden Bereich festgelegt werden sollen, wird in Nachrichtenverträgen 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 Ablauf anhand von traceId + parentSpanId + gen_ai.conversation.id, sodass jeder Span genügend Informationen enthält, um in beide Richtungen korreliert werden zu können.
Nachrichtenverträge
In diesem Abschnitt wird definiert, welche Spans Sie erzeugen können und welche Attribute jeweils zu ihnen gehören. Die vollständige Attribut-nach-Attribut-Spezifikation 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 | Der meistgesuchte Fallstrick |
|---|---|---|
invoke_agent |
Aufruf eines Agenten. Der „Stamm“ einer Agent-Ausführung. | Erforderlich, damit die Ausführung in den Microsoft Defender-Ansichten zur Agentenaktivität oder im Microsoft 365 Admin Center angezeigt wird. Ohne sie landet die Telemetrie nur in der erweiterten Suche von Microsoft Defender (CloudAppEvents). |
execute_tool |
Ein Tool-/Funktionsaufruf, der von einem Agent ausgeführt wird. | -- |
chat |
Ein LLM-Inferenzaufruf. |
Verwenden Sie das Literal chat, NICHT inference. |
output_messages |
Eine abschließende ausgegebene Meldung. | -- |
Span-Hierarchie und Run-Gruppierung
Agent 365 rekonstruiert einen Lauf aus dem Standard-OTLP-Span-Graphen (traceId, spanId, parentSpanId) sowie den für den Lauf geltenden Attributen aus der Attributreferenz.
Sechs Regeln:
-
Immer festlegen
parentSpanIdfür jeden Span, der kein Stammelement ist. Ohne sie kann die Baumstruktur des Laufs nicht rekonstruiert werden. -
Verwenden Sie dieselbe
traceIdüber alle Spans in einer Ausführung hinweg. -
Legen Sie
gen_ai.conversation.idfür jeden Bereich mit demselben Wert fest. Dies ist der primäre Verknüpfungsschlüssel für „alle Spans in dieser Ausführung“. Sie wird nicht automatisch weitergegeben. -
Legen Sie
microsoft.channel.namefür jeden Bereich mit demselben 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
| Gestalt | Auszugebende Spans | Hinweise |
|---|---|---|
| Einzel-Agent-Chatbot (keine Tools, keine LLM-Spanne) | Nur ein invoke_agent |
Legen Sie run-weite Attribute sowie gen_ai.input.messages und gen_ai.output.messages fest. Identisch mit der kleinsten möglichen Anforderung. |
| Agent mit Tools (am häufigsten) |
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 weisen dieselben Attribute für den gesamten Textlauf auf. Ein vollständiges Beispiel finden Sie unter Beispiel für einen Agentenlauf. |
| Agent-zu-Agenten | Jeder Agent emittiert seine eigene invoke_agent |
Verwenden Sie dasselbe gen_ai.conversation.id für beide Agents. 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 über keine Entra-Registrierung verfügt, verwenden Sie stattdessen microsoft.a365.caller.agent.platform.id und gen_ai.caller.agent.type. |
Checkliste für die Einarbeitung
Führen Sie diese Checkliste durch, bevor Sie zur Produktion wechseln.
| Kategorie | Überprüfen |
|---|---|
| Authentifizierung | Ihre Entra-App (oder Ihr Blueprint) ist registriert und Sie können dafür Tokens erstellen. |
| Authentifizierung | Ihrer App wurde Agent365.Observability.OtelWrite zugewiesen (App-Rolle für S2S, Umfang für delegierte Aktionen). |
| Authentifizierung | Jeder Agent verfügt über eine eigene Entra-appId als {agentId} in der URL. 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 die Einwilligung für Agent365.Observability.OtelWrite erteilt. Ohne Zustimmung werden Token ohne Rolle/Bereich ausgegeben, und Anforderungen werden mit 403abgelehnt. |
| Lizenzierung | Mindestens ein Benutzer im Kundenmandanten verfügt über eine Microsoft 365 E7- oder Microsoft Agent 365-Lizenz zugewiesen (Zuordnung, nicht nur SKU-Anwesenheit im Mandanten). Ohne zugewiesene Lizenz wird die Erfassung stillschweigend verworfen. Siehe Voraussetzungen. |
| Spannweiten | Jeder Span definiert die ausführungsweiten Grundlagen (Span-Hierarchie und Ausführungsgruppierung). |
| Spannweiten |
invoke_agent-Spans legen gen_ai.input.messages und gen_ai.output.messages fest. |
| Spannweiten |
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. |
| Spannweiten |
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). |
| Spannweiten | Alle Nicht-Stamm-Spans legen parentSpanId fest; alle Spans in einer Ausführung haben dieselbe traceId. |
| Nutzlast | Der Anfragetextkörper ist ≤ 1 MB. |
| Überprüfung | Sie analysieren partialSuccess bei jeder Antwort und protokollieren Zurückweisungen. |
| Überprüfung | Sie haben den Verifizierungsablauf in Verifying ingestion anhand Ihrer ersten Durchläufe ausgeführt. |
Nächste Schritte
- Attributreferenz – Spezifikation je Attribut und Leitfaden zur Wertauswahl.
- Problembehandlung : Überprüfen der Aufnahme, allgemeiner Fallstricke und Fehlerantworten.