Integruj wgląd agentów bezpośrednio przez OTel

Ten przewodnik prowadzi krok po kroku przez proces wysyłania telemetrii agenta bezpośrednio do Agent 365 za pomocą OpenTelemetry (OTLP/HTTP+JSON). Przed rozpoczęciem przeczytaj koncepcje obserwowalności Agent 365, aby zrozumieć model, przepływy uwierzytelniania oraz obszary, do których trafiają Twoje dane.

Ważne

Bezpośredni wariant OTel jest wyjątkiem, a nie domyślnym rozwiązaniem. Używaj tej ścieżki tylko wtedy, gdy masz już pipeline OpenTelemetry, Twoja struktura nie może korzystać z SDK Agent 365 lub Twój agent jest napisany w języku, którego SDK jeszcze nie wspiera (na przykład Java). Dla wszystkich innych zalecaną ścieżką jest Microsoft OpenTelemetry Distro, która zapewnia zunifikowane SDK obserwowalności w Agent 365, Microsoft Foundry, Azure Monitor oraz innych. Wcześniejsze Observability SDK nadal działa bez zmian powodujących niezgodność, ale nie jest już zalecane do nowych integracji; wytyczne dotyczące migracji dla obecnych użytkowników SDK pojawią się wkrótce.

Wymagania wstępne

Upewnij się, że poniższe konfiguracje zostały wdrożone przed rozpoczęciem przesyłania telemetrii.

Kto Co
Administrator dzierżawy Zarejestruj się w Agent 365 i udziel zgody dla swojej aplikacji agenta. Zapoznaj się z Konfiguracja Agent 365. Bez licencjonowanego dzierżawcy, pobranie jest po cichu odrzucana – żądanie zwraca 200 OK z partialSuccess: null, ale dane nigdy nie pojawiają się w dalszych etapach.
Administrator dzierżawy Przypisz licencję Microsoft 365 E7 lub Microsoft Agent 365 co najmniej jednemu użytkownikowi w dzierżawcy. Sama obecność SKU nie wystarcza. Przypisanie do użytkownika uruchamia workflow backendu Defendera, który umożliwia pobieranie danych. Bez przypisanej licencji żądania zwracają 200 OK z partialSuccess: null, a dane są ignorowane bez powiadomienia.
Administrator dzierżawy Udziel zgody dzierżawie. Zobacz Udziel agentom dostępu do zasobów Microsoft 365. Bez tego tokeny są wydawane bez roli/zakresu, a żądania zwracają 403.
Twój zespół programistyczny Zarejestruj swoją aplikację (standardową aplikację Microsoft Entra lub blueprint). Zobacz Rozpocznij rozwój Agent 365.
Twój zespół programistyczny Dodaj Agent365.Observability.OtelWrite w sekcji uprawnień API (rola aplikacji dla S2S, zakres dla delegowanych). Dla blueprintów zobacz Konfigurowanie dziedzicznych uprawnień. Współpracuj z zespołem wdrożeniowym Agent 365, aby włączyć wymagane uprawnienie.

Przepisy uwierzytelniające

Wszystkie cztery scenariusze korzystają ze standardowego endpointu tokena Microsoft Entra:

Pole Value
Punkt końcowy tokenu https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Zasób (aud w zwróconym tokenie) 9b975845-388f-4429-889e-eab1ef63949c (również akceptuje api://9b975845-388f-4429-889e-eab1ef63949c)
Zakres S2S 9b975845-388f-4429-889e-eab1ef63949c/.default
Zakres OBO 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

Poniższe przepisy pokazują surowy HTTP dla jasności. W środowisku produkcyjnym zaleca się korzystać z Microsoft.Identity.Web lub innej biblioteki MSAL, która obsługuje odświeżanie i buforowanie tokenów.

Którego przepisu potrzebuję?

Mój model aplikacji Mój przepływ OAuth Przejdź do
Standardowa rejestracja aplikacji Microsoft Entra S2S (dane uwierzytelniające klienta) S2S, standardowa aplikacja Microsoft Entra
Standardowa rejestracja aplikacji Microsoft Entra OBO (delegowany) OBO, standardowa aplikacja Microsoft Entra
Tożsamość agenta utworzona na podstawie Blueprintu S2S (dane uwierzytelniające klienta) S2S, tożsamość agenta utworzona na podstawie Blueprintu
Tożsamość agenta utworzona na podstawie Blueprintu OBO / współpracownik AI OBO, tożsamość agenta utworzona na podstawie Blueprintu

S2S, standardowa aplikacja Microsoft Entra

Jeden POST do punktu końcowego tokenu dzierżawcy z grant_type=client_credentials. Uwierzytelnij aplikację za pomocą sekretu klienta, certyfikatu (podpisanej asercji JWT), tożsamości zarządzanej lub federacyjnego poświadczenia.

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

Zwrócony token posiada appid/azp = {your-app-id}, roles który zawiera Agent365.Observability.OtelWrite, oraz aud = 9b975845-.... Użyj go na ścieżce /observabilityService/.../traces.

W przypadku uwierzytelniania opartego na certyfikacie, zastąp client_secret={secret} z client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}.

