Tính đúng tiền một session Claude Code
Việc cần làm là đọc file transcript mà Claude Code lưu trên máy, rồi tính ra số token và số tiền của từng session. Có hai tool nói là làm được việc này. Tháng 11/2026 mình chạy cả hai trên bản copy transcript của chính mình và tự tính tay một session. Không tool nào ra con số tiền dùng được, và lý do nằm ở format của file, nên script bạn tự viết cũng sẽ dính y như vậy.
Các tool, theo thứ tự mình thử
- cc-cost (lob-labs/cc-cost, bản 1.1.0, test ngày 6/11/2026). Một script Python 330 dòng, không cần dependency nào. Nó chỉ đọc chứ không ghi gì.
- claudia, giờ đổi tên là opcode (getAsterisk/claudia, test ngày 6/11/2026). Đây là một app desktop viết bằng Tauri. Mình không build nó, mà viết lại phần code đọc token của nó sang Python, từng dòng một, rồi chạy trên bản copy của bốn transcript.
- Bảng giá của chính mình, để tính lại đúng mấy session đó.
# one session, with its written advice
python3 -I repo/cc_cost.py SESSION_FILE.jsonl --diagnose
# a whole project folder; the = matters, see below
python3 -I repo/cc_cost.py --json --project=-PROJECT_FOLDER_NAME
Cái bẫy: một message mà nhiều dòng
Claude Code ghi mỗi content block thành một dòng trong transcript (thinking, text, mỗi lần gọi tool), và dòng nào cũng mang cùng message id, cùng số usage. Cộng hết mọi dòng thì bạn đếm cùng một lượng token nhiều lần. Trên cả folder mình test, con số bị đếm lên khoảng 3,4 lần.
Lấy một session Sonnet cho dễ thấy: 83 dòng usage, nhưng chỉ có 36 message thật.
- cc-cost in ra 96.988 token output, 8.327.772 token cache read và $30,45.
- Bỏ các dòng lặp đi thì session đó chỉ có 39.431 token output và 3.580.941 token cache read.
- Tính theo giá Sonnet 5 hiện tại thì là $1,63. cc-cost báo cao gấp 18,6 lần. Hai session khác bị báo cao gấp 14 và 20 lần.
Mỗi tool đúng chỗ nào, sai chỗ nào
cc-cost cộng mọi dòng nên dính lỗi đếm lặp. Bảng giá của nó có bốn dòng, Opus 4.6 và 4.7, Sonnet 4.6 và Haiku 4.5, model nào nó không nhận ra thì tính theo giá Opus cũ ($15 input, $75 output cho mỗi triệu token). Mọi model 5.x mình dùng đều rơi vào mức giá đó. Test của nó dùng transcript giả rất gọn, mỗi message một dòng, nên format file thật chưa từng được test.
claudia xử lý được chuyện lặp. Nó bỏ qua một dòng khi đã gặp cặp message id : requestId đó rồi, tính trên mọi file. Với session Sonnet ở trên, nó báo 36 message và 39.431 token output, khớp với số mình đếm. Nhưng nó tính cả bốn file là $0,00, vì bảng giá chỉ biết tên model có chữ opus-4 hoặc sonnet-4, còn lại cố tình tính bằng 0. Số token thì đúng. Còn số tiền thì cần một bảng giá có người cập nhật thường xuyên.
Cả hai đều bỏ qua field entrypoint, là field cho biết transcript đến từ một người ngồi trong editor hay từ một lần chạy headless claude -p. Một folder project đầy run tự động sẽ hiện ra thành cả đống session tí hon, lẫn vào giữa các session thật.
Còn chỗ nào hỏng
- Ví dụ trong README của cc-cost là
--project -home-foo, chạy là dừng với lỗi "expected one argument", vì tên folder của Claude Code bắt đầu bằng dấu gạch và bộ đọc argument của Python tưởng đó là một flag. Phải viết--project=-home-foomới chạy. - Lời khuyên
--diagnosecủa nó báo "Bash dominates" cho cả hai session lớn. Với cache hit 98%, mỗi lần gọi đó chỉ tính bằng một phần mười giá input, nên lời khuyên này nhắm sai chỗ tốn tiền. Còn lời khuyên về cache (đánh dấu context bằngcache_control) là dành cho người gọi API, trong Claude Code bạn không set được. - Danh sách "top expensive turns" in ra 80 ký tự đầu của mỗi message từ assistant. Bạn dán cái đó vào bug report là có thể dán luôn nội dung session của mình.
Con số nào tin được
Cache hit rate, tính bằng read / (read + write + fresh input). Lần chạy nào nó cũng đứng vững: 98,3% với một session dài, 53,1% với một lần chạy Haiku hai lượt. Dòng lặp gần như không làm lệch một tỉ lệ.
Nếu bạn tự viết bộ đếm: bỏ các cặp message id : requestId bị lặp, giữ bảng giá luôn mới, và tách run headless khỏi session thật bằng entrypoint. Test nó trên transcript thật chứ đừng dùng transcript giả gọn gàng. Trang usage của chính mình cũng đọc đúng mấy dòng này, và đọc code thì thấy có thể nó cũng dính lỗi lặp. Mình chưa đối chiếu nó với số thật.
English