SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-13

Claude Code 费用跟踪工具对比:日志、用量页与 OTel

Claude Code 费用跟踪器读取的数据并不相同。本文对比本地 JSONL 日志解析器、内置账户用量页面和 OpenTelemetry,说明各自能回答什么、为何结果会不一致。

Claude Code 费用跟踪器实际读取的内容

每个 Claude Code 费用跟踪器都会读取三类数据源之一,而数据源决定了它能回答什么问题。日志解析器读取您本地磁盘上的会话记录文件。仪表板读取 Anthropic 为您的账户或组织保留的使用记录。指标后端读取 Claude Code 在启用后发出的 OpenTelemetry(OTel)数据流。这三类工具可能同时正确,但结果仍然不一致,因为它们统计的是不同内容。

本指南不再解释 token。Claude Code 如何统计 token 使用量介绍输入、输出、缓存写入和缓存读取;只有先理解这些内容,仪表板数据才有意义。这里讨论的问题更具体:对于每种工具类型,它能看到什么,以及永远无法看到什么。

同一天出现 3 个 Claude Code 费用跟踪工具的原因

同一天发布了 3 个独立的 Claude Code 费用跟踪工具。它们不是同一工具的 3 个版本,这一点才是关键。其中一个解析本地会话文件;一个封装账户用量页面;还有一个是由您自行运行的托管式跟踪后端。

它们同时出现,是因为 Agent 会话的成本不再直观。聊天的费用大致可以从屏幕上看到。Agent 会读取 20 个文件、运行测试套件,并在每轮交互中重新发送整个对话,因此费用取决于您从未输入的上下文。订阅模式下则完全没有具体的金额,只有一个用量条,而且有些日子消耗得更快。3 个工具分别填补了这一空白的不同部分。

形式 1:本地日志解析器告诉您今天消耗了多少

Claude Code 会将每次对话以 JSON Lines(JSONL)格式存储在 ~/.claude/projects/<project>/<session-id>.jsonl 中,其中 <project> 是您的工作目录路径,非字母数字字符会替换为 -。该文件中的每轮 assistant 响应都包含本次请求的 token 数量。日志解析器会将这些数量相加并计算价格。

ccusage 是大多数人最终选择的工具。它无需安装:

npx ccusage@latest daily
npx ccusage@latest daily --breakdown
npx ccusage@latest blocks
npx ccusage@latest session --json

daily 按日期汇总。--breakdown 按模型拆分每一行,因此您可以看出某个 Opus 下午的用量是否占了一周的大部分。blocks 按订阅重置所依据的五小时窗口分组。session 按对话汇总,--instances 按项目分组,因此您可以看出哪个代码仓库的成本更高。添加 --since--until 可限制日期范围,并运行 npx ccusage@latest daily --help 查看您的版本所需的日期格式。截至 August 2026,它还可以读取其他 agent CLI 的数据,包括 Codex 和 OpenCode;如果您要比较这些工具,这一点很重要。

价格来自模型价格表,该工具提供三种成本模式。--mode auto 优先使用 Claude Code 写入文件的 costUSD 值;如果该值不存在,则根据 token 数量计算。--mode calculate 始终根据 token 数量计算,并忽略已记录的成本。--mode display 只显示已记录的成本,对于没有记录成本的行则输出 $0.00。如果某个总数看起来不正确,请先使用 calculate 运行相同的报告,再使用 display 运行一次。两者差距较大,表示大多数条目都没有记录成本,因此您看到的全部都是估算值。

相同的数据也可以用于提示符。ccusage statusline 会输出一行简短内容,用于 Claude Code 状态栏;您可以像配置其他状态栏命令一样,将它接入 ~/.claude/settings.json。有关设置块及其接收字段,请参阅 构建 Claude Code 状态栏

日志解析器无法看到未在此机器上发生的活动。另一台笔记本电脑、claude.ai 上的会话、队友的工作:这些会话记录存储在各自的磁盘上。旧数据也可能缺失,因为在 cleanupPeriodDays 设置下,会话记录默认会在 30 天后清理;除非您提前归档,否则上个季度的数据已经不存在。

还有一个风险,它与数据结构有关。Anthropic 的文档说明,条目格式属于 Claude Code 内部格式,并且会随版本变化。因此,直接解析这些文件的脚本可能在任何版本发布时失效。这适用于所有采用这种方式的工具。这也是手写一个针对 JSONL 的 jq 单行命令并不像看起来那么可靠的原因:维护中的解析器会跟踪格式变化,而您的单行命令可能在字段重命名的当天开始输出看似准确但实际错误的数字。

最后,订阅用户需要注意美元金额的含义。Pro 或 Max 不会按 token 计费,因此该数字表示按 API 标准价格计算时这些 token 的成本。它衡量的是您的使用量有多大,不是您的实际账单。如果您真正想知道的是应该选择哪个套餐,则需要单独比较;请参阅 API 计费与 Claude 订阅的比较

方式 2:内置用量界面会告诉您哪个模型消耗了预算

Claude Code 自带报告功能,但大多数人从未打开过。请在会话中运行 /usage。顶部的 Session 区块会按模型显示 token 数量,并显示当前会话的美元金额。该金额根据 token 数量和标准目录价格在本地计算。它不反映折扣或促销价格,因此可能与发票金额不同。/clear 开始新对话后,总量会重置。

如果使用 Pro、Max、Team 或 Enterprise 计划,同一界面还会显示您已使用的计划限额,并将近期用量按总量百分比归因到 skills、subagents、plugins 和各个 MCP 服务器。它会标记占近期用量 10% 或以上的行为,例如上下文过长或缓存未命中。按 dw 可在最近 24 小时和最近 7 天之间切换。这些数据是近似值,根据本机的本地会话历史计算,因此不会统计其他设备的用量。当进度条为空而不只是数值较低时,界面会告诉您该时间窗口已关闭,但不会说明如何继续工作;达到限额后该怎么做则是关于模型、上下文和计划的另一项决策。

当开发者数量超过 1 人后,数据会转移到帐户层面。API 组织可使用 Console usage 页面、Claude Code dashboard(显示每位成员的支出和已接受代码行数),以及 Claude Code Analytics API。该 API 使用管理员密钥,并返回相同的每日用户指标。Teams 和 Enterprise 计划可在管理控制台中查看支出报告并导出 CSV,数据每日更新;Enterprise 还提供 analytics API。您能看到哪些内容取决于每位开发者的登录方式,因此混合组织需要查看两份报告,再手动汇总。

如需估算预算,Anthropic 成本文档截至 August 2026 发布的数据是:每位开发者每天活跃时平均接近 $13,每位开发者每月约为 $150 到 $250,90% 的用户每个活跃日低于 $30。请将其视为企业部署中的已发布基准,而不是对您团队的预测。请先运行小规模试点并进行测量,再进行外推。

dashboard 无法看到的是低于按天和按人员粒度的数据。它们会告诉您 Opus 占用了 Tuesday 的大部分用量,但不会告诉您是哪个提示词、哪个代码仓库或哪个 CI 任务导致的。它们还存在延迟,因为组织级报告每天更新一次。因此,它们适合复盘,不适合在今天下午捕获失控的 agent。要捕获失控的 agent,需要使用限制,而不是报告;相关内容请参见在 VPS 上控制 agent 成本

方案 3:自建 OpenTelemetry 堆栈,找出是哪条提示词导致性能回退

设置一个环境变量后,Claude Code 会发出 OpenTelemetry 指标和事件。这是唯一一种能将每个用户的令牌和成本数据近乎实时地流式传输到您控制的系统中的方案。这些指标包括 claude_code.cost.usage(单位为 USD)、claude_code.token.usage(单位为令牌)、claude_code.session.countclaude_code.active_time.total

令牌指标最有价值,因为它包含多个属性。每个数据点都包含 type,其值为 inputoutputcacheReadcacheCreation;还包含 modelquery_source,其值为 mainsubagentauxiliary。此外,它还包含 agent.nameskill.namemcp_server.namemcp_tool.name。这些数据足以回答任何仪表板都无法回答的问题:账单中有多少来自子代理,而不是您自己的交互;某个 MCP 服务器是否让输入令牌数翻了一倍;有人编辑 CLAUDE.md 后,缓存读取是否大幅减少。缓存行为通常是意外成本的来源,提示词缓存何时能够收回成本会解释如何分析这些数据。

这里需要说明一个容易在相关讨论中反复出现的误区。Langfuse 是一个适合自行托管的追踪后端,在 VPS 上运行 Langfuse 的方法见自行托管 Langfuse 进行代理追踪。它的 OTLP 端点只接受追踪数据。Claude Code 导出的是指标和日志事件,而不是 span,因此将 OTEL_EXPORTER_OTLP_ENDPOINT 指向 Langfuse 后,项目会保持为空,也不会产生任何有用的错误信息。对于您自行通过 API 构建的代理,Langfuse 是合适的工具,因为您自己的代码会为每个 span 创建提示词、模型和成本信息。对于 Claude Code CLI,指标存储更合适。

在自己的 VPS 上设置 Claude Code 支出跟踪

只需要两个服务:一个接收指标的采集器,以及一个存储指标的 Prometheus。不要让这两个服务暴露在公网,因为开放的 OTLP 端口会接受任何发现它的人的写入请求。写入 /opt/ccmetrics/compose.yaml

services:
  collector:
    image: otel/opentelemetry-collector-contrib:latest
    command: ["--config=/etc/otel/config.yaml"]
    volumes:
      - ./collector.yaml:/etc/otel/config.yaml:ro
    ports:
      - "10.8.0.1:4318:4318"
    restart: unless-stopped
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prom-data:/prometheus
    ports:
      - "127.0.0.1:9090:9090"
    restart: unless-stopped

volumes:
  prom-data:

10.8.0.1 是服务器在 WireGuard 隧道中的地址,因此采集器只能从您的设备访问,其他位置都无法访问。端口前的地址在这里很重要,因为 Docker 发布的端口不会受到 ufw 过滤:请参阅Docker 发布的端口为何会绕过 ufw。隧道本身的配置方法请参阅在自己的 VPS 上配置 WireGuard VPN

/opt/ccmetrics/collector.yaml

receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:

exporters:
  prometheus:
    endpoint: 0.0.0.0:8889

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [prometheus]

/opt/ccmetrics/prometheus.yml。端口 8889 从不发布到主机,因为 Prometheus 会通过 Compose 网络中的服务名访问采集器:

global:
  scrape_interval: 30s

scrape_configs:
  - job_name: claude-code
    static_configs:
      - targets: ["collector:8889"]
cd /opt/ccmetrics
docker compose up -d
docker compose logs collector

采集器日志应以 Everything is ready. Begin running and processing data. 结尾。如果日志因配置错误而停止,说明 YAML 解析失败,容器会反复重启。

现在让 Claude Code 连接到它。在每台运行 Claude Code 的设备上,将以下内容添加到 ~/.claude/settings.json

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "none",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://10.8.0.1:4318",
    "OTEL_METRIC_EXPORT_INTERVAL": "10000"
  }
}

启动一个会话,发送一条提示,等待导出间隔结束(此处为 10 秒,默认值为 60 秒),然后让 Prometheus 查询它已获取的指标:

curl -s http://localhost:9090/api/v1/label/__name__/values | grep -o 'claude_code[a-z_]*'

您应该会得到多个以 claude_code_ 开头的名称。导出器会将点号改写为下划线,并追加单位,因此具体字符串取决于您的采集器版本。结果为空表示没有数据到达。请确认协议和端口匹配,因为 http/protobuf 使用 4318,而 grpc 使用 4317;不匹配时会静默失败。运行 claude --debug,调试日志会报告 OTel 导出错误。

如果只有一台设备且不需要服务器,可以跳过以上步骤。设置 OTEL_METRICS_EXPORTER=prometheus 后,Claude Code 会直接在 http://localhost:9464/metrics 暴露抓取端点。当 prometheus 是唯一列出的导出器时,Claude Code 会从指标名称中省略 USDtokenss 单位,使抓取结果保持有效的 Prometheus 文本格式。

这种架构还涉及一项隐私选择。默认情况下,离开设备的只有计数,不包括提示文本和工具输出。OTEL_LOG_USER_PROMPTS=1OTEL_LOG_TOOL_CONTENT=1 会改变这一点;启用后,您的指标服务器中会保存源代码以及上下文中的其他内容。请谨慎启用这些选项,并先阅读避免将机密信息放入代理上下文

跟踪脚本运行和 CI 运行的支出

非交互式运行最容易造成意外支出,因为没有人实时查看屏幕。使用 claude -p--output-format json 后,运行结果负载中会报告本次运行的成本:

claude -p "summarise the failing tests" --output-format json | jq '.total_cost_usd'

该负载包含 total_cost_usd 以及按模型细分的费用,因此 CI 作业无需使用仪表板即可记录自身支出。可以将该值追加到文件,也可以将其作为指标推送到上面的收集器。这是目前成本最低且实用的支出跟踪方式,每次运行只需调用一次 jq

故障模式及其现象

报告为空。 npx ccusage@latest daily 没有打印任何行,说明它读取的不是 Claude Code 写入的位置。CLAUDE_CONFIG_DIR 会更改该位置,因此必须告知解析器新的位置。如果存在数据行,但只追溯到大约一个月前,这是 cleanupPeriodDays 的正常设计:默认会在 30 天后删除会话记录。

两台机器报告的总数不同。 这是预期行为,不是错误。/usage 和任何日志解析器都只读取本机的会话历史,因此来自其他设备或 claude.ai 的用量不会出现在两者中。

本地总数与账单不一致。 本地数据根据 token 数量和标准目录价格计算。它们不会考虑促销价格或合同折扣;对于订阅,token 根本不会单独计费。API 计费应以 Console usage 页面为准。

执行相同的工作,费用却上升了。 首先检查缓存列。长会话每轮都会重新发送完整历史记录。缓存有效时按缓存价格计费,缓存失效后按完整输入价格计费。因此,长时间中断一次就会重新处理整个对话。这通常表现为输入数量很大、输出数量很小;输入与输出 token 的价格解释了两者为何会独立变化。

某一天使用了子代理,看起来不可能。 每个子代理都运行在自己的上下文窗口中,因此 token 用量取决于运行的子代理数量及其各自的运行时长。只有 OTel 数据可以通过 query_source 属性在 claude_code.token.usage 上区分这些子代理。日志解析器只能显示总量,无法进一步区分。

FAQ

ccusage 是否会显示我在 Max 计划下实际支付的费用?

不会。订阅计划不是按 token 计费,因此日志解析器会按照 API 的标准目录价格为 token 估价,并显示相同工作通过 API 完成时的费用。这可以较好地反映某一天的使用量,也便于比较不同项目或模型的消耗。要查看实际应付金额,请使用 Console 的用量页面查看 API 计费,并使用计划计费页面查看订阅费用。

Claude Code 将这些工具读取的会话文件存储在哪里?

存储在 ~/.claude/projects/<project>/<session-id>.jsonl 中,其中 <project> 是工作目录路径,非字母数字字符会替换为 -。每一行都是一个 JSON 对象,对应一条消息、一次工具调用或一项元数据。CLAUDE_CONFIG_DIR 会移动整个目录,cleanupPeriodDayssettings.json 中控制 30 天的保留期限。Anthropic 将条目格式说明为内部格式,并且该格式可能随版本变化,因此应使用持续维护的工具进行解析,不要使用自己的脚本。

我可以将 Claude Code 遥测数据发送到 Langfuse 吗?

不能直接发送。Langfuse OTLP 端点接收 trace,而 Claude Code 导出的是 metrics 和日志事件,而不是 span,因此没有可写入这些数据的位置。请将 Claude Code metrics 发送到 OpenTelemetry collector,并存储到 Prometheus。对于通过 API 自行构建的 agent,可以使用 Langfuse;此时由您自己的代码生成包含 prompt、模型和费用信息的 span。

为什么本地数值与 Console 用量页面不一致?

因为两者的计算方式不同。/usage 和日志解析器会汇总当前机器上会话文件中的 token 数量,再按照 API 的标准目录价格进行估价。Console 会统计整个组织在所有机器和所有 key 上的实际费用,并计入折扣。出现差异是正常的。差异很大时,通常说明还有其他设备、CI runner 或其他团队成员在使用同一账户计费。

如何跟踪 CI 中一次 claude -p 运行的费用?

使用 --output-format json 运行,并从结果中读取 total_cost_usd,例如使用 claude -p "..." --output-format json | jq '.total_cost_usd'。同一负载还包含按模型划分的明细和会话 ID。按 job 记录该数值,即可获得按 pipeline 统计的费用,无需 agent、dashboard 或额外服务。