cost-tracking
affaan-m/ECC
Анализируйте использование токенов Claude Code, расходы и бюджеты на основе данных из локального журнала показателей системы отслеживания затрат ECC. Предоставляются сводные отчеты, разбивки по модели, сеансу или дате, а также возможность экспорта в формат CSV.
...Расширить всеОтслеживание затрат
Используйте этот навык для анализа истории затрат и использования Claude Code на основе журнала метрик,
который записывает хук stop:cost-tracker ECC.
Где хранятся данные
Трекер добавляет по одному объекту JSON за каждое завершение сеанса в файл
~/.claude/metrics/costs.jsonl. Каждая строка представляет собой совокупный снимок данных для данного
сеанса, поэтому для подсчёта общей суммы расходов необходимо взять последнюю строку для каждого session_id и
провести суммирование по всем сеансам — при суммировании каждая строка учитывается несколько раз.
Схема строки:
| Поле | Значение |
|---|---|
timestamp |
Временная метка в формате ISO для моментального снимка |
session_id |
Идентификатор сеанса Claude Code |
transcript_path |
Путь к стенограмме сеанса |
model |
Используемая модель |
input_tokens / output_tokens |
Количество токенов |
cache_write_tokens / cache_read_tokens |
Количество токенов в кэше подсказок |
estimated_cost_usd |
Заранее рассчитанная совокупная стоимость сессии в долларах США |
Предпочтительно использовать estimated_cost_usd вместо ручного расчета цен — цены на модель и кэш
меняются, а трекер является достоверным источником информации.
Когда использовать
- Пользователь спрашивает: «Сколько я потратил?», «Во сколько обошлась эта сессия?» или «Каково моё использование токенов?»
- Пользователь упоминает бюджеты, лимиты расходов, превышения лимитов или меры контроля затрат.
- Пользователь хочет получить разбивку затрат по модели, сеансу или дате либо экспортировать данные в формат 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
.
Пример — сводка по модели за последние 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 || "(unknown)";
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 просмотрите тот же набор последних данных (или исходные
строки для CSV) и выведите нужные поля.
Рекомендации по составлению отчётов
При представлении данных о затратах включайте сегодняшние расходы по сравнению с вчерашними, итоговые показатели по всем сессиям, разбивку по моделям и количество сессий. Оформляйте суммы менее одного доллара с четырьмя знаками после запятой, более крупные суммы — с двумя.
Антипаттерны
- Не суммируйте каждую строку — они являются кумулятивными по сеансу; сначала сведите данные к последней
строке по
каждому session_id. - Не оценивайте затраты на основе исходного количества токенов, если присутствует поле
estimated_cost_usd. - Не следует предполагать наличие журнала без проверки.
- Не прописывайте цены на текущие модели в ответах, предназначенных для пользователей.
- Не рекомендуйте устанавливать непроверенные хуки или плагины, которые выполняют произвольный код.
Связанные
/cost-report— отчет в виде команды, основанный на том же журнале метрик.cost-aware-llm-pipeline— шаблоны маршрутизации моделей и проектирования бюджета.token-budget-advisor— планирование контекста и бюджета токенов.strategic-compact— уплотнение контекста для сокращения повторяющихся затрат токенов.
---
name: cost-tracking
description: Analyze Claude Code token usage, spending, and budgets from the local ECC cost-tracker metrics log. Provides summaries, breakdowns by model, session, or date, and CSV export.
---
# Cost Tracking
Use this skill to analyze Claude Code cost and usage history from the metrics log
that ECC's `stop:cost-tracker` hook writes.
## Where the data lives
The tracker appends one JSON object per session-stop to
`~/.claude/metrics/costs.jsonl`. Each row is a **cumulative snapshot for that
session**, so to total spend you take the **latest row per `session_id`** and
sum across sessions — summing every row multiply-counts.
Row schema:
| Field | Meaning |
| --- | --- |
| `timestamp` | ISO timestamp of the snapshot |
| `session_id` | Claude Code session identifier |
| `transcript_path` | Path to the session transcript |
| `model` | Model used |
| `input_tokens` / `output_tokens` | Token counts |
| `cache_write_tokens` / `cache_read_tokens` | Prompt-cache token counts |
| `estimated_cost_usd` | Precomputed cumulative cost in USD for the session |
Prefer `estimated_cost_usd` over hand-calculating pricing — model and cache
prices change, and the tracker is the source of truth.
## When to Use
- The user asks "how much have I spent?", "what did this session cost?", or
"what is my token usage?"
- The user mentions budgets, spending limits, overruns, or cost controls.
- The user wants a cost breakdown by model, session, or date, or a CSV export.
## How It Works
First verify the log exists (use `node`, not `sqlite3` — the tracker writes
JSONL, and `node` is cross-platform):
```bash
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)'
```
If the log is missing, do not fabricate usage data. Tell the user that cost
tracking populates after the first session ends with the `stop:cost-tracker`
hook enabled.
## Example — summary, by model, last 7 days
```bash
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));
'
```
For a session drilldown or CSV export, iterate the same `latest` set (or the raw
rows for CSV) and print the fields you need.
## Reporting Guidance
When presenting cost data, include today's spend vs yesterday, total across all
sessions, a by-model breakdown, and session count. Format sub-dollar amounts
with four decimals, larger amounts with two.
## Anti-Patterns
- Do not sum every row — they are cumulative per session; reduce to the latest
row per `session_id` first.
- Do not estimate costs from raw token counts when `estimated_cost_usd` is present.
- Do not assume the log exists without checking.
- Do not hard-code current model pricing in user-facing answers.
- Do not recommend installing unreviewed hooks or plugins that execute arbitrary code.
## Related
- `/cost-report` - Command-form report over the same metrics log.
- `cost-aware-llm-pipeline` - Model-routing and budget-design patterns.
- `token-budget-advisor` - Context and token-budget planning.
- `strategic-compact` - Context compaction to reduce repeated token spend.
Все файлы
1 файловУстановить cost-tracking
Скачайте файлы навыков и распакуйте их в каталог .claude/skills/.
Скачать ZIPКлонируйте репозиторий и скопируйте файлы навыка в свой проект.
git clone https://github.com/affaan-m/ECC/tree/main/skills/cost-tracking # Copy SKILL.md to your .claude/skills/ directory
Копировать





Дом
