文档索引
在此获取完整文档索引: https://code.claude.com/docs/llms.txt 使用此文件发现所有可用页面,然后再进一步探索。
使用 OpenTelemetry 进行可观测性
使用 OpenTelemetry 将 Agent SDK 的跟踪、指标和事件导出到您的可观测性后端。
当您在生产环境中运行智能体时,您需要了解它们的行为:
- 它们调用了哪些工具
- 每个模型请求花了多长时间
- 消耗了多少令牌
- 哪里发生了故障
Agent SDK 可以将此数据作为 OpenTelemetry 跟踪、指标和日志事件导出到任何接受 OpenTelemetry 协议(OTLP)的后端,如 Honeycomb、Datadog、Grafana、Langfuse 或自托管收集器。
本指南说明 SDK 如何发出遥测数据、如何配置导出,以及数据到达后端后如何标记和过滤。要直接从 SDK 响应流读取令牌使用量和成本而不是导出到后端,请参阅跟踪成本和使用量。
SDK 中遥测数据的流向
Agent SDK 将 Claude Code CLI 作为子进程运行,并通过本地管道与其通信。CLI 内置了 OpenTelemetry 仪表化:它在每个模型请求和工具执行周围记录 span,为令牌和成本计数器发出指标,并为提示和工具结果发出结构化日志事件。SDK 本身不产生遥测数据。相反,它将配置传递给 CLI 进程,CLI 直接导出到您的收集器。
配置作为环境变量传递。默认情况下,子进程继承应用程序的环境,因此您可以在两个地方配置遥测:
- 进程环境:在应用程序启动之前在 shell、容器或编排器中设置变量。每个
query()调用都会自动获取它们,无需代码更改。这是生产部署的推荐方法。 - 按调用选项:在
ClaudeAgentOptions.env(Python)或options.env(TypeScript)中设置变量。当同一进程中的不同智能体需要不同的遥测设置时使用此方式。在 Python 中,env合并到继承的环境之上。在 TypeScript 中,env完全替换继承的环境,因此在传递的对象中包含...process.env。
CLI 导出三个独立的 OpenTelemetry 信号。每个都有自己的启用开关和自己的导出器,因此您可以只打开需要的。
| 信号 | 包含内容 | 启用方式 |
|---|---|---|
| 指标 | 令牌、成本、会话、代码行数和工具决策的计数器 | OTEL_METRICS_EXPORTER |
| 日志事件 | 每个提示、API 请求、API 错误和工具结果的结构化记录 | OTEL_LOGS_EXPORTER |
| 跟踪 | 每次交互、模型请求、工具调用和钩子的 span(测试版) | OTEL_TRACES_EXPORTER 加 CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 |
有关指标名称、事件名称和属性的完整列表,请参阅 Claude Code 监控参考。Agent SDK 发出相同的数据,因为它运行相同的 CLI。Span 名称在下面的读取智能体跟踪中列出。
启用遥测导出
遥测默认关闭,直到您设置 CLAUDE_CODE_ENABLE_TELEMETRY=1 并选择至少一个导出器。最常见的配置通过 OTLP HTTP 将所有三个信号发送到收集器。
以下示例在字典中设置变量并通过 options.env 传递它们。智能体运行单个任务,CLI 将 span、指标和事件导出到 collector.example.com 的收集器,同时循环消费响应流:
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
OTEL_ENV = {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
# Required for traces, which are in beta. Metrics and log events do not need this.
"CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1",
# Choose an exporter per signal. Use otlp for the SDK; see the Note below.
"OTEL_TRACES_EXPORTER": "otlp",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
# Standard OTLP transport configuration.
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4318",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer your-token",
}
async def main():
options = ClaudeAgentOptions(env=OTEL_ENV)
async for message in query(
prompt="List the files in this directory", options=options
):
print(message)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
const otelEnv = {
CLAUDE_CODE_ENABLE_TELEMETRY: "1",
// Required for traces, which are in beta. Metrics and log events do not need this.
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA: "1",
// Choose an exporter per signal. Use otlp for the SDK; see the Note below.
OTEL_TRACES_EXPORTER: "otlp",
OTEL_METRICS_EXPORTER: "otlp",
OTEL_LOGS_EXPORTER: "otlp",
// Standard OTLP transport configuration.
OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf",
OTEL_EXPORTER_OTLP_ENDPOINT: "http://collector.example.com:4318",
OTEL_EXPORTER_OTLP_HEADERS: "Authorization=Bearer your-token",
};
for await (const message of query({
prompt: "List the files in this directory",
// env replaces the inherited environment in TypeScript, so spread
// process.env first to keep PATH, ANTHROPIC_API_KEY, and other variables.
options: { env: { ...process.env, ...otelEnv } },
})) {
console.log(message);
}
由于子进程默认继承应用程序的环境,您可以通过在 Dockerfile、Kubernetes 清单或 shell 配置文件中导出这些变量并完全省略 options.env 来实现相同的结果。
console 导出器将遥测数据写入标准输出,SDK 将其用作消息通道。在通过 SDK 运行时不要将 console 设置为导出器值。要在本地检查遥测数据,请将 OTEL_EXPORTER_OTLP_ENDPOINT 指向本地收集器或一体化 Jaeger 容器。
从短时间调用中刷新遥测数据
CLI 批量处理遥测数据并按间隔导出。在正常进程退出时,它会尝试刷新待处理数据,但刷新受短超时限制,因此如果收集器响应缓慢,span 仍可能被丢弃。如果您的进程在 CLI 关闭之前被杀死,批量缓冲区中的任何内容都会丢失。缩短导出间隔可减少两个窗口。
默认情况下,指标每 60 秒导出一次,跟踪和日志每 5 秒导出一次。以下示例缩短了所有三个间隔,以便在短任务仍在运行时数据到达收集器:
OTEL_ENV = {
# ... exporter configuration from the previous example ...
"OTEL_METRIC_EXPORT_INTERVAL": "1000",
"OTEL_LOGS_EXPORT_INTERVAL": "1000",
"OTEL_TRACES_EXPORT_INTERVAL": "1000",
}
const otelEnv = {
// ... exporter configuration from the previous example ...
OTEL_METRIC_EXPORT_INTERVAL: "1000",
OTEL_LOGS_EXPORT_INTERVAL: "1000",
OTEL_TRACES_EXPORT_INTERVAL: "1000",
};
读取智能体跟踪
跟踪为您提供了智能体运行的最详细视图。设置 CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 后,智能体循环的每一步都成为一个您可以在跟踪后端中检查的 span:
claude_code.interaction: 包装智能体循环的单轮,从接收到提示到产生响应。claude_code.llm_request: 包装对 Claude API 的每次调用,带有模型名称、延迟和令牌计数作为属性。claude_code.tool: 包装每次工具调用,带有权限等待(claude_code.tool.blocked_on_user)和执行本身(claude_code.tool.execution)的子 span。claude_code.hook: 包装每次钩子执行。除了上述变量外,还需要详细的测试版跟踪(ENABLE_BETA_TRACING_DETAILED=1和BETA_TRACING_ENDPOINT)。
llm_request、tool 和 hook span 是包含它们的 claude_code.interaction span 的子级。当智能体通过 Task 工具生成子智能体时,子智能体的 llm_request 和 tool span 嵌套在父智能体的 claude_code.tool span 下,因此完整的委派链显示为一个跟踪。
Span 默认携带 session.id 属性。当您对同一会话进行多次 query() 调用时,在后端按 session.id 过滤以将它们视为一个时间线。如果 OTEL_METRICS_INCLUDE_SESSION_ID 设置为假值,则省略该属性。
跟踪处于测试版。Span 名称和属性可能在版本之间更改。有关跟踪导出器配置变量,请参阅监控参考中的跟踪(测试版)。
将跟踪链接到您的应用程序
SDK 自动将 W3C 跟踪上下文传播到 CLI 子进程。当您在应用程序中有活动的 OpenTelemetry span 时调用 query(),SDK 将 TRACEPARENT 和 TRACESTATE 注入子进程环境,CLI 读取它们以便其 claude_code.interaction span 成为您 span 的子级。智能体运行随后出现在应用程序的跟踪中,而不是作为断开连接的根。
CLI 还将 TRACEPARENT 转发给它运行的每个 Bash 和 PowerShell 命令。如果通过 Bash 工具启动的命令发出自己的 OpenTelemetry span,这些 span 嵌套在包装该命令的 claude_code.tool.execution span 下。
当您在 options.env 中显式设置 TRACEPARENT 时,自动注入会被跳过,因此您可以根据需要固定特定的父上下文。交互式 CLI 会话完全忽略传入的 TRACEPARENT;只有 Agent SDK 和 claude -p 运行会遵守它。有关完整的 span 和属性参考,请参阅监控参考中的跟踪(测试版)。
为您的智能体标记遥测数据
默认情况下,CLI 将 service.name 报告为 claude-code。如果您运行多个智能体,或将 SDK 与其他导出到同一收集器的服务一起运行,请覆盖服务名称并添加资源属性,以便在后端按智能体过滤。
以下示例重命名服务并附加部署元数据。这些值作为 OpenTelemetry 资源属性应用于智能体发出的每个 span、指标和事件:
options = ClaudeAgentOptions(
env={
# ... exporter configuration ...
"OTEL_SERVICE_NAME": "support-triage-agent",
"OTEL_RESOURCE_ATTRIBUTES": "service.version=1.4.0,deployment.environment=production",
},
)
const options = {
env: {
...process.env,
// ... exporter configuration ...
OTEL_SERVICE_NAME: "support-triage-agent",
OTEL_RESOURCE_ATTRIBUTES:
"service.version=1.4.0,deployment.environment=production",
},
};
将操作归因于最终用户
CLI 根据其用于调用 Anthropic 的凭据将身份属性附加到每个事件。当您构建从一个部署为多个最终用户服务的应用程序时,这些属性标识您服务的凭据,而不是智能体代表其行事的最终用户。
要使工具调用和 MCP 活动可归因于应用程序的最终用户,请在每次 query() 调用时将最终用户身份作为资源属性注入。在插值之前对值进行百分比编码,因为 OTEL_RESOURCE_ATTRIBUTES 保留逗号、空格和等号。以下示例将请求用户和租户附加到来自一个请求的每个 span 和事件:
from urllib.parse import quote
options = ClaudeAgentOptions(
env={
# ... exporter configuration ...
"OTEL_RESOURCE_ATTRIBUTES": f"enduser.id={quote(request.user_id)},tenant.id={quote(request.tenant_id)}",
},
)
const options = {
env: {
...process.env,
// ... exporter configuration ...
OTEL_RESOURCE_ATTRIBUTES: `enduser.id=${encodeURIComponent(request.userId)},tenant.id=${encodeURIComponent(request.tenantId)}`,
},
};
附加了最终用户身份后,tool_decision、tool_result、mcp_server_connection 和 permission_mode_changed 事件成为可转发到安全信息和事件管理(SIEM)平台的按用户审计跟踪。有关安全相关事件的完整列表及其各自携带的属性,请参阅监控参考中的审计安全事件。
控制导出中的敏感数据
遥测默认是结构性的。持续时间、模型名称和工具名称记录在每个 span 上;当底层 API 请求返回使用数据时记录令牌计数,因此失败或中止的请求的 span 可能省略它们。您的智能体读写的内容默认不记录。这些选择启用变量将内容添加到导出数据中:
| 变量 | 添加内容 |
|---|---|
OTEL_LOG_USER_PROMPTS=1 | claude_code.user_prompt 事件和 claude_code.interaction span 上的提示文本 |
OTEL_LOG_TOOL_DETAILS=1 | claude_code.tool_result 事件上的工具输入参数(文件路径、shell 命令、搜索模式) |
OTEL_LOG_TOOL_CONTENT=1 | claude_code.tool 上作为 span 事件的完整工具输入和输出主体,截断至 60 KB。需要启用跟踪 |
OTEL_LOG_RAW_API_BODIES | 完整的 Anthropic Messages API 请求和响应 JSON 作为 claude_code.api_request_body 和 claude_code.api_response_body 日志事件。设置为 1 表示截断至 60 KB 的内联主体,或 file:<dir> 表示磁盘上未截断的主体,在事件中带有 body_ref 路径。主体包含整个对话历史,扩展思考内容已编辑。启用此选项意味着同意上述三个变量会揭示的所有内容 |
除非您的可观测性管道被批准存储智能体处理的数据,否则请保持这些变量未设置。有关属性和编辑行为的完整列表,请参阅监控参考中的安全和隐私。
相关文档
这些指南涵盖了监控和部署智能体的相关主题:
- 跟踪成本和使用量:无需外部后端即可从消息流读取令牌和成本数据。
- 托管 Agent SDK:在容器中部署智能体,您可以在环境级别设置 OpenTelemetry 变量。
- 监控:CLI 发出的每个环境变量、指标和事件的完整参考。