使用 Application Insights 的環境層級遙測(預覽版)

[本文章是發行前版本文件,且隨時可能變更。]

使用 Azure 應用程式 Insights 監視從受控環境匯出的 Copilot Studio 代理程式追蹤。 設定匯出後,使用 Azure 監視器 和 Application Insights 來驗證代理執行、監控節點與工具執行、建立警示,並建立自訂查詢與儀表板以進行操作分析。

Note

  • 標準執行架構與 GitHub Copilot 執行架構驅動的 Agent,皆可使用環境層級遙測。
  • 私人預覽版結束後,根 Agent 叫用 (invoke_agent) 現在會以 dependencies 而非 requests 的形式發出。 因此,較舊的 Agent 根叫用追蹤可能仍會出現在 requests 資料表中。
  • 為了利用最新的遙測策略與能力評估此預覽功能,您可以在啟用 早期發佈週期 的非生產環境中進行測試。
  • 此功能僅適用於 受管理環境。
  • Application Insights 僅提供在 Copilot Studio 內建的代理日誌,不包括宣告式代理。
  • 若要僅採用環境層級的 Application Insights 策略來處理 Copilot Studio 代理遙測,組織可以選擇停用代理層級的 Application Insights 遙測。

本文說明如何透過 Power Platform 管理中心設定 Copilot Studio agent 追蹤的環境層級匯出至 Azure 應用程式 Insights。

Important

本文包含 Microsoft Copilot Studio 預覽版文件,內容可能有所變更。

預覽功能不供生產時使用,而且可能功能受限。 這些功能是在正式發行前先行推出,讓您能夠搶先體驗並提供意見反應。

如果你正在打造一個準備好上線的代理程式,請參考 Microsoft Copilot Studio 概述。

先決條件

在設定資料匯出連線前,先完成 「將資料匯出至應用程式洞察」的先決條件。

出口的是什麼

啟用匯出後,Copilot Studio 的 Agent 追蹤遙測會以追蹤導向、與 OpenTelemetry 一致的可觀察性格式寫入 Application Insights,支援調查、儀表板與警示功能。

Copilot Studio 的代理程式事件會以 span 的形式寫入 dependencies 資料表。 每個匯出的事件(InvokeAgent、ExecuteTool和OutputMessages)都是單一 span 資料列(itemType = dependency)。

範圍如何組成追蹤

遙測會遵循 OpenTelemetry 追蹤與範圍模型,並透過 operation_Id 與 operation_ParentId 資料行重建:

  • 每個代理程式回合都是各自獨立的追蹤,並透過共用的 operation_Id 識別,讓 Application Insights 能夠將該回合分組,並在端對端交易檢視中呈現。
  • InvokeAgent 範圍是其回合追蹤的根。 其 ExecuteTool 與相連的 OutputMessages 範圍會巢狀於其下,各自帶有 operation_ParentId = InvokeAgent 範圍的 id。
  • 一次交談會橫跨多個回合,每個回合都會以個別追蹤的形式發出。 依 gen_ai.conversation.id 分組或篩選,將同一段對話的各輪次重新串連起來。
  • OutputMessages 範圍不一定會發出 InvokeAgent 根,這表示它們 (依設計) 可能沒有相符的父項就送達,並顯示為獨立的單一節點追蹤。

建立匯出套件

依照 Power Platform 管理中心文件中「建立匯出套件」的指示,建立一個將匯出類型設為 Copilot Studio 的匯出套件。

驗證設定

儲存導出設定後,與代理執行測試對話,確認遙測資料是否已傳送到 Application Insights。 在新配置下,遙測傳送可能需要長達24小時。 驗證這點:

  • 代理程式跨度會顯示在 dependencies 表格中。
  • 每個回合中的 InvokeAgent、ExecuteTool 和 OutputMessages 範圍共用同一個 operation_Id。

應用洞察欄位

下表顯示 dependencies 表中的欄位,以及三個匯出的代理程式事件:InvokeAgent、ExecuteTool 和 OutputMessages 中各自會填入哪些欄位。 代理與操作的語義位於 customDimensions(亦即 gen_ai.* 鍵,例如 gen_ai.operation.name)中,而非原生欄位。

