Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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.
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-
Tożsamość agenta wymienia
T1na 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},rolesktóry zawieraAgent365.Observability.OtelWrite, orazaud=9b975845-.... - Użyj tego tokena na ścieżce
/observabilityService/.../traces. - URL
{agentId}to tożsamości agenta (appId), a nie appId blueprintu.
- Zwrócony token posiada
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.
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ą.Blueprint uwierzytelnia się i uzyskuje
T1, tak samo jak w przepływie tożsamości agenta pochodzącym od blueprintu S2S.Tożsamość agenta wymienia
T1iTcna 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 ustawionomicrosoft.tenant.idi wartość ta się nie zgadza, żądanie zostaje odrzucone. -
{agentId}- appId aplikacji wywołującej appId (to także appId OAuthclient_id). W przypadku tożsamości pochodzących z blueprintu, to identyfikator agenta appId, a nie blueprint appId. Musi być równy atrybutowiappid/azptwojego tokena. -
api-version=1- wymagane
Kodowanie treści żądania
Ciało żądania ma standardowy układ OTLP/HTTP+JSON: obiekt ExportTraceServiceRequest zawierający resourceSpans → scopeSpans → spans. Należy pamiętać o następujących zasadach:
-
traceId(16 bajtów) orazspanId(8 bajtów) są wysyłane jako ciągi znaków w zapisie szesnastkowym małymi literami. -
startTimeUnixNano/endTimeUnixNanosą ciągami zawierającymi nanosekundy epoki Uniksa. -
kindjest liczbą całkowitą reprezentującą wartość wyliczeniową OTLP (na przykład1dlaINTERNAL);status.codejest liczbą całkowitą reprezentującą wartość wyliczeniową (na przykład1dlaOK,2dlaERROR). - 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:
-
Zawsze ustawiaj
parentSpanIdna każdym spanie nie będącym korzeniem. Bez niej struktura drzewa przebiegu nie może być odtworzona. -
Używaj tego samego
traceIdwe wszystkich spanach w jednym przebiegu. -
Ustaw
gen_ai.conversation.idna 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. -
Ustaw
microsoft.channel.namena 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ędnyminvoke_agenttylko, jeśli element nadrzędny jest w tym samym żądaniu OTLP, dlatego ustaw je samodzielnie na każdym spanie. -
Ustaw
microsoft.session.idna każdym spanie, gdy masz sesję logiczną. - W przypadku wywołań agent-do-agenta, gdzie agent podrzędny znajduje się w osobnym żądaniu, użyj tego samego
gen_ai.conversation.idi skorzystaj z atrybutówmicrosoft.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
- Referencja atrybutów – specyfikacja i wskazówki dotyczące wyboru wartości dla każdego atrybutu.
- Rozwiązywanie problemów – weryfikacja pobrania, typowych pułapek i odpowiedzi na błędy.