S2S, tożsamość agenta utworzona na podstawie Blueprintu

Tożsamości agentów nie posiadają własnych danych uwierzytelniających. Blueprint tożsamości agenta przechowuje dane uwierzytelniające (zarządzaną tożsamość FIC, certyfikat lub sekret klienta) i wystawia tokeny w imieniu swoich tożsamości agentów podrzędnych poprzez dwuetapową wymianę. Aby uzyskać więcej informacji, zobacz przepływ OAuth aplikacji autonomicznej.

  1. Blueprint uwierzytelnia się i otrzymuje federowany token wymiany tożsamości T1:

    • {blueprint-credential} to token MSI blueprintu, JWT podpisany certyfikatem lub asercja tokena typu secret exchange-token, zgodnie z konfiguracją blueprintu.
    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. Tożsamość agenta wymienia T1 na token zasobu Obserwacji Agent 365:

    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
    
    • Zwrócony token posiada appid/azp = {agent-identity-app-id}, roles który zawiera Agent365.Observability.OtelWrite, oraz aud = 9b975845-....
    • Użyj tego tokena na ścieżce /observabilityService/.../traces.
    • URL {agentId} to tożsamości agenta (appId), a nie appId blueprintu.

OBO, standardowa aplikacja Microsoft Entra

Odbierz przychodzący token użytkownika Tc od swojego klienta nadrzędnego (Bearer lub PFAT), a następnie wymień go:

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

W przypadku uwierzytelniania certyfikatem zamień client_secret={secret} na tę samą parę client_assertion_type + client_assertion jak w S2S.

Zwrócony token posiada appid/azp = {your-app-id}, scp który zawiera Agent365.Observability.OtelWrite, oraz aud = 9b975845-.... Użyj go na ścieżce /observability/.../traces. Token odświeżający jest zwracany razem z odpowiedzią; buforuj go i używaj ponownie zamiast ponownie przeprowadzać wymianę przy każdym wywołaniu.

OBO, tożsamość agenta pochodząca z Blueprinta (w tym współpracownik AI)

Istnieją trzy główne kroki w przepływie on-behalf-of (OBO). Więcej informacji znajdziesz w Agent OAuth flows: On behalf of flow.

  1. Otrzymaj token Tcużytkownika. Dla AI współpracownika ten token reprezentuje własne konto użytkownika agenta; w przeciwnym razie reprezentuje osobę wywołującą.

  2. Blueprint uwierzytelnia się i uzyskuje T1, tak samo jak w przepływie tożsamości agenta pochodzącym od blueprintu S2S.

  3. Tożsamość agenta wymienia T1 i Tc na token zasobu z uprawnieniami delegowanymi:

    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
    

Zwrócony token ma appid/azp = {agent-identity-app-id}, scp zawierający Agent365.Observability.OtelWrite, i reprezentuje użytkownika agenta. Użyj go na ścieżce /observability/.../traces. URL {agentId} to tożsamości agenta (appId), a nie appId blueprintu. Dodatkowo zwracany jest token odświeżający; zachowaj go i wykorzystaj ponownie.

Wymagane roszczenia na zwróconym tokenie

Trasa S2S (/observabilityService/...) - token aplikacyjny:

Oświadczenie Wymagana wartość
aud 9b975845-388f-4429-889e-eab1ef63949c (lub api://9b975845-...)
roles Musi zawierać Agent365.Observability.OtelWrite
appid (v1) lub azp (v2) Musi być równy URL {agentId}
scp Musi być nieobecny

Delegowana trasa (/observability/...) – token delegowany przez użytkownika (Bearer lub PFAT):

Oświadczenie Wymagana wartość
aud 9b975845-388f-4429-889e-eab1ef63949c (lub api://9b975845-...)
scp Musi zawierać Agent365.Observability.OtelWrite
appid / azp Musi być równy URL {agentId}

Delegowana trasa akceptuje zarówno tokeny Bearer, jak i tokeny MSAuth1.0 PFAT. Podmioty wywołujące bezpośrednio powinny używać Bearer. Jeśli nie wiesz, którym tokenem dysponujesz, użyj Bearer.

Punkty końcowe

Dwie trasy; wybierz według sposobu uwierzytelniania usługi, a nie tego, co robi użytkownik:

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

Nagłówki:

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

parametry adresów URL

  • {tenantId} – identyfikator GUID dzierżawcy klienta. Serwer traktuje ten parametr jako autorytatywny; jeśli w Twoich spanach ustawiono microsoft.tenant.id i wartość ta się nie zgadza, żądanie zostaje odrzucone.
  • {agentId} - appId aplikacji wywołującej appId (to także appId OAuth client_id). W przypadku tożsamości pochodzących z blueprintu, to identyfikator agenta appId, a nie blueprint appId. Musi być równy atrybutowi appid / azp twojego tokena.
  • api-version=1 - wymagane

Kodowanie treści żądania

Ciało żądania ma standardowy układ OTLP/HTTP+JSON: obiekt ExportTraceServiceRequest zawierający resourceSpansscopeSpansspans. Należy pamiętać o następujących zasadach:

  • traceId (16 bajtów) oraz spanId (8 bajtów) są wysyłane jako ciągi znaków w zapisie szesnastkowym małymi literami.
  • startTimeUnixNano / endTimeUnixNanociągami zawierającymi nanosekundy epoki Uniksa.
  • kind jest liczbą całkowitą reprezentującą wartość wyliczeniową OTLP (na przykład 1 dla INTERNAL); status.code jest liczbą całkowitą reprezentującą wartość wyliczeniową (na przykład 1 dla OK, 2 dla ERROR).
  • Wszystkie wartości atrybutów są wysyłane jako stringValue.

Struktura odpowiedzi

Udane wywołanie zwraca 200 OK:

{ "partialSuccess": null }

Jeśli niektóre spany zostały odrzucone przez filtr dla pojedynczych spanów:

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

Nazwy pól są zapisane w camelCase w komunikacji. Zawsze sprawdzaj partialSuccess: otrzymanie 200, gdy wszystkie Twoje spany zostały odrzucone, to rzeczywisty scenariusz, który musisz zgłosić. Limity i warunki porzucenia wymieniają ciche przypadki porzucenia, w których 200 wraca mimo partialSuccess: null braku danych w dalszej części strumienia.

Najmniejsze możliwe żądanie

Najprostszy test end-to-end wysyła pojedynczy span invoke_agent. Ten span to najmniejszy obiekt, który trafia do Microsoft Defender.

Krok 1. Uzyskaj token elementu nośnego. Dla S2S użyj poświadczeń klienta z spanem 9b975845-388f-4429-889e-eab1ef63949c/.default (zobacz przykłady uwierzytelniania dla pełnej instrukcji).

Krok 2. Wyślij pojedynczy span metodą POST:

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

Krok 3. Oczekuj 200 OK z taką treścią:

{ "partialSuccess": null }

Krok 4. Potwierdź, że dane faktycznie zostały zaimportowane. 200 OK nie jest dowodem zaimportowania danych; Weryfikacja zaimportowania opisuje proces weryfikacji. Aby POST zapisany plik treści, zastąp --data @- <<EOF ... EOF za pomocą --data @./otlp-request.json.

Przykład uruchomienia agenta

Użytkownik na Microsoft Teams pyta: „Jaka jest pogoda w Seattle?”. Twój agent wywołuje funkcję GetWeather, zleca LLM sformatowanie odpowiedzi i odpowiada. Ten pojedynczy przebieg składa się z czterech spanów:

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

Atrybuty całego biegu ustawione na każdym spanie:

Atrybut Przykładowa wartość
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

Ważne

Te atrybuty obejmujące cały bieg nie są propagowane automatycznie. Musisz ustawić gen_ai.conversation.id, microsoft.channel.name, i microsoft.session.id na każdym spanie.

Span A: invoke_agent (poziom główny)

{
  "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 (wywołanie 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 */
  ]
}

Wysyłanie danych telemetrycznych

Korzystanie z OTel SDK

Większość partnerów wysyła ślady przez OTel SDK, a nie ręcznie implementowane HTTP. SDK obsługuje batch procesy, próby i kodowanie OTLP/HTTP+JSON za ciebie. Ustaw endpoint eksportera i wstrzyknij nagłówek Authorization.

Endpoint eksportera jest adresem URL trasy, włącznie z ciągiem zapytania.

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

(W przypadku delegowanej trasy używaj /observability/... zamiast /observabilityService/....)

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

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

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

Pakiet: OpenTelemetry.Exporter.OpenTelemetryProtocol.

Ręczne HTTP

Jeśli nie możesz lub nie chcesz używać OTel SDK, zbuduj żądanie OTLP/HTTP+JSON samodzielnie i wyślij je metodą POST. Struktura treści jest określona przez specyfikację OpenTelemetry OTLP/HTTP+JSON:

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

Każdy <span> jest obiektem, którego wymagane pola to traceId, spanId, name, kind, startTimeUnixNano, endTimeUnixNano, attributes, a (dla spanów nie-root) parentSpanId. Odwołaj się do Endpointów oraz Kodowania treści żądania w celu zapoznania się z zasadami kodowania (czasy zakodowane jako string, liczby w formacie hex traceId / spanId, liczby całkowite kind / status.code, wszystkie wartości atrybutów jako stringValue).

Zestaw atrybutów, które należy ustawić na każdym spanie, jest określony w kontraktach wiadomości. Pełną listę atrybutów można znaleźć w Opisie atrybutów. Odwołaj się do przykładu uruchomienia Agenta, aby zobaczyć kompletny przykład działania z tokenem Bearer w nagłówku i treścią żądania bezpośrednio w ciele.

Możesz wysłać wszystkie spany jednego przebiegu w jednym ciele POST (zalecane – jedno żądanie, jeden ślad) lub rozdzielić je na wiele POST-ów. Serwer odtwarza przebieg na podstawie traceId + parentSpanId + gen_ai.conversation.id, dzięki czemu każdy span zawiera wystarczające atrybuty, aby można było go skorelować bez względu na sposób przesyłania.

Kontrakty komunikacyjne

Ta sekcja określa, jakie rozpięcia możesz emitować i które atrybuty są na każdym z nich. Pełną specyfikację atrybutów znajdziesz w Odniesieniu do atrybutów.

Rodzaje operacji

Każdy span, który wysyłasz, musi mieć gen_ai.operation.name ustawiony na jedną z tych czterech wartości (niezależnie od wielkości liter). Każdy span z brakującą lub nierozpoznaną wartością jest odrzucony bez powiadomienia i liczony w partialSuccess.rejectedSpans.

gen_ai.operation.name Znaczenie Najczęściej wyszukiwane w Google "łapanie"
invoke_agent Wywołanie agenta. "Root" uruchomienia agenta. Wymagane, aby uruchomienie pojawiło się w widokach aktywności agentów Microsoft Defender lub w Centrum administracyjnym Microsoft 365. Bez niego telemetria trafia tylko do Microsoft Defender Advanced Hunting (CloudAppEvents).
execute_tool Wywołanie narzędzia lub funkcji przez agenta. --
chat Wywołanie inferencji LLM. Używaj dosłownego chat, NIE inference.
output_messages Końcowy komunikat wyjściowy. --

Hierarchia spanów i grupowanie runów

Agent 365 rekonstruuje przebieg ze standardowego grafu rozpięć OTLP (traceId, spanId, parentSpanId) oraz atrybutów całego biegu z odniesienia do atrybutów.

Sześć zasad:

  1. Zawsze ustawiaj parentSpanId na każdym spanie nie będącym korzeniem. Bez niej struktura drzewa przebiegu nie może być odtworzona.
  2. Używaj tego samego traceId we wszystkich spanach w jednym przebiegu.
  3. Ustaw gen_ai.conversation.id na każdym spanie z tą samą wartością. To jest główny klucz łączenia dla wszystkich spanów w tym uruchomieniu. Nie jest propagowana automatycznie.
  4. Ustaw microsoft.channel.name na każdym spanie z tą samą wartością. Spany narzędzi, które nie mają ustawionego kanału lub rozmowy, mogą je odziedziczyć po elemencie nadrzędnym invoke_agenttylko, jeśli element nadrzędny jest w tym samym żądaniu OTLP, dlatego ustaw je samodzielnie na każdym spanie.
  5. Ustaw microsoft.session.id na każdym spanie, gdy masz sesję logiczną.
  6. W przypadku wywołań agent-do-agenta, gdzie agent podrzędny znajduje się w osobnym żądaniu, użyj tego samego gen_ai.conversation.id i skorzystaj z atrybutów microsoft.a365.caller.agent.* (zobacz dokumentację atrybutów), aby uchwycić kontekst agenta wywołującego.

Drzewo czterospanowe w przykładzie „Agent run” jest kanonicznym wzorcem.

Typowe kształty biegów

Kształt Spany do wysłania Uwagi
Czatbot z pojedynczym agentem (bez narzędzi, bez spanów LLM) Tylko jedno invoke_agent Ustaw atrybuty globalne dla uruchomienia plus gen_ai.input.messages i gen_ai.output.messages. Identyczne jak najmniejsza możliwa prośba.
Agent z narzędziami (najczęściej spotykany) invoke_agent korzeń + chat, execute_tool, output_messages elementy podrzędne Wszystkie elementy podrzędne dziedziczą traceId od korzenia i ustawiają parentSpanId = root.spanId. Wszystkie posiadają identyczne atrybuty w ramach uruchomienia. Zobacz Przykład uruchomienia agenta dla kompletnego przykładu.
Połączenie agent-agent Każdy agent emituje własne invoke_agent Użyj tego samego gen_ai.conversation.id dla obu agentów. Na docelowym invoke_agent ustaw gen_ai.execution.type = "Agent2Agent" oraz atrybuty microsoft.a365.caller.agent.* (agenta wywołującego appId, nazwę, blueprint appId, identyfikator użytkownika i adres e-mail). Jeśli agent wywołujący nie ma rejestracji Entra, użyj microsoft.a365.caller.agent.platform.id i gen_ai.caller.agent.type zamiast tego.

Lista kontrolna onboardingu

Sprawdź tę listę kontrolną przed wdrożeniem na produkcję.

Kategoria Sprawdzanie
Auth Twoja aplikacja Entra (lub blueprint) jest zarejestrowana i możesz wygenerować dla niej tokeny.
Auth Twoja aplikacja otrzymała Agent365.Observability.OtelWrite (rola aplikacyjna dla S2S, zakres dla delegowanych).
Auth Każdy agent ma własny Entra appId, tak jak {agentId} w URL. W przypadku tożsamości wywodzących się z blueprintów, ten appId jest appId tożsamości agenta, a nie appId blueprintu. Jeśli agent nie jest zarejestrowany w Entra, zobacz Wybieranie wartości.
Auth Administrator tenantu udzielił zgody dla Agent365.Observability.OtelWrite. Bez zgody tokeny są wydawane bez roli/zakresu, a żądania są odrzucane z 403.
Licencja Co najmniej jeden użytkownik w tenantcie klienta ma przypisaną licencję Microsoft 365 E7 lub Microsoft Agent 365 (przypisanie, nie tylko obecność SKU w tenantcie). Jeśli licencja nie została przypisana, telemetria jest pomijana bez powiadomienia. Zobacz Wymagania wstępne.
Spany Każdy zakres ustala podstawowe zasady całego cyklu (hierarchię rozłącza i grupowanie serii).
Spany invoke_agent Spany ustawiają gen_ai.input.messages oraz gen_ai.output.messages.
Spany execute_toolrozpiętości ustalone gen_ai.tool.name, gen_ai.tool.type, gen_ai.tool.call.id, gen_ai.tool.call.arguments, . gen_ai.tool.call.result
Spany chat span ustawia gen_ai.request.model oraz gen_ai.provider.name (i najlepiej także gen_ai.usage.input_tokens / gen_ai.usage.output_tokens – kodowane jako ciągi znaków).
Spany Wszystkie nie-rootowe span-y ustawiają parentSpanId; wszystkie span-y w runie mają ten sam traceId.
Ładunek Treść żądania nie przekracza 1 MB.
Weryfikacja Parsujesz partialSuccess każdą odpowiedź i logujesz odmowy.
Weryfikacja Przeprowadziłeś proces weryfikacji w Verifying Ingestion na podstawie pierwszych przebiegów.

Następne kroki