ダイレクト OTel を使用してエージェントの可観測性を統合する

このガイドでは、OpenTelemetry (OTLP/HTTP+JSON) 経由でエージェント テレメトリをエージェント 365 に直接送信する方法をエンド ツー エンドで説明します。 開始する前に、 Agent 365 の可観測性の概念 を読んで、モデル、認証フロー、およびデータが格納されているサーフェスを理解してください。

Important

OTel の直接パスは例外であり、既定値ではありません。 既に OpenTelemetry パイプラインがある場合、フレームワークで Agent 365 SDK を使用できない場合、またはエージェントが SDK でまだサポートされていない言語 (Java など) にある場合にのみ使用します。 他のすべてのユーザーに対して推奨されるパスは、Microsoft OpenTelemetry Distro です。これは、Agent 365、Microsoft Foundry、Azure Monitor などの統一された可観測性 SDK を提供します。 以前の Observability SDK は、変更を中断することなく引き続き動作しますが、新しい統合には推奨されなくなりました。既存の SDK ユーザー向けの移行ガイダンスが提供されます。

Prerequisites

テレメトリ フローの前に、次の構成が設定されていることを確認します。

What
テナント管理者 エージェント 365 にサインアップし、エージェント アプリに同意します。 エージェント 365 へのオンボードを参照してください。 ライセンスされたテナントがない場合、インジェストは自動的に削除されます。要求は200 OKpartialSuccess: null返しますが、データはダウンストリームに表示されません。
テナント管理者 少なくとも 1 人のユーザーに Microsoft 365 E7 または Microsoft Agent 365 ライセンスを割り当てます。 SKU が存在するだけでは不十分です。 ユーザーへの割り当てにより、インジェストを有効にするDefenderバックエンド ワークフローが開始されます。 割り当てられたライセンスがない場合、要求は200 OKpartialSuccess: nullを返し、データは自動的に削除されます。
テナント管理者 テナントの同意を付与します。 Microsoft 365 リソースへのエージェントアクセスを参照してください。 これを指定しないと、トークンはロール/スコープなしで発行され、要求は 403を返します。
開発チーム アプリ (標準Microsoft Entraアプリまたはブループリント) を登録します。 「エージェント 365 開発の開始」を参照してください。
開発チーム Agent365.Observability.OtelWrite (S2S のアプリ ロール、委任されたスコープ) にを追加します。 ブループリントについては、「 継承可能なアクセス許可の構成」を参照してください。 Agent 365 オンボード チームと調整して、アクセス許可を有効にします。

認証レシピ

4 つのレシピはすべて、標準のMicrosoft Entra トークン エンドポイントを使用します。

フィールド 価値
トークン エンドポイント https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
リソース (返されたトークン内のaud ) 9b975845-388f-4429-889e-eab1ef63949c ( api://9b975845-388f-4429-889e-eab1ef63949cも受け入れます)
S2S スコープ 9b975845-388f-4429-889e-eab1ef63949c/.default
OBO スコープ 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

以下のレシピは、わかりやすくするために生の HTTP を示しています。 運用環境では、Microsoftを優先します。Identity.Web またはトークンの更新とキャッシュを処理する別の MSAL ライブラリ。

どのレシピが必要ですか?

マイ アプリ モデル マイ OAuth フロー 移動先
Standard Microsoft Entra アプリの登録 S2S (クライアント資格情報) S2S、Standard Microsoft Entra アプリ
Standard Microsoft Entra アプリの登録 OBO (代理) OBO、標準 Microsoft Entra アプリ
ブループリント由来のエージェント識別子 S2S (クライアント資格情報) S2S、ブループリントから派生したエージェント ID
ブループリント由来のエージェント識別子 OBO / AI チームメイト OBO、ブループリントから派生したエージェント ID

S2S、Standard Microsoft Entra アプリ

grant_type=client_credentialsを使用してテナントのトークン エンドポイントに対する 1 つの POST。 クライアント シークレット、証明書 (署名された JWT アサーション)、またはマネージド ID またはフェデレーション資格情報を使用してアプリを認証します。

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

返されたトークンには、appidと/azp = を含む{your-app-id}rolesAgent365.Observability.OtelWriteaud = 9b975845-...があります。 /observabilityService/.../traces ルートで使用します。

証明書ベースの認証の場合は、 client_secret={secret}client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}に置き換えます。

S2S、ブループリントから派生したエージェント ID