表格中的 dependencies 欄位 召喚代理 執行工具 輸出訊息 樣本值
timestamp [UTC] ✔️ ✔️ ✔️ 6/11/2026, 5:02:13.501 AM
id ✔️ ✔️ ✔️ 1111aaa1-aa11-11aa-11a1-a1aaa1111aa1
name ✔️ ✔️ ✔️ InvokeAgent / ExecuteTool / OutputMessages
resultCode ✔️ ✔️ ✔️ OK、ERROR
type ✔️ ✔️ ✔️ GenAI
target ✔️ ✔️ ✔️ GenAI
data ✔️ ✔️ ✔️ invoke_agent / execute_tool / output_messages
success ✔️ ✔️ ✔️ True
duration ✔️ ✔️ ✔️ 0
performanceBucket ✔️ ✔️ ✔️ <250ms
itemType ✔️ ✔️ ✔️ dependency
customDimensions ✔️ ✔️ ✔️ 了解更多請參閱 customDimension 屬性
operation_Id ✔️ ✔️ ✔️ trace-1111aaa1-aa11-11aa-11a1-a1aaa1111aa1 (由該回合中的每個範圍共用)
operation_ParentId ✔️ ✔️ ✔️ 子範圍會使用該回合的 InvokeAgentid;InvokeAgent 範圍則是追蹤根項目
client_Type ✔️ ✔️ ✔️ PC
client_IP ✔️ ✔️ ✔️ 0.0.0.0
client_City ✔️ ✔️ ✔️ San Jose
client_StateOrProvince ✔️ ✔️ ✔️ California
client_CountryOrRegion ✔️ ✔️ ✔️ United States
appId ✔️ ✔️ ✔️ 11111a1a-1111-1111-a111-1a1a1a11111a
appName ✔️ ✔️ ✔️ -
iKey ✔️ ✔️ ✔️ aa111a1a-a1aa-111a-111a-a111a111111a
sdkVersion ✔️ ✔️ ✔️ dotnetc:2.23.0-29
itemId ✔️ ✔️ ✔️ a1a1111a-1111-11a1-1111-111111aa1a1a
itemCount ✔️ ✔️ ✔️ 1
_ResourceId ✔️ ✔️ ✔️ -

customDimensions 屬性

每個區間都包含 customDimensions JSON。 下表顯示每個跨間常見的鍵:

Key 樣本值
SpanId 1111aaa1-aa11-11aa-11a1-a1aaa1111aa1
error.type 404
Status.code 1、2
Status.message Descriptive failure message
gen_ai.agent.id 1aa11a11-1a1a-1a11-1a1a-1111aa1111aa
gen_ai.agent.name MCS Agent
gen_ai.conversation.id aaaaa111-1a1a-1111-1aa1-a111111a11a1
gen_ai.request.model Sonnet46
gen_ai.operation.name invoke_agent / execute_tool / output_messages
env.id 111a1aa1-a1aa-aaa1-a11a-11a111111111
microsoft.tenant.id 11aaa111-1a11-1a1a-a111-aa1a111a111a
microsoft.a365.agent.blueprint.id 1111111a-aa11-1a11-a1a1-a11a1111a1a1
microsoft.a365.agent.platform.id 111a1aa1-…_1a11111a-…
microsoft.channel.name Copilot Studio Test Pane
resource.provider copilot studio
signal.category default
a365.enabled True
appinsights.enabled True
user.id -
user.email My.User@mytenant.onmicrosoft.com
user.name My User
client.address ::ffff:00.00.00.00
telemetry.sdk.name A365ObservabilitySDK
telemetry.sdk.language dotnet
telemetry.sdk.version 1.1.9.43597

事件專屬鍵

下表顯示事件專屬的鍵:

Key 召喚代理 執行工具 輸出訊息 說明
gen_ai.input.messages ✔️ - - {role, parts:[{content, type}]} 的 JSON 陣列——使用者提示
gen_ai.output.messages - - ✔️ JSON 陣列——代理人的回覆
gen_ai.tool.name - ✔️ - 例如, workiqsharepoint:mcp_SharePointRemoteServer
gen_ai.tool.type - ✔️ - 例如, MCP - Power Platform Connector
gen_ai.tool.call.id - ✔️ - 工具呼叫識別碼
gen_ai.tool.call.arguments - ✔️ - 傳送至工具的 JSON 承載
gen_ai.tool.call.result - ✔️ - 工具回傳的 JSON 有效載荷

探索目前的架構

本文所記錄的架構可能會隨時間演變。 與其僅依賴前述表格,不如使用以下查詢,在你自己的環境中即時檢視最新的結構。

列出本地表格欄位

以下查詢會回傳資料表的 dependencies 欄位層級結構。 在建立查詢、儀表板或警示時,用它來確認可用的原生欄位。

dependencies
| getschema
| project ColumnName, ColumnType
| order by ColumnName asc

探索 customDimensions 索引鍵(動態屬性)

以下查詢列出表格中 JSON customDimensions 中dependencies的所有鍵:屬性名稱、出現在哪些代理事件(InvokeAgent、、ExecuteToolOutputMessages)、以及一個範例值。 與原生欄位結構不同,這些屬性是動態的,因此當 SDK 新增 gen_ai.* 或新增鍵時,查詢仍保持準確。 把它當作現有屬性的即時真實來源。

dependencies
| where timestamp > ago(7d)
| mv-expand Key = bag_keys(customDimensions) to typeof(string)
| summarize Events = make_set(name), SampleValue = take_any(tostring(customDimensions[Key])) by Key
| order by Key asc

監視匯出的遙測資料

使用 Application Insights Logs 查詢代理活動並調查代理或工具執行情況。 所有匯出的遙測資料都會以 span 的形式存放在 dependencies 資料表中:

  • 每個 Agent 回合都是一個追蹤,以共用的 operation_Id 分組。
  • InvokeAgent 範圍是追蹤根;ExecuteTool 與 OutputMessages 範圍會透過 operation_ParentId 巢狀於其下。
  • 依 gen_ai.conversation.id 分組,以串連同一對話的多個回合,並以 _ 分割該 ID,以納入子代理的追蹤資訊。

Agent (預覽版) 刀鋒視窗

除了 日誌 之外,Application Insights 還提供內建的 代理程式(預覽) 檢視,可在不需撰寫 Kusto 查詢的情況下,將匯出的 GenAI 遙測資料視覺化。 由於 Copilot Studio 會將其範圍寫入 dependencies 資料表,這些刀鋒視窗會直接讀取該資料:

  • 代理運行:列出從這些 InvokeAgent 跨度建立的代理呼叫,並附上持續時間、成功率及每次執行所屬的對話。 有一些限制;詳情請參閱「已知限制與考量」。
  • 工具:彙 ExecuteTool 整這些時間範圍,顯示客服人員呼叫哪些工具、頻率及效能。
  • 模型:總結模型在多次運行中的使用情況,揭示所調用的模型及其呼叫模式。

Application Insights 代理程式面板的螢幕擷取畫面。

利用 Application Insights 分析代理遙測

當您將環境連接到 Application Insights 後,當使用者與代理互動時,包括在 Copilot Studio 測試期間,它會記錄代理的遙測資料。 要查看已記錄的遙測資料,請前往 Azure 中 Application Insights 資源的日誌區塊。 在這裡,你可以使用 Kusto 查詢來查詢及分析資料。 在 範例查詢中了解更多。

範例查詢

以下 Kusto 查詢範例從 Application Insights 中的表格重建 Copilot Studio 客服人員的對話dependencies。 由於每次回合中的所有跨度都共用同一個追蹤 operation_Id,因此查詢會在每個追蹤內依根優先順序排列跨度(即 InvokeAgent 跨度會排在其子跨度之前)。

查詢 1:傳回特定對話 ID 的完整追蹤記錄

此查詢會回傳一個已知對話的每一段,依時間順序排列,每個根段先於子段。 將 對話 ID 的佔位符替換成你客服的對話 ID。 你可以在測試自訂代理時輸入以下指令找到它: /debug conversationid。

let LatestConvo = "<Conversation ID>"; 
dependencies
| where tostring(customDimensions["gen_ai.conversation.id"]) == LatestConvo
| order by operation_Id asc, iff(name == "InvokeAgent", 0, 1) asc, timestamp asc
| project timestamp, name, id, operation_Id,
          operation_ParentId, duration, target, type, cloud_RoleName,
          resultCode, customDimensions

查詢二:回傳特定客服的最新對話

此查詢會尋找指定時間內指定代理人最近的對話。 它會以相同的時間順序、根先順序回傳該對話的每個區段。 將 代理人名稱 的佔位符替換成你代理人的名字。

let Window = 7d;
let AgentName = "<Agent name>";
let LatestConvo = toscalar(
    dependencies
    | where timestamp > ago(Window)
    | where tostring(customDimensions["gen_ai.agent.name"]) == AgentName
    | where isnotempty(tostring(customDimensions["gen_ai.conversation.id"]))
    | top 1 by timestamp desc
    | project tostring(customDimensions["gen_ai.conversation.id"])
);
dependencies
| where timestamp > ago(Window)
| where tostring(customDimensions["gen_ai.conversation.id"]) == LatestConvo
| order by operation_Id asc, iff(name == "InvokeAgent", 0, 1) asc, timestamp asc
| project timestamp, name, id, operation_Id,
          operation_ParentId, duration, target, type, cloud_RoleName,
          resultCode, customDimensions

查詢 3:將已知的 genAI OpenTelemetry 屬性展開成資料行

此查詢會傳回與查詢 2 相同的追蹤,但也會將每個已知的 OpenTelemetry 語意慣例索引鍵剖析為個別的具名資料行。 結果是一個扁平且明確定義的表格,你可以直接排序、篩選並掃描生成式 AI 欄位,如工具名稱、模型、使用者提示、客服回覆和對話 ID。 將 代理人名稱 的佔位符替換成你代理人的名字。

let Window = 7d;
let AgentName = "<Agent name>";
let LatestConvo =
    toscalar(
        dependencies
        | where timestamp > ago(Window)
        | extend
            AgentName_ = tostring(customDimensions["gen_ai.agent.name"]),
            ConversationId_ = tostring(customDimensions["gen_ai.conversation.id"])
        | where AgentName_ == AgentName
        | where isnotempty(ConversationId_)
        | summarize arg_max(timestamp, ConversationId_)
        | project ConversationId_
    );
dependencies
| where timestamp > ago(Window)
| extend
    ConversationId = tostring(customDimensions["gen_ai.conversation.id"])
| where ConversationId == LatestConvo
| extend
    OperationName    = tostring(customDimensions["gen_ai.operation.name"]),
    AgentId          = tostring(customDimensions["gen_ai.agent.id"]),
    AgentName        = tostring(customDimensions["gen_ai.agent.name"]),
    Model            = tostring(customDimensions["gen_ai.request.model"]),
    ToolName         = tostring(customDimensions["gen_ai.tool.name"]),
    ToolType         = tostring(customDimensions["gen_ai.tool.type"]),
    ToolCallId       = tostring(customDimensions["gen_ai.tool.call.id"]),
    ToolArguments    = tostring(customDimensions["gen_ai.tool.call.arguments"]),
    ToolResult       = tostring(customDimensions["gen_ai.tool.call.result"]),
    EnvironmentId    = tostring(customDimensions["env.id"]),
    TenantId         = tostring(customDimensions["microsoft.tenant.id"]),
    ChannelName      = tostring(customDimensions["microsoft.channel.name"]),
    BlueprintId      = tostring(customDimensions["microsoft.a365.agent.blueprint.id"]),
    PlatformId       = tostring(customDimensions["microsoft.a365.agent.platform.id"]),
    ResourceProvider = tostring(customDimensions["resource.provider"]),
    SignalCategory   = tostring(customDimensions["signal.category"]),
    UserId           = tostring(customDimensions["user.id"]),
    UserName         = tostring(customDimensions["user.name"]),
    UserEmail        = tostring(customDimensions["user.email"])
| extend
    InputMessages  = parse_json(tostring(customDimensions["gen_ai.input.messages"])),
    OutputMessages = parse_json(tostring(customDimensions["gen_ai.output.messages"]))
| extend
    UserInput   = tostring(InputMessages[0].parts[0].content),
    AgentOutput = tostring(OutputMessages[0].parts[0].content)
| order by
    operation_Id asc,
    iff(name == "InvokeAgent", 0, 1) asc,
    timestamp asc
| project
    timestamp, name, id, operation_Id, operation_ParentId, OperationName, ConversationId,
    AgentId, AgentName, Model, ToolName, ToolType, ToolCallId, ToolArguments, ToolResult,
    UserInput, AgentOutput, EnvironmentId, TenantId, ChannelName, BlueprintId, PlatformId,
    ResourceProvider, SignalCategory, UserId, UserName, UserEmail, duration, target, type,
    cloud_RoleName, resultCode, customDimensions

查詢 4:動態展開所有生成式 AI OpenTelemetry 屬性

此查詢會傳回與查詢 3 相同的範圍,但每個 gen_ai.* 索引鍵都會從 customDimensions 動態解壓縮,並放入各自以 ga_ 為前置詞的資料行中。 由於投影是動態的,SDK 之後會自動顯示任何新 gen_ai.* 屬性,無需更改查詢內容。 將 代理人名稱 的佔位符替換成你代理人的名字。

let Window = 7d;
let AgentName = "<Agent name>";
let LatestConvo = toscalar(
    dependencies
    | where timestamp > ago(Window)
    | where tostring(customDimensions["gen_ai.agent.name"]) == AgentName
    | where isnotempty(tostring(customDimensions["gen_ai.conversation.id"]))
    | top 1 by timestamp desc
    | project tostring(customDimensions["gen_ai.conversation.id"])
);
dependencies
| where timestamp > ago(Window)
| where tostring(customDimensions["gen_ai.conversation.id"]) == LatestConvo
| order by operation_Id asc, iff(name == "InvokeAgent", 0, 1) asc, timestamp asc
| mv-apply Key = bag_keys(customDimensions) on (
    where Key startswith "gen_ai."
    | summarize OTelGenAI = make_bag(bag_pack(tostring(Key), customDimensions[tostring(Key)]))
  )
| project timestamp, name, id, operation_Id, operation_ParentId,
          duration, target, type, cloud_RoleName, resultCode,
          OTelGenAI, customDimensions
| evaluate bag_unpack(OTelGenAI, 'ga_')

已知的限制與考量

  • 此功能不支援未認證或 多租戶代理設定 情境。 因此,Application Insights 不會記錄這些資料。
  • 此功能目前僅在 Microsoft 公有雲環境中提供。
  • 在某些連線 Agent 案例中,追蹤之間的父子關聯性未正確對應。
  • 對於由標準執行架構驅動的 Agent,追蹤中不會提供 duration 值。
  • 務必在目標應用程式洞察資源中開啟 本地認證 屬性。
  • 遙測匯出不具交易性。 在臨時服務事件中,可能會發生少量資料遺失。
  • 在推出結構描述相關的擷取更新期間,可能會發生資料不一致的情況。
  • 此功能不會捕捉與主題相關的事件,如 TopicStart、 TopicAction和 TopicEnd。
  • 目前追蹤與範圍識別碼採用基於 GUID 的表示法,取代 OpenTelemetry 標準的 32 字元追蹤 ID 與 16 字元的擴展 ID 十六進位格式。
  • 為了簡化報告與故障排除,避免同時傳送代理層級與環境層級遙測資料至同一個 Application Insights 實例。
  • 遙測數據可能在由 GitHub Copilot 架構驅動的代理程式與由標準架構驅動的代理程式間有所不同。
  • 確保您的環境層級 Application Insights 設定符合資料駐留、隱私及基於角色的存取控制(RBAC)要求。
  • 大量日誌內容,包括代理回應與工具參數,可能會被截斷。