使用 OpenTelemetry 监控 Agent 使用情况
本文介绍了如何为 VS Code 中的 Copilot Chat Agent 交互启用和配置 OpenTelemetry 监控。
Copilot Chat 可以通过 OpenTelemetry (OTel) 导出追踪 (traces)、指标 (metrics) 和事件 (events),使您能够洞察 Agent 交互、LLM 调用、工具执行和令牌使用情况。所有信号名称和属性均遵循 OTel GenAI 语义规范,因此数据适用于任何兼容 OTel 的后端。
采集的内容
Copilot Chat 发出三种类型的 OTel 信号:追踪、指标和事件。
属性命名空间
Copilot Chat 在三个命名空间下发出 OTel 属性
| 命名空间 | 来源 | 何时使用 |
|---|---|---|
gen_ai.* |
OTel GenAI 语义规范 | 当存在标准键时使用 |
github.copilot.* |
规范的 Copilot 特定命名空间,与 GitHub Copilot CLI OpenTelemetry 规范 共享 | 建议用于新的仪表板、警报和查询 |
copilot_chat.* |
原始 VS Code 扩展命名空间 | 旧版。现在有几个键在发出时会同时包含 github.copilot.* 等效项 |
旧版 copilot_chat.* 键将无限期持续发出,以便现有的收集器、仪表板和下游消费者无需更改即可继续工作。没有终止日期。本节中的表格将双重发出的行标记为旧版 (Legacy),并指向首选键。
追踪 (Traces)
每个 Agent 交互都会产生一个分层跨度 (span) 树,以捕获完整的执行流
invoke_agent copilot [~15s]
├── chat gpt-4o [~3s] (LLM requests tool calls)
├── execute_tool readFile [~50ms]
├── execute_tool runCommand [~2s]
├── chat gpt-4o [~4s] (LLM generates final response)
└── (span ends)
当 Agent 调用子 Agent(例如通过 runSubagent 工具)时,追踪上下文会自动传播。子 Agent 的 invoke_agent 跨度会作为父 Agent execute_tool 跨度的子级出现,从而在异步边界之间生成连接的追踪树。
invoke_agent 跨度
包装整个 Agent 编排,包括所有 LLM 调用和工具执行。
| 属性 | 描述 |
|---|---|
gen_ai.operation.name |
始终为 invoke_agent |
gen_ai.provider.name |
提供商(例如 github) |
gen_ai.agent.name |
Agent 名称(例如 copilot, copilotcli, claude) |
gen_ai.conversation.id |
对话会话 ID |
gen_ai.request.model |
请求的模型 |
gen_ai.response.model |
解析后的模型 |
gen_ai.usage.input_tokens |
会话中的总输入令牌数 |
gen_ai.usage.output_tokens |
会话中的总输出令牌数 |
gen_ai.usage.cache_read.input_tokens |
缓存读取输入令牌(如果可用) |
gen_ai.usage.cache_creation.input_tokens |
缓存创建输入令牌(如果可用) |
github.copilot.agent.type |
builtin, custom 或 plugin |
github.copilot.git.repository |
Git 仓库的远程 URL(如果在 Git 仓库中) |
github.copilot.git.branch |
活动分支(如果在 Git 仓库中) |
github.copilot.git.commit_sha |
当前提交(如果在 Git 仓库中) |
github.copilot.github.org |
GitHub 组织所有者(仅限 GitHub 远程仓库) |
copilot_chat.repo.remote_url |
旧版。建议使用 github.copilot.git.repository |
copilot_chat.repo.head_branch_name |
旧版。建议使用 github.copilot.git.branch |
copilot_chat.repo.head_commit_hash |
旧版。建议使用 github.copilot.git.commit_sha |
copilot_chat.turn_count |
此会话中的 LLM 往返次数 |
error.type |
错误类型(失败时) |
gen_ai.input.messages |
完整提示消息(仅内容捕获) |
gen_ai.output.messages |
完整响应消息(仅内容捕获) |
gen_ai.tool.definitions |
工具架构(仅内容捕获) |
chat 跨度
每个 LLM API 调用对应一个跨度。
| 属性 | 描述 |
|---|---|
gen_ai.operation.name |
始终为 chat |
gen_ai.provider.name |
提供商名称 |
gen_ai.request.model |
请求的模型 |
gen_ai.response.model |
解析后的模型 |
gen_ai.response.finish_reasons |
停止原因(例如 ["stop"]) |
gen_ai.request.max_tokens |
最大输出令牌数 |
gen_ai.request.temperature |
Temperature(已设置时) |
gen_ai.request.top_p |
Top-p(已设置时) |
gen_ai.usage.input_tokens |
此调用的输入令牌数 |
gen_ai.usage.output_tokens |
此调用的输出令牌数 |
gen_ai.usage.cache_read.input_tokens |
缓存读取输入令牌(如果可用) |
gen_ai.usage.cache_creation.input_tokens |
缓存创建输入令牌(如果可用) |
gen_ai.usage.reasoning.output_tokens |
推理令牌(如果可用) |
gen_ai.usage.reasoning_tokens |
旧版。建议使用 gen_ai.usage.reasoning.output_tokens |
copilot_chat.time_to_first_token |
首个 SSE 令牌的生成时间(毫秒) |
server.address |
API 主机名 |
error.type |
错误类型(失败时) |
execute_tool 跨度
每个工具调用对应一个跨度。
| 属性 | 描述 |
|---|---|
gen_ai.operation.name |
始终为 execute_tool |
gen_ai.tool.name |
工具名称(例如 readFile) |
gen_ai.tool.type |
function 或 extension (MCP 工具) |
gen_ai.tool.call.id |
工具调用标识符 |
github.copilot.tool.parameters.edit_type |
对于编辑工具:create, update, str_replace 或 insert |
github.copilot.tool.parameters.skill_name |
用于技能调用 |
github.copilot.tool.parameters.mcp_server_name_hash |
对于 MCP 工具:服务器名称的 SHA-256 哈希值 |
github.copilot.tool.parameters.mcp_tool_name |
对于 MCP 工具:被调用的工具名称 |
github.copilot.tool.parameters.command |
对于 shell 工具(仅内容捕获,已截断) |
github.copilot.tool.parameters.file_path |
对于文件工具(仅内容捕获) |
github.copilot.tool.parameters.mcp_server_name |
对于 MCP 工具(仅内容捕获) |
error.type |
错误类型(失败时) |
gen_ai.tool.call.arguments |
工具输入参数(仅内容捕获) |
gen_ai.tool.call.result |
工具输出(仅内容捕获) |
execute_hook 跨度
每个钩子执行对应一个跨度(例如 PreToolUse, Stop)。
| 属性 | 描述 |
|---|---|
gen_ai.operation.name |
始终为 execute_hook |
github.copilot.hook.decision |
pass, block 或 non_blocking_error |
github.copilot.hook.duration |
钩子执行时长(秒) |
github.copilot.hook.tool_names |
钩子作用域包含的工具(JSON 数组) |
copilot_chat.hook_type |
钩子事件(例如 PreToolUse) |
copilot_chat.hook_result_kind |
success, error 或 non_blocking_error |
copilot_chat.hook_input |
钩子输入有效负载(已截断) |
copilot_chat.hook_output |
钩子标准输出,成功时(已截断) |
error.type |
错误类型(失败时) |
指标 (Metrics)
GenAI 语义规范指标
| 指标名称 | 类型 | 描述 |
|---|---|---|
gen_ai.client.operation.duration |
直方图 | LLM API 调用时长(秒) |
gen_ai.client.token.usage |
直方图 | 令牌计数(输入和输出) |
扩展特定指标
| 指标名称 | 类型 | 描述 |
|---|---|---|
copilot_chat.tool.call.count |
计数器 | 按名称和成功状态统计的工具调用次数 |
copilot_chat.tool.call.duration |
直方图 | 工具执行延迟(毫秒) |
copilot_chat.agent.invocation.duration |
直方图 | Agent 端到端执行时长(秒) |
copilot_chat.agent.turn.count |
直方图 | 每个 Agent 调用中的 LLM 往返次数 |
copilot_chat.session.count |
计数器 | 启动的聊天会话数 |
copilot_chat.time_to_first_token |
直方图 | 首个 SSE 令牌的生成时间(秒) |
Agent 活动和结果指标跟踪所有界面(行内聊天、本地 Agent、Copilot CLI Agent、Claude Agent 和 Copilot 编码 Agent)的 Agent 代码更改
| 指标名称 | 类型 | 描述 |
|---|---|---|
copilot_chat.edit.acceptance.count |
计数器 | 编辑接受和拒绝决策(行内聊天、聊天编辑、hunk 级别) |
copilot_chat.chat_edit.outcome.count |
计数器 | 文件级聊天编辑会话结果(接受、拒绝、保存) |
copilot_chat.lines_of_code.count |
计数器 | 被接受的 Agent 编辑所增加或删除的代码行数 |
copilot_chat.edit.survival.four_gram |
直方图 | 4-gram 文本相似度存活分数 (0-1) |
copilot_chat.edit.survival.no_revert |
直方图 | 无还原存活分数 (0-1) |
copilot_chat.user.action.count |
计数器 | 用户交互操作:复制、插入、应用、跟进 |
copilot_chat.user.feedback.count |
计数器 | 聊天响应的点赞和点踩投票 |
copilot_chat.agent.edit_response.count |
计数器 | 按成功或失败统计的 Agent 编辑响应 |
copilot_chat.agent.summarization.count |
计数器 | 上下文摘要结果(应用、失败) |
copilot_chat.pull_request.count |
计数器 | 通过 CLI Agent 创建的 Pull Request |
copilot_chat.cloud.session.count |
计数器 | 按合作伙伴 Agent 统计的云端和远程 Agent 会话 |
copilot_chat.cloud.pr_ready.count |
计数器 | 远程 Agent 作业的 PR 就绪通知 |
指标包含用于过滤的属性,例如 gen_ai.request.model, gen_ai.provider.name, gen_ai.tool.name, copilot_chat.edit.source 和 error.type。
活动
| 事件 | 描述 |
|---|---|
gen_ai.client.inference.operation.details |
包含模型、令牌和完成原因的完整 LLM 调用元数据 |
copilot_chat.session.start |
在新聊天会话开始时发出 |
copilot_chat.tool.call |
包含计时和错误详细信息的单次工具调用 |
copilot_chat.agent.turn |
包含令牌计数的单次轮次 LLM 往返 |
copilot_chat.edit.feedback |
用户接受或拒绝了文件级 Agent 编辑 |
copilot_chat.edit.hunk.action |
用户接受或拒绝了单个 hunk |
copilot_chat.inline.done |
行内聊天编辑已接受或拒绝 |
copilot_chat.edit.survival |
定期测量 AI 生成的代码在被接受后存活了多少 |
copilot_chat.user.feedback |
用户对聊天响应进行了投票(点赞或点踩) |
copilot_chat.cloud.session.invoke |
云端或远程 Agent 会话已启动 |
资源属性
所有信号都携带这些资源属性
| 属性 | 值 |
|---|---|
service.name |
copilot-chat (可通过 OTEL_SERVICE_NAME 配置) |
service.version |
扩展版本 |
session.id |
每个 VS Code 窗口唯一 |
使用 OTEL_RESOURCE_ATTRIBUTES 添加自定义资源属性,以便按团队、部门或其他组织边界进行过滤
export OTEL_RESOURCE_ATTRIBUTES="team.id=platform,department=engineering"
内容捕获
默认情况下,不会捕获提示内容、响应或工具参数。仅包含模型名称、令牌计数和持续时间等元数据。
要捕获完整内容,请启用 github.copilot.chat.otel.captureContent 设置,或设置 COPILOT_OTEL_CAPTURE_CONTENT=true。这将在跨度属性中填充完整的提示消息、响应消息、系统提示、工具架构、工具参数和工具结果。
内容捕获可能包含敏感信息,例如代码、文件内容和用户提示。仅在受信任的环境中启用此功能。
启用 OTel 监控
当满足以下任何条件时,OTel 将被激活
- github.copilot.chat.otel.enabled 为
true - github.copilot.chat.otel.dbSpanExporter.enabled 为
true 设置COPILOT_OTEL_ENABLED=true- 设置了
OTEL_EXPORTER_OTLP_ENDPOINT
VS Code 设置
打开设置(⌘, (Windows, Linux Ctrl+,))并搜索 copilot otel
| 设置 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| github.copilot.chat.otel.enabled | 布尔值 | false |
启用 OTel 发出 |
| github.copilot.chat.otel.exporterType | 字符串 | "otlp-http" |
otlp-http, otlp-grpc, console 或 file |
| github.copilot.chat.otel.otlpEndpoint | 字符串 | "https://:4318" |
OTLP 收集器端点 |
| github.copilot.chat.otel.captureContent | 布尔值 | false |
捕获完整的提示和响应内容 |
| github.copilot.chat.otel.maxAttributeSizeChars | 整数 | 0 |
每个内容属性(提示、工具参数、工具结果)的最大字符数。0 表示禁用截断。设置正值以匹配后端的属性大小限制。 |
| github.copilot.chat.otel.outfile | 字符串 | "" |
JSON 行输出的文件路径 |
| github.copilot.chat.otel.dbSpanExporter.enabled | 布尔值 | false |
将 OTel 跨度持久化到本地 SQLite 数据库,用于 Chat: Export Agent Traces DB 命令。隐式启用 OTel。 |
环境变量
环境变量的优先级始终高于 VS Code 设置。
| 变量 | 默认值 | 描述 |
|---|---|---|
COPILOT_OTEL_ENABLED |
false |
启用 OTel。当设置了 OTEL_EXPORTER_OTLP_ENDPOINT 时也会启用。 |
COPILOT_OTEL_ENDPOINT |
OTLP 端点 URL(优先级高于 OTEL_EXPORTER_OTLP_ENDPOINT) |
|
OTEL_EXPORTER_OTLP_ENDPOINT |
标准 OTel OTLP 端点 URL | |
OTEL_EXPORTER_OTLP_PROTOCOL |
http/protobuf |
OTLP 协议。仅 grpc 会更改行为。 |
COPILOT_OTEL_PROTOCOL |
覆盖 OTLP 协议 (grpc 或 http)。优先级高于 OTEL_EXPORTER_OTLP_PROTOCOL。 |
|
OTEL_SERVICE_NAME |
copilot-chat |
资源属性中的服务名称 |
OTEL_RESOURCE_ATTRIBUTES |
额外的资源属性 (key1=val1,key2=val2) |
|
COPILOT_OTEL_CAPTURE_CONTENT |
false |
捕获完整的提示和响应内容 |
COPILOT_OTEL_MAX_ATTRIBUTE_SIZE_CHARS |
0 |
覆盖内容属性的最大字符大小。0 表示禁用截断。优先级高于 maxAttributeSizeChars 设置。 |
COPILOT_OTEL_LOG_LEVEL |
info |
最低日志级别:trace, debug, info, warn 或 error。 |
COPILOT_OTEL_FILE_EXPORTER_PATH |
将所有信号作为 JSON 行写入此文件。 | |
COPILOT_OTEL_HTTP_INSTRUMENTATION |
false |
启用 HTTP 级别的 OTel 插桩。 |
OTEL_EXPORTER_OTLP_HEADERS |
身份验证标头(例如 Authorization=Bearer token) |
命令
当 github.copilot.chat.otel.dbSpanExporter.enabled 为 true 时,Copilot Chat 会将 OTel 跨度持久化到本地 SQLite 数据库中。这对于离线检查或在不运行 OTLP 后端的情况下共享追踪数据非常有用。
| 命令 | 描述 |
|---|---|
Chat: Export Agent Traces DB (github.copilot.chat.otel.exportAgentTracesDB) |
将本地 SQLite 跨度数据库导出为 .db 文件。仅当 dbSpanExporter.enabled 设置为 true 时可用。 |
后台 Agent 和 Claude Agent 的追踪结构
启用 OTel 后,所有 Agent 类型都会自动进行插桩。启用前台 Agent 追踪的相同设置也会启用 Copilot CLI 和 Claude Agent 追踪。
Copilot CLI (后台 Agent)
Copilot CLI SDK 在与聊天扩展相同的 VS Code 进程中运行,并生成丰富的追踪层次结构,包括子 Agent、权限、钩子和工具调用。扩展包装跨度 (invoke_agent copilotcli, 服务 copilot-chat) 是 SDK 原生跨度 (服务 github-copilot) 的父级。两者都会出现在您的收集器的同一个追踪中。
CLI 会话也会在 VS Code 的Agent Debug Log 面板中显示完整的 SDK 层次结构,与追踪查看器中显示的内容相同。调试面板即使在 OTel 导出被禁用时也能工作,因为 SDK 的内部追踪始终处于活动状态。
当 OTel 导出被禁用时,调试面板会自动捕获完整的提示和响应内容。当 OTel 导出被启用时, github.copilot.chat.otel.captureContent 设置将控制调试面板和 OTLP 导出的内容捕获。
Copilot CLI (终端会话)
使用 New Copilot CLI Session 启动的终端 CLI 会话在单独的进程中运行。启用 OTel 后,扩展会将 COPILOT_OTEL_ENABLED 和 OTEL_EXPORTER_OTLP_ENDPOINT 转发到终端进程。终端追踪显示为服务 github-copilot 下的独立根追踪,不会链接到扩展追踪。
CLI 运行时仅支持 otlp-http。当配置了 otlp-grpc 时,终端 CLI 仍使用 HTTP。在同一端口上同时提供两种协议的后端(例如 Aspire Dashboard)可以透明地工作。
Claude Agent
启用 OTel 后,Claude Agent 会话会生成服务 copilot-chat 下的扩展级跨度,并遵循 GenAI 语义规范。扩展通过拦截 Claude SDK 消息并代理通过本地 HTTP 服务器发出的 LLM 调用来创建跨度。
invoke_agent claude 根跨度包装了每个用户请求,并带有嵌套的 chat、execute_tool 和 execute_hook 跨度。当工具是 Agent(Claude 子 Agent 调用)时,子 chat 和 execute_tool 跨度会嵌套在下方,从而提供完整的子 Agent 可视性。
按 Agent 类型过滤
在您的追踪查看器中,按 service.name 过滤以查看特定 Agent 运行时的追踪
service.name |
来源 |
|---|---|
copilot-chat |
前台 Agent、CLI 包装器和 Claude Agent 跨度(扩展发出) |
github-copilot |
CLI SDK 原生跨度和 CLI 终端会话 |
claude-code |
Claude Code 子进程 SDK 遥测(当 CLAUDE_CODE_ENABLE_TELEMETRY 被转发时) |
在 copilot-chat 服务中,通过 gen_ai.agent.name 区分 Agent 类型
gen_ai.agent.name |
Agent 类型 |
|---|---|
GitHub Copilot Chat |
前台 Agent (Agent 模式) |
copilotcli |
CLI 包装器跨度 |
claude |
Claude Agent |
与可观测性后端配合使用
Copilot Chat 的 OTel 输出适用于任何支持 OTLP 协议的后端。将 github.copilot.chat.otel.otlpEndpoint 设置或 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量指向后端的 OTLP 摄取 URL,并配置导出器类型以匹配后端的协议 (otlp-http 或 otlp-grpc)。
Aspire Dashboard
Aspire Dashboard 是本地开发最简单的选择。它是一个带有内置 OTLP 端点和追踪查看器的单一应用程序,无需云账户。
您可以使用 Aspire CLI 启动仪表板
aspire dashboard run
或者从其 Docker 容器镜像运行相同的独立仪表板
docker run --rm -d -p 18888:18888 -p 4318:18890 --name aspire-dashboard \
mcr.microsoft.com/dotnet/aspire-dashboard:latest
VS Code 配置
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.captureContent": true
}
打开 https://:18888 并转到 Traces 以查看您的 Agent 交互跨度。

Jaeger
Jaeger 是一个开源的分布式追踪平台,直接支持 OTLP。
docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/jaeger:latest
VS Code 配置
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.otlpEndpoint": "https://:4318"
}
打开 https://:16686,选择服务 copilot-chat,然后选择 Find Traces。
Azure Application Insights
使用带有 Azure Monitor 导出器 的 OTel Collector,将 Copilot Chat 遥测数据转发到 Application Insights。将 VS Code 的 github.copilot.chat.otel.otlpEndpoint 设置指向收集器的 OTLP 端点,并配置收集器将其导出到您的 Application Insights 连接字符串。
有关带有现成仪表板的端到端设置,请参阅 使用 Grafana 监控 AI 编码 Agent。该指南介绍了如何运行 OTel Collector、将 VS Code 指向它,以及导入预制的 Azure Managed Grafana 仪表板。该仪表板可视化了来自 Application Insights 的 Copilot 操作、输入和输出令牌、聊天会话、工具调用以及每个模型的响应时间和 TTFT。
Langfuse
Langfuse 是一个开源的 LLM 可观测性平台,具有原生 OTLP 摄取功能,并支持 OTel GenAI 语义规范。
VS Code 配置
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.otlpEndpoint": "https://:3000/api/public/otel",
"github.copilot.chat.otel.captureContent": true
}
使用 OTEL_EXPORTER_OTLP_HEADERS 环境变量设置身份验证标头。有关详细信息,请参阅 Langfuse OTel 文档。
其他后端
任何兼容 OTLP 的后端均可工作,包括 Grafana Tempo、Honeycomb 和 Datadog。请参阅各后端的文档以获取 OTLP 摄取设置。
其他导出器示例
默认导出器是 otlp-http。您可以切换到 otlp-grpc、console 或 file 以适应您的后端或调试工作流程。
OTLP/gRPC
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.exporterType": "otlp-grpc",
"github.copilot.chat.otel.otlpEndpoint": "https://:4317"
}
控制台输出(快速调试)
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.exporterType": "console"
}
基于文件的输出(离线或 CI)
{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.exporterType": "file",
"github.copilot.chat.otel.outfile": "/tmp/copilot-otel.jsonl"
}
远程收集器的身份验证标头只能通过 OTEL_EXPORTER_OTLP_HEADERS 环境变量进行配置(例如 Authorization=Bearer your-token)。
安全与隐私
OTel 监控默认关闭,除非您显式启用,否则不会发出任何数据。您可以控制采集的内容及其去向。
| 方面 | 详细信息 |
|---|---|
| 默认关闭 | 除非您显式启用,否则不会发出任何 OTel 数据。OTel SDK 在禁用时不会加载,从而实现零运行时开销。 |
| 默认无内容 | 提示、响应和工具参数需要通过 captureContent 开启。 |
| 默认属性中无 PII | 会话 ID、模型名称和令牌计数不是个人身份信息。 |
| 用户配置的端点 | 数据仅发送到您指向的位置。没有“电话回家”行为。 |