エージェント ID には、独自の資格情報がありません。 エージェント ID ブループリントは、資格情報 (マネージド ID FIC、証明書、またはクライアント シークレット) を保持し、2 段階認証を通じて子エージェント ID に代わってトークンを作成します。 詳細については、 自律アプリの OAuth フローを参照してください。

  1. ブループリントは認証され、フェデレーション ID 交換トークン T1取得されます。

    • {blueprint-credential} はブループリントの MSI トークン、証明書署名済み JWT、またはシークレット交換トークン アサーションです。ブループリント構成ごと。
    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. エージェント ID は、Agent 365 Observability リソース トークンの T1 を交換します。

    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
    
    • 返されたトークンには、appidと/azp = を含む{agent-identity-app-id}rolesAgent365.Observability.OtelWriteaud = 9b975845-...があります。
    • /observabilityService/.../traces ルートでこのトークンを使用します。
    • URL {agentId} は、エージェント ID の appId であり、ブループリントの appId ではありません。

OBO、Standard Microsoft Entra アプリ

アップストリームの呼び出し元 (Bearer または PFAT) からユーザーの受信トークン Tc を受け取り、交換します。

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

証明書認証の場合は、 client_secret={secret} を S2S と同じ client_assertion_type + client_assertion ペアに置き換えます。

返されたトークンには、appidと/azp = を含む{your-app-id}scpAgent365.Observability.OtelWriteaud = 9b975845-...があります。 /observability/.../traces ルートで使用します。 更新トークンが一緒に返されます。キャッシュし、すべての呼び出しで交換を再実行する代わりにそれを再利用します。

OBO、ブループリントから派生したエージェント ID (AI チームメイトを含む)

代理フローには、主に 3 つの手順があります。 詳細については、「 エージェント OAuth フロー: フローの代理」を参照してください。

  1. ユーザー トークン Tcを受け取ります。 AI チームメイトの場合、このトークンはエージェント自身のユーザー アカウントを表します。それ以外の場合は、人間の呼び出し元を表します。

  2. ブループリントは、S2S のブループリント由来のエージェント ID フローと同様に、認証を行って T1 を取得します。

  3. エージェント ID は、委任されたリソース トークンの T1Tc を交換します。

    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
    

返されるトークンには、appidを含む/azp = {agent-identity-app-id}scpAgent365.Observability.OtelWriteがあり、エージェントのユーザーを表します。 /observability/.../traces ルートで使用します。 URL {agentId} は、ブループリントの appId ではなく、エージェント ID の appIdです。 更新トークンが一緒に返されます。キャッシュして再利用します。

返されたトークンの必須クレーム

S2S ルート (/observabilityService/...) - アプリ専用トークン:

請求 必須の値
aud 9b975845-388f-4429-889e-eab1ef63949c (または api://9b975845-...)
roles Agent365.Observability.OtelWrite を含める必要があります
appid (v1) または azp (v2) URL と等しい必要があります {agentId}
scp 欠席している必要があります

委任されたルート (/observability/...) - ユーザー委任トークン (ベアラーまたは PFAT):

請求 必須の値
aud 9b975845-388f-4429-889e-eab1ef63949c (または api://9b975845-...)
scp Agent365.Observability.OtelWrite を含める必要があります
appid / azp URL と等しい必要があります {agentId}

委任されたルートは、 Bearer トークンと MSAuth1.0 PFAT トークンの両方を受け入れます。 直接呼び出し元は、 Bearerを使用する必要があります。 持っているものがわからない場合は、 Bearerを使用します。

Endpoints

2 つのルート。ユーザーが行っていることではなく、 サービス の認証方法によって選択します。

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

ヘッダー:

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

URL パラメーター

  • {tenantId} - 顧客テナントの GUID。 サーバーはこれを権限のあるものとして扱います。スパンが microsoft.tenant.id 設定されていて、それが一致しない場合、要求は拒否されます。
  • {agentId} - 呼び出し元アプリケーションの appId (OAuth client_idも)。 ブループリントから派生した ID の場合、これは エージェント ID appId であり、ブループリント appId ではありません。 トークンの appid / azp 要求と等しい必要があります。
  • api-version=1 -必須。

リクエスト本文のエンコーディング

ボディは標準的な OTLP/HTTP+JSON 形式で、resourceSpansscopeSpansspans を持つ ExportTraceServiceRequest です。 次の詳細に注意してください。

  • traceId (16 バイト) と spanId (8 バイト) は、小文字の 16 進文字列として送信されます。
  • startTimeUnixNano / endTimeUnixNano は Unix エポック ナノ秒を保持する 文字列 です。
  • kindは整数の OTLP 列挙値 (たとえば、1INTERNAL) です。status.codeは整数列挙型です (たとえば、1の場合はOK2の場合はERROR)。
  • すべての属性値は stringValueとして送信されます。

応答図形

呼び出しが成功すると、 200 OKが返されます。

{ "partialSuccess": null }

各スパンに対するフィルターによって、一部のスパンが除外された場合:

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

フィールド名は、通信上では camelCase です。 必ずpartialSuccess確認してください: HTTP 200が返ってきても、すべてのスパンが拒否されることは実際にあり得る結果なので、必ず明示してください。 制限とドロップ条件 では、データがダウンストリームに表示されないにもかかわらず、200 が partialSuccess: null で返されるサイレント ドロップ ケースが一覧表示されます。

可能な限り最小の要求

最も単純なエンド ツー エンドテストでは、単一の invoke_agent スパンが送信されます。 このスパンは、Microsoft Defender に取り込まれる最小のデータ単位です。

ステップ 1. ベアラー トークンを取得します。 S2S の場合は、スコープ 9b975845-388f-4429-889e-eab1ef63949c/.default でクライアント資格情報を使用します (完全な レシピについては認証レシピ を参照してください)。

ステップ 2. 単一のスパンを 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

手順 3. このボディでは 200 OK が想定されます。

{ "partialSuccess": null }

ステップ 4. データが実際に着陸したことを確認します。 200 OKはインジェストの証拠 ではありませんインジェストの検証 では、検証フローについて説明します。 代わりに、保存した本文ファイルを POST するには、 --data @- <<EOF ... EOF--data @./otlp-request.json に置き換えます。

エージェントの実行例

Microsoft Teamsのユーザーが「シアトルの天気は何ですか?」と尋ねます。 エージェントが GetWeather 関数を呼び出し、LLM に応答の書式を設定するよう求め、応答します。 その1回の実行は、4つのスパンから成ります。

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

すべてのスパンで設定される実行全体の属性:

特性 値の例
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

これらの実行全体の属性は自動的には反映 されません 。 すべてのスパンで gen_ai.conversation.idmicrosoft.channel.name、および microsoft.session.id を自分で設定する必要があります。

スパン A: invoke_agent (ルート)

{
  "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 呼び出し)

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

範囲 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 */
  ]
}

スパン 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 */
  ]
}

