SuperAPI AI 工具集

cost-tracking

部署与运维

查看项目

更新于 10-15 10:36

技能介绍

Cost Tracking 是一个用于分析 Claude Code 成本与用量历史的技能,数据来源是 ECC 的 stop:cost-tracker 钩子写入的指标日志。

用途 当用户询问“我花了多少钱”“这个会话花了多少”“我的 token 用量是多少”,或提到预算、支出上限、超支、成本控制,或需要按模型、会话、日期拆分成本、导出 CSV 时使用本技能。

数据位置 跟踪器在每次会话停止时向 ~/.claude/metrics/costs.jsonl 追加一个 JSON 对象。每一行是该会话的累计快照,因此要计算总花费,需先取每个 session_id 的最新一行,再跨会话求和——直接累加所有行会重复计数。

ECC 还在 ~/.claude/metrics/cost-snapshots/ 下维护内部按会话文件,供运行时钩子读取当前会话总额而无需重扫全部历史。这些文件应视为可重建的缓存;每个快照存储一个字节游标,只扫描新追加的行。稳定读取为 O(1),更新为 O(新增字节)。过期条目在 30 天后或目录超过 512 个会话时被清理。冷启动追赶工作量限制为每次钩子调用 16 MiB,大于 1 MiB 的畸形未终止行会被丢弃并保留可恢复游标。报告与导出应继续使用 costs.jsonl。

行字段

  • timestamp:快照的 ISO 时间戳
  • session_id:Claude Code 会话标识
  • transcript_path:会话记录路径
  • model:使用的模型
  • input_tokens / output_tokens:token 计数
  • cache_write_tokens / cache_read_tokens:提示缓存 token 计数
  • estimated_cost_usd:该会话预计算的累计成本(美元)

优先使用 estimated_cost_usd,而非手工计算价格——模型与缓存价格会变化,跟踪器是权威来源。

使用方式 首先确认日志存在(使用 node,而非 sqlite3——跟踪器写的是 JSONL,且 node 跨平台):

node -e 'const fs=require("fs"),os=require("os"),p=require("path");const f=p.join(os.homedir(),".claude","metrics","costs.jsonl");console.log(fs.existsSync(f)?"cost log found":"cost log not found: "+f)'

如果日志缺失,不要编造用量数据。告知用户成本跟踪会在启用 stop:cost-tracker 钩子后的首个会话结束时开始填充。

示例——最近 7 天按模型汇总:

node -e ' const fs=require("fs"),os=require("os"),path=require("path"); const f=path.join(os.homedir(),".claude","metrics","costs.jsonl"); if(!fs.existsSync(f)){console.log("cost log not found: "+f);process.exit(0);} const rows=fs.readFileSync(f,"utf8").split(/\r?\n/).filter(Boolean).map(l=>{try{return JSON.parse(l)}catch{return null}}).filter(Boolean); const bySession=new Map(); for(const r of rows){const k=r.session_id||r.transcript_path||r.timestamp;const p=bySession.get(k);if(!p||String(r.timestamp)>String(p.timestamp))bySession.set(k,r);} const latest=[...bySession.values()]; const cost=r=>Number(r.estimated_cost_usd)||0, day=r=>String(r.timestamp||"").slice(0,10), sum=a=>a.reduce((s,r)=>s+cost(r),0), f4=n=>"$"+n.toFixed(4); const today=new Date().toISOString().slice(0,10), yest=new Date(Date.now()-864e5).toISOString().slice(0,10); console.log("today: "+f4(sum(latest.filter(r=>day(r)===today)))+" | yesterday: "+f4(sum(latest.filter(r=>day(r)===yest)))+" | total: "+f4(sum(latest))+" ("+latest.length+" sessions)"); const m=new Map();for(const r of latest){const k=r.model||"(unknown)";m.set(k,(m.get(k)||0)+cost(r));} console.log("by model:");[...m.entries()].sort((a,b)=>b[1]-a[1]).forEach(([k,v])=>console.log(" "+f4(v)+" "+k)); '

如需会话下钻或 CSV 导出,遍历同一最新集合(CSV 可用原始行)并打印所需字段。

报告建议 呈现成本数据时,应包含今日花费对比昨日、所有会话总计、按模型拆分以及会话数量。小于 1 美元的金额保留四位小数,较大金额保留两位。

反模式

  • 不要累加每一行——它们是按会话累计的;先按 session_id 归约到最新一行。
  • 当存在 estimated_cost_usd 时,不要从原始 token 数估算成本。
  • 不要未检查就假定日志存在。
  • 不要在面向用户的回答中硬编码当前模型价格。
  • 不要推荐安装执行任意代码的未经审查的钩子或插件。

相关

  • /cost-report:基于同一指标日志的命令形式报告。
  • cost-aware-llm-pipeline:模型路由与预算设计模式。
  • token-budget-advisor:上下文与 token 预算规划。
  • strategic-compact:通过上下文压缩减少重复 token 花费。