本指南將詳述如何從端到端直接透過 OpenTelemetry (OTLP/HTTP+JSON) 將 Agent 遙測資料傳送到 Agent 365。 在開始之前,請先閱讀 Agent 365 可檢視性概念,以了解模型、驗證流程,以及資料駐留的介面。
重要
直接 OTel 路徑是例外狀況,而非預設。 僅在您已經有 OpenTelemetry 管線、您的框架無法使用 Agent 365 SDK,或您的 Agent 採用 SDK 尚未支援的語言 (例如 JAVA) 時使用此方法。 對於其他使用者,建議採用的路徑是 Microsoft OpenTelemetry 發行版,能跨 Agent 365、Microsoft Foundry、Azure 監視器等多個平台提供統一的可檢視性 SDK。 早期的 可檢視性 SDK 仍可繼續運作,不會產生重大變更,但已不再建議用於新的整合;現有 SDK 使用者的移轉指引即將推出。
先決條件
在任何遙測流程開始之前,請確保以下設定已完成。
| 何人 | 說明 |
|---|---|
| 租用戶管理員 | 註冊 Agent 365 並為您的 Agent 應用程式授與同意。 請參閱上線到 Agent 365。 若沒有獲得授權的租用戶,將靜默丟棄擷取 - 要求會傳回200 OK和 partialSuccess: null,但資料永遠不會在下游出現。 |
| 租用戶管理員 |
指派 Microsoft 365 E7 或 Microsoft Agent 365 授權給租用戶中至少一位使用者。 SKU 存在還不夠 將授權指派給會啟動 Defender 後端工作流程 (會啟動擷取) 的使用者。 如果沒有指派的授權,要求會傳回200 OK 和 partialSuccess: null,資料會遭到靜默丟棄。 |
| 租用戶管理員 | 授與租用戶同意。 請參閱授與 Agent 對 Microsoft 365 資源的存取權。 若未完成租用戶同意,系統會發出不含角色/作用域的權杖,且要求會傳回 403。 |
| 您的開發團隊 | 註冊應用程式 (標準 Microsoft Entra 應用程式或藍圖)。 請參閱開始使用 Agent 365 開發。 |
| 您的開發團隊 | 在 API權限 (用於 S2S 的應用程式角色,範圍用於委派) 底下,新增 Agent365.Observability.OtelWrite。 針對藍圖,請參閱設定可繼承權限。 請與 Agent 365 上線團隊協調以啟用權限。 |
驗證方案
所有四種方案皆使用標準的 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 流程 | 移至 |
|---|---|---|
| 標準 Microsoft Entra 應用程式註冊 | S2S (用戶端認證) | S2S、標準 Microsoft Entra 應用程式 |
| 標準 Microsoft Entra 應用程式註冊 | OBO (已委派) | OBO、標準 Microsoft Entra 應用程式 |
| 藍圖衍生的 Agent 身分識別 | S2S (用戶端認證) | S2S,藍圖衍生的 Agent 身分識別 |
| 藍圖衍生的 Agent 身分識別 | OBO / AI 隊友 | OBO,藍圖衍生的 Agent 身分識別 |
S2S、標準 Microsoft Entra 應用程式
一個 POST 到租用戶的權杖端點,且帶有 grant_type=client_credentials。 透過用戶端密碼、憑證 (簽署的 JWT 判斷提示)、受控識別或同盟認證來驗證應用程式。
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}、包含 Agent365.Observability.OtelWrite 以及 aud = 9b975845-... 的 roles。 在 /observabilityService/.../traces 路由上使用它。
對於憑證型驗證,請將 client_secret={secret} 替換成 client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt}。
S2S,藍圖衍生的 Agent 身分識別
Agent 身分識別本身沒有自己的認證。 Agent 身分識別藍圖持有認證 (受控識別 FIC、憑證或用戶端密碼),並透過兩步驟交換代表其子 Agent 身分識別發行權杖。 如需詳細資訊,請參閱自主應用程式 OAuth 流程。
藍圖驗證後,取得同盟身分識別交換權杖
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-
Agent 身分識別使用
T1來交關 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- 傳回的權杖具有
appid/azp={agent-identity-app-id}、包含Agent365.Observability.OtelWrite以及aud=9b975845-...的roles。 - 在
/observabilityService/.../traces路徑上使用這個權杖。 - URL
{agentId}是 Agent 身分識別 appId,而非藍圖 appId。
- 傳回的權杖具有
OBO、標準 Microsoft Entra 應用程式
從您的上游呼叫者 (持有人 或 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}、包含 Agent365.Observability.OtelWrite 以及 aud = 9b975845-... 的 scp。 在 /observability/.../traces 路由上使用它。 同時會傳回重新整理權杖;請快取並重複使用它,而不是在每次呼叫時重新執行交換。
OBO,藍圖衍生的 Agent 身分識別 (包括 AI 隊友)
代理者流程有三個主要步驟。 如需詳細資訊,請參閱 Agent OAuth 流程:代理者流程。
收到使用者權杖
Tc。 對於 AI 隊友,此權杖代表 Agent 的使用者帳號;否則,它代表真人來電者。藍圖進行驗證並取得
T1,與 S2S 藍圖衍生的 Agent 身分識別流程相同。Agent 身分識別用
T1和Tc交換委派的資源權杖: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}、包含 Agent365.Observability.OtelWrite 的 scp,並代表 Agent 的使用者。 在 /observability/.../traces 路由上使用它。 URL {agentId}是 Agent 身分識別 appId,而非藍圖 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。
端點
兩種路由;請依您的服務的驗證方式選擇,而不是依使用者的動作:
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 (同時也是 OAuthclient_id)。 對於藍圖衍生的身分識別,這是 Agent 身分識別 appId,而不是藍圖 appId。 必須等同於您權杖中的appid/azp宣告。 -
api-version=1- 必要。
要求主體編碼
主體為標準的 OTLP/HTTP+JSON 格式:一個 ExportTraceServiceRequest,包含 resourceSpans → scopeSpans → spans。 請記住以下詳細資料:
-
traceId(16 位元組) 和spanId(8 位元組) 是以小寫十六進位字串傳送。 -
startTimeUnixNano/endTimeUnixNano均為 字串,其內容為 Unix 紀元納秒。 -
kind整數 OTLP列舉值 (例如1代表INTERNAL);status.code是整數列舉 (例如1代表OK、2代表ERROR)。 - 所有屬性值皆以
stringValue格式傳送。
回覆結構
成功呼叫時會傳回 200 OK:
{ "partialSuccess": null }
如果某些跨度依每個跨度篩選條件遭到拒絕:
{
"partialSuccess": {
"rejectedSpans": 2,
"errorMessage": "Dropped 2 non-A365 span(s) ..."
}
}
欄位名稱在協議傳輸時採用 camelCase 格式。
務必檢查partialSuccess:若收到 200 但所有跨度均遭到拒絕,這是必須顯露的真實結果。
限制與捨棄條件列出靜默捨棄的情況,在沒有下游資料的情況下仍傳回 200 且具有 partialSuccess: null。
最小的可能要求
最簡單的端對端測試是發送單一 invoke_agent跨度。 這個跨度是 Microsoft Defender 所接收的最小主體。
步驟 1. 取得持有人權杖。 對於 S2S,請使用範圍為9b975845-388f-4429-889e-eab1ef63949c/.default 的用戶端認證 (完整方案請參見驗證方案)。
步驟 2. 張貼單一跨度:
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 不能證明擷取;驗證擷取過程會帶您走過確認流程。 若要張貼已儲存的主體檔案,請將 --data @- <<EOF ... EOF替換成 --data @./otlp-request.json。
Agent 執行範例
一位使用者在 Microsoft Teams 上詢問:「西雅圖的天氣如何?」 您的 Agent 呼叫一個 GetWeather 函式,請 LLM 格式化答案,然後回覆。 這個單一執行共有四個跨度:
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 |
重要
這些執行範圍屬性不會自動傳播。 您必須在每個跨度上自行設定 gen_ai.conversation.id、microsoft.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 */
]
}
跨度 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
大多數合作夥伴會透過 OTel SDK 傳送追蹤資料,而非自行撰寫 HTTP。 SDK 會自動處理批次、重試以及 OTLP/HTTP+JSON 編碼。 設定匯出器端點,並注入 Authorization 標頭。
匯出端點即為路由網址本身,包括查詢字串:
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 要求並張貼。 主題形式由 OpenTelemetry OTLP/HTTP+JSON 規格定義:
{
"resourceSpans": [{
"resource": { "attributes": [ ... ] }, // optional
"scopeSpans": [{
"scope": { "name": "<your-instrumentation>", "version": "1.0.0" },
"spans": [ <span>, <span>, ... ]
}]
}]
}
每個 <span> 都是一個物件,必填欄位為 traceId、spanId、name、kind、startTimeUnixNano、endTimeUnixNano、attributes、以及 (若為非根跨度) parentSpanId。 請參閱端點與要求主體編碼以了解編碼規則 (字串編碼時間、十六進位traceId / spanId、整數kind / status.code、所有屬性值為 stringValue)。
每個跨度需設定的屬性集是在訊息合約中定義。 請參閱屬性參照以了解完整屬性清單。 請參考 Agent 執行範例,這是一個端到端範例,其中持有人權杖位於頁首,主體為內嵌格式。
您可以將一個執行的所有跨度一次性用單一 POST 主體發送 (慣用 - 一次要求,一個追蹤),或分多次 POST 發送。 伺服器會從 traceId + parentSpanId + gen_ai.conversation.id 重新建構執行流程,因此每個跨度都攜帶足夠資訊以便於關聯。
管理合約
本區段會定義您可以發出的跨度以及每個跨度所需包含的屬性。 如需完整屬性規格,請參見屬性參考。
作業類型
您發送的每個跨度都必須將 gen_ai.operation.name 設定為這四個值之一 (不區分大小寫)。 任何遺漏或無法識別值的跨度都會遭到靜默丟棄並計入 partialSuccess.rejectedSpans。
gen_ai.operation.name |
意義 | 最常透過 Google 搜尋的陷阱 |
|---|---|---|
invoke_agent |
Agent 的一次叫用。 Agent 執行的「根」。 | 必須有此項,執行才會顯示在 Microsoft Defender Agent 活動視圖或 Microsoft 365 系統管理中心。 若沒有它,遙測資料僅會落在 Microsoft Defender 進階獵捕 (CloudAppEvents)。 |
execute_tool |
由 Agent 執行的工具或函數呼叫。 | -- |
chat |
LLM 推論呼叫。 |
使用常值 chat,不是 inference. |
output_messages |
最終發出的輸出訊息。 | -- |
跨度階層與執行群組
Agent 365 會根據標準 OTLP 跨度圖 (traceId、spanId、parentSpanId) 以及來自屬性參考的執行範圍屬性來重新建構執行。
六條規則:
-
一律在每個非根跨度上設定
parentSpanId。 沒有它,執行的樹狀結構無法重建。 -
在一次執行中的每個跨度都重複使用相同的
traceId。 - 用相同的值在每個跨度上設定
gen_ai.conversation.id。 這是「本次執行中所有跨度」的主要聯結鍵。 它並非自動傳播。 - 用相同的值在每個跨度上設定
microsoft.channel.name。 遺漏管道 / 交談的工具跨度能從其父系invoke_agent繼承 (只有在父系位於同一個 OTLP 要求中時),因此請在每個跨度上自行設定這些屬性。 -
在有邏輯工作階段時,請在每個跨度上設定
microsoft.session.id。 - 對於 Agent 到 Agent的呼叫,如果子 Agent 位於不同的要求中,請重複使用相同的
gen_ai.conversation.id,並使用microsoft.a365.caller.agent.*屬性 (請參閱 屬性參考) 來擷取呼叫 Agent 的上下文。
Agent 執行範例中的四跨度樹是 canonical 形狀。
常見的執行形狀
| 圖形 | 需要匯出的跨度 | 附註 |
|---|---|---|
| 單一 Agent 聊天機器人 (不含工具,無 LLM 跨度) | 僅一個 invoke_agent |
設定執行範圍屬性,以及 gen_ai.input.messages 和 gen_ai.output.messages。 與 最小可能要求一模一樣。 |
| 具有工具 的 Agent (最常見) |
invoke_agent 根 + chat、execute_tool、子 output_messages 節點 |
所有子系都共用根的 traceId,並設定 parentSpanId = root.spanId。 這些都具備相同的執行範圍特性。 請參閱 Agent 執行範例,以獲取完整範例。 |
| Agent 到 Agent | 每個 Agent 都會發出其專屬的 invoke_agent |
在兩個 Agent 之間共用同一個 gen_ai.conversation.id。 在目標的 invoke_agent 上,請設定 gen_ai.execution.type = "Agent2Agent" 和 microsoft.a365.caller.agent.* 屬性 (包括呼叫 Agent 的 appId、名稱、藍圖 appId、使用者識別碼和電子郵件)。 如果呼叫 Agent 沒有 Entra 註冊,請改用 microsoft.a365.caller.agent.platform.id 和 gen_ai.caller.agent.type 。 |
上線檢查清單
在部署到生產環境之前,請執行檢查清單。
| 類別 | 檢查 |
|---|---|
| 驗證 | 您的 Entra 應用程式 (或藍圖) 已經註冊,您可以為它製造權杖。 |
| 驗證 | 您的應用程式已獲授與 Agent365.Observability.OtelWrite (S2S 的應用程式角色,委派的範圍)。 |
| 驗證 | 每個 Agent 在 URL 中都有自己的 Entra appId 作為 {agentId}。 對於藍圖衍生的身分識別,appId 指的是 Agent 身分識別 appId,而不是藍圖 appId。 若 Agent 沒有 Entra 註冊,請參閱 選擇值。 |
| 驗證 | 租用戶管理員授與 同意給 Agent365.Observability.OtelWrite。 未經同意,權杖會核發,且沒有角色/作用域,要求會遭到拒絕且具有 403。 |
| 授權 | 客戶租用戶中至少有一位使用者已指派Microsoft 365 E7 或 Microsoft Agent 365 授權 (指派,而非僅是租用戶中的 SKU 存在)。 沒有指派授權時,擷取會遭到靜默丟棄。 請參閱必要條件。 |
| 跨度 | 每個跨度設定執行範圍基本要素 (跨度層級與執行分組)。 |
| 跨度 |
invoke_agent跨度會設定 gen_ai.input.messages 和 gen_ai.output.messages。 |
| 跨度 |
execute_tool 跨度會設定gen_ai.tool.name、gen_ai.tool.type、gen_ai.tool.call.id、 gen_ai.tool.call.arguments、gen_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 並記錄拒絕。 |
| 驗證 | 針對初次執行,您已在驗證擷取中,執行過驗證流程。 |