テレメトリの送信

OTel SDK の使用

ほとんどのパートナーは、手動ロール HTTP ではなく OTel SDK を介してトレースを送信します。 SDK はバッチ処理、再試行、OTLP/HTTP+JSON エンコードを自動的に処理します。 エクスポーター エンドポイントを設定し、 Authorization ヘッダーを挿入します。

エクスポーター エンドポイントは、クエリ文字列を含むルート URL 自体です。

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

(委任されたルートに/observability/...の代わりに/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}"},
)

パッケージ: 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}` },
});

パッケージ: @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;
    }));

パッケージ: OpenTelemetry.Exporter.OpenTelemetryProtocol

HTTP(手動)

OTel SDK を使用できない場合、または使用したくない場合は、OTLP/HTTP+JSON 要求を自分でビルドして POST します。 ボディ シェイプは、OpenTelemetry OTLP/HTTP+JSON 仕様によって定義されます。

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

<span> は、必須フィールドが traceIdspanIdnamekindstartTimeUnixNanoendTimeUnixNanoattributes、および (非ルート スパンの場合) parentSpanIdを持つオブジェクトです。 エンコード規則 (文字列エンコード時間、16 進traceId、整数 / spanIdkind、すべての属性値 / ) については、「status.codestringValue」を参照してください。

各スパンで設定する属性のセットは、 メッセージ コントラクトで定義されます。 属性の完全な一覧については、属性 リファレンスを参照 してください。 ヘッダーと本文のインラインでベアラー トークンを使用したエンドツーエンドの作業サンプルについては、 エージェントの実行例 を参照してください。

実行のすべてのスパンを 1 つの POST 本文 (1 つの要求、1 つのトレース) で送信することも、複数の POST にまたがって送信することもできます。 サーバーは traceId + parentSpanId + gen_ai.conversation.idから実行を再構築するため、各スパンはどちらの方法でも相互に関連付けられるのに十分です。

メッセージ契約

このセクションでは、出力できるスパンと、それぞれの属性を定義します。 属性ごとの完全な仕様については、属性リファレンスを 参照してください

操作の種類

送信する各 span では、gen_ai.operation.name にこれら4つの値のいずれかを設定する必要があります(大文字と小文字は区別しません)。 値が見つからないか認識されないスパンは、自動的に削除され、 partialSuccess.rejectedSpansでカウントされます。

gen_ai.operation.name Meaning Googleで最も検索されている落とし穴
invoke_agent エージェントの呼び出し。 エージェント実行の "ルート" です。 実行が Microsoft Defender のエージェント アクティビティ ビューまたは Microsoft 365 管理センターに表示されるには必要です。 これがないと、テレメトリは Microsoft Defender の高度なハンティング (CloudAppEvents) にのみ送られます。
execute_tool エージェントによって実行されるツール/関数呼び出し。 --
chat LLMの推論呼び出し。 chatではなく、リテラル inferenceを使用します。
output_messages 最終的に出力されるメッセージ。 --

スパン階層と実行のグループ化

エージェント 365 は、標準の OTLP スパン グラフ(traceIdspanIdparentSpanId)と、属性リファレンスの実行全体にわたる属性から実行を再構築します。

6 つの規則:

  1. ルート以外のすべてのスパンで常に parentSpanIdを設定してください。 これを使用しないと、実行のツリー構造を再構築できません。
  2. 実行内のすべてのスパンで同じtraceIdを再利用します。
  3. 同じ値を持つすべてのスパンにgen_ai.conversation.idを設定します。 これは、「この実行内のすべてのスパン」の主要な結合キーです。 これは自動的には反映 されません
  4. 同じ値を持つすべてのスパンにmicrosoft.channel.nameを設定します。 チャネルまたは会話が設定されていないツールスパンは、親が同じOTLPリクエスト内にあるinvoke_agent場合にのみ親からそれらを継承できるため、各スパンに自分で設定してください。
  5. 論理セッションがある場合は、すべてのスパンでmicrosoft.session.idを設定します。
  6. 子エージェントが別の要求にあるエージェント間呼び出しの場合は、同じ gen_ai.conversation.id を再利用し、 microsoft.a365.caller.agent.* 属性 ( 属性リファレンスを参照) を使用して呼び出し元エージェント コンテキストをキャプチャします。

エージェントの実行例の 4 スパン ツリーは正規の図形です。

一般的な実行図形

形状 送信するスパン メモ
単一エージェント チャットボット (ツールなし、LLM スパンなし) invoke_agent は 1 つのみ 実行全体の属性に加えて、 gen_ai.input.messagesgen_ai.output.messagesを設定します。 可能な 限り最小の要求と同じです。
ツールを使用したエージェント (最も一般的) invoke_agent ルート + chatexecute_tooloutput_messages 子要素 すべての子がルートの traceId を共有し、 parentSpanId = root.spanIdを設定します。 すべて同じ実行全体の属性を持っています。 完全な例については、 エージェントの実行例 を参照してください。
エージェント間 各エージェントはそれぞれ独自の invoke_agent を出力します 両方のエージェントで同じ gen_ai.conversation.id を再利用します。 ターゲットの invoke_agentで、 gen_ai.execution.type = "Agent2Agent"microsoft.a365.caller.agent.* 属性 (呼び出し元エージェントの appId、名前、ブループリント appId、ユーザー ID、電子メール) を設定します。 呼び出し元エージェントに Entra 登録がない場合は、代わりに microsoft.a365.caller.agent.platform.idgen_ai.caller.agent.type を使用します。

オンボーディング チェックリスト

運用環境に移行する前に、このチェックリストを実行します。

Category チェック
認証 お使いの Entra アプリ (またはブループリント) は登録されており、そのトークンを発行できます。
認証 アプリには Agent365.Observability.OtelWrite が付与されています(S2S の場合はアプリ ロール、委任の場合はスコープ)。
認証 各エージェントには、URL にとして独自の Entra {agentId} があります。 ブループリント派生 ID の場合、その appId は、ブループリント appId ではなく、エージェント ID appId です。 エージェントに Entra 登録がない場合は、「 値の選択」を参照してください。
認証 テナント管理者がAgent365.Observability.OtelWrite同意しました。 同意がないと、トークンはロール/スコープなしで発行され、要求は 403で拒否されます。
ライセンス 顧客テナント内の少なくとも 1 人のユーザーに Microsoft 365 E7 または Microsoft Agent 365 ライセンスが割り当てられている (テナント内の SKU プレゼンスだけでなく、割り当て)。 割り当てられたライセンスがないと、インジェストは自動的に削除されます。 「前提条件」を参照してください。
スパン すべてのスパンは、実行全体の要点 (スパン階層と実行グループ) を設定します。
スパン invoke_agent は、 gen_ai.input.messagesgen_ai.output.messagesを設定します。
スパン execute_tool スパンセット gen_ai.tool.namegen_ai.tool.typegen_ai.tool.call.idgen_ai.tool.call.argumentsgen_ai.tool.call.result
スパン chat スパンのセット gen_ai.request.model および gen_ai.provider.name(および理想的には gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - 文字列としてエンコードされたもの)。
スパン ルート以外のすべてのスパンは parentSpanId設定されます。実行内のすべてのスパンは同じ traceIdを共有します。
ペイロード リクエスト本文は 1 MB 以下です。
確認 すべての応答で partialSuccess を解析し、拒否をログに記録します。
確認 最初の実行を対象に、インジェストの検証で検証フローを実行しました。

次のステップ