成本追蹤 是做什麼的?
使用此技能分析 Claude Code 的成本與用量歷史記錄,資料來自 ECC 的 stop:cost-tracker Hook 所寫入的指標記錄檔。
資料存放位置
追蹤器會在每次工作階段結束時附加一筆 JSON 物件至 ~/.claude/metrics/costs.jsonl。每行代表該工作階段的累積快照,因此若要計算總花費,需取每個 session_id 的最新一行並加總各工作階段的值——若直接加總所有行會造成重複計算。
行結構:
| 欄位 | 說明 |
|---|---|
timestamp | 快照的 ISO 時間戳記 |
session_id | Claude Code 工作階段識別碼 |
transcript_path | 工作階段記錄檔的路徑 |
model | 所使用的模型 |
input_tokens / output_tokens | Token 計數 |
cache_write_tokens / cache_read_tokens | Prompt 快取 Token 計數 |
estimated_cost_usd | 該工作階段預先計算的累積成本(美元) |
建議優先使用 estimated_cost_usd 而非自行手動計算定價——模型與快取價格會變動,追蹤器才是唯一來源。
使用時機
- 使用者詢問「我花了多少錢?」「這個工作階段花費多少?」或「我的 Token 用量如何?」
- 使用者提到預算、花費上限、超支或成本控制。
- 使用者想要按模型、工作階段或日期查看成本明細,或匯出 CSV。
運作方式
首先確認記錄檔是否存在(使用 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)?"找到成本記錄":"找不到成本記錄: "+f)'
若記錄檔不存在,請勿虛構用量資料。請告知使用者,啟動 stop:cost-tracker Hook 後,成本追蹤功能會在首個工作階段結束時開始記錄資料。
範例——摘要、按模型分類、最近 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("找不到成本記錄: "+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("今日: "+f4(sum(latest.filter(r=>day(r)===today)))+" | 昨日: "+f4(sum(latest.filter(r=>day(r)===yest)))+" | 總計: "+f4(sum(latest))+" ("+latest.length+" 個工作階段)");
const m=new Map();for(const r of latest){const k=r.model||"(未知)";m.set(k,(m.get(k)||0)+cost(r));}
console.log("按模型分類:");[...m.entries()].sort((a,b)=>b[1]-a[1]).forEach(([k,v])=>console.log(" "+f4(v)+" "+k));
'
若要深入查詢某個工作階段或匯出 CSV,可迭代上述的 latest 集合(若是 CSV 則使用原始行),輸出所需欄位即可。
報告指引
呈現成本資料時,應包含今日花費與昨日花費的比較、所有工作階段的總計、按模型分類的明細,以及工作階段數量。低於 1 美元的金額顯示四位小數,較大金額則顯示兩位小數。
反模式
- 不要對每一行加總——每行是工作階段內的累積值;應先針對每個
session_id取最新一筆。 - 當
estimated_cost_usd存在時,不要從原始 Token 計數自行估算成本。 - 不要假設記錄檔一定存在而不先檢查。
- 不要在回覆中使用者消息中硬編碼當前模型定價。
- 不要推薦安裝未經審查的 Hook 或外掛,以免執行任意程式碼。
相關
/cost-report- 基於相同指標記錄檔的命令列報告。cost-aware-llm-pipeline- 模型路由與預算設計模式。token-budget-advisor- 情境與 Token 預算規劃。strategic-compact- 減少重複 Token 花費的情境壓縮。