
Đo chi phí mỗi lượt khi chạy coding agent headless
Một ticket ngốn 402 USD sau chín lượt agent mà không ai biết. Vì sao total_cost_usd đánh lừa bạn, và cách ghi đúng chi phí của từng lượt chạy.
Bạn cho coding agent chạy headless trong CI suốt hai tuần, rồi hóa đơn API về cao gấp mấy lần dự tính. Mở log ra thì lượt nào cũng có con số tiền đàng hoàng, nhưng cộng lại không khớp với bất cứ thứ gì. Bài này chỉ ra chỗ con số đó đánh lừa bạn, cách ghi chi phí từng lượt cho đúng, và ba hành vi đốt tiền vừa được đo trên 1.200 phiên chạy thật.
Con số trong log là chỉ số công-tơ, không phải hóa đơn
Panth Patel, người dẫn nhóm phần mềm tại Oizom, mô tả một ticket trên bảng của anh chạm mốc 402 USD sau chín lượt agent mà không có chỗ nào trong ứng dụng báo điều đó. Hệ thống của anh — ticket-tracker, một orchestrator khoảng 600 dòng, không phụ thuộc thư viện ngoài — biến mỗi ticket thành một phiên headless Claude Code, và mỗi lần agent có việc để làm thì gọi claude -p một lần. Đó là một lượt.
Cái bẫy nằm ở trường total_cost_usd trên dòng kết quả. Theo bài viết, giá trị này cộng dồn qua --resume: nó là tổng đang chạy của cả phiên, không phải chi phí của lần chạy vừa xong. Ticket OCZ-5 cho thấy rõ điều đó: lượt 8 chỉ thực hiện một lời gọi API và sinh ra 0 token output, nhưng vẫn báo 392,83 USD — đúng bằng con số lượt 7 đã báo.
Đọc ngây thơ, dòng log đó nói lượt 8 tốn 392,83 USD. Cộng các dòng lại thì mọi lượt trước bị đếm lại ở mỗi lượt sau — cộng dồn kiểu đó, báo cáo chi phí phình lên mà không ai truy được vì sao.
Sửa bằng một phép trừ, không phải một dashboard
Cách xử lý trong bài rất gọn: lưu lại số đọc cuối cùng của phiên, rồi báo phần chênh lệch. Orchestrator giữ trạng thái theo từng ticket trong một file JSON với hai trường — session_usd (tổng gần nhất phiên đó báo) và session_usage (các số đếm token gần nhất). Khi một lượt kết thúc:
const prevUsd = e.session_usd ?? 0;
const costUsd = Math.max(0, r.total_cost_usd - prevUsd);
e.session_usd = r.total_cost_usd;
Chi phí của lượt là tổng mới trừ tổng cũ, chặn dưới ở 0. Các số đếm token (input, output, cache_read, cache_write) được xử lý y hệt. Ba tình huống quyết định chuyện con số có trung thực hay không:
| Tình huống | Orchestrator làm gì |
|---|---|
| Phiên mới (lượt đầu, hoặc file phiên đã mất) | Tạo session id mới và reset session_usd về 0 trước khi chạy |
| Phiên được resume | Trừ đi tổng gần nhất đã báo |
| Lượt chết không có dòng kết quả | Không phát biên lai; phần chi tiêu đó hiện ra trong chênh lệch của lượt kế tiếp, vẫn đúng ticket |
Chi tiết dễ bỏ sót nhất là điều kiện resume. Orchestrator chỉ resume khi file .jsonl của phiên còn tồn tại dưới ~/.claude/projects/. Nếu file không còn, lượt đó khởi tạo phiên mới và phiên mới đếm từ 0 — lúc này mà vẫn trừ tổng cũ thì bạn xóa sạch chi phí thật của lượt. Đây là chỗ một script tự viết rất dễ sai.
Con số được gắn thẳng vào ticket: mỗi lượt kết thúc, orchestrator đăng một biên lai dạng "Turn 3 · review · $1.24 · 12 min", kèm cost_usd của lượt và session_usd như Claude Code báo. Giữ cả hai là cố ý — chi phí lượt để người đọc dùng, tổng phiên để đối chiếu số học. Mỗi biên lai mang một Idempotency-Key ghép từ ticket và số lần chạy, nên request bị retry không đếm lượt hai lần.
Ba hành vi đốt tiền đã được đo, không phải đoán
Đo đúng rồi thì câu hỏi kế tiếp là tiền đi đâu. Một nghiên cứu nộp lên arXiv ngày 25/09/2026 (arXiv:2609.30725, nhóm Yiran Hu và cộng sự) phân tích 1.200 trajectory từ Claude Code và Mini-SWE-Agent trên bốn cấu hình, chạy trên SWE-bench Verified. Nhóm tác giả gọi đây là nghiên cứu đầu tiên về kém hiệu quả chi phí ở mức hành vi của coding agent, và chỉ ra ba hành vi:
- subsumed retrieval — truy hồi lại thứ đã nằm trong ngữ cảnh
- similar script generation — sinh đi sinh lại các script gần như giống nhau
- test re-execution — chạy lại test không cần thiết
Theo bài báo, ba hành vi này xuất hiện ở 79,00%–98,00% số task và chiếm tới 22,75% chi phí task: gần một phần tư hóa đơn nằm ở phần lặp thừa, không nằm ở phần model "suy nghĩ khó". Nhóm tác giả đánh giá tiếp ba chiến lược giảm thiểu trên hơn 10.000 trajectory ở tập held-out SWE-bench Verified và Pro:
- Structure-aware retrieval gây thêm chi phí truy hồi và làm đổi cách agent ủy thác, dẫn tới cải thiện không nhất quán và chi phí tăng tới 28,14%.
- Skill do agent tự tổng hợp có xu hướng sinh hướng dẫn cấp thấp, bám vào một trace cụ thể, nên hiệu quả và tính tổng quát đều hạn chế.
- Skill do người phát triển thiết kế đưa ra hướng dẫn cấp cao, không phụ thuộc trace, và giảm chi phí tới 41,73% — theo bài báo là khoảng gấp đôi mức lợi ích tối đa của skill do agent tự sinh.
Đọc theo hướng thực hành: thời gian bạn bỏ ra viết một file skill mô tả quy ước của repo có khả năng trả lại nhiều hơn thời gian bỏ ra tinh chỉnh tầng retrieval.
"Tiết kiệm token" phụ thuộc vào việc bạn đếm cái gì
Một bài đo lường khác trong tuần cho thấy con số tiết kiệm dễ bị đọc sai thế nào. Tác giả nói rõ mình có liên kết với Belcore, một lớp memory/context cho ứng dụng LLM, nên số dưới đây là tuyên bố của nhà cung cấp, không phải kiểm chứng độc lập. Với bộ LongMemEval_S (500 câu hỏi, mỗi câu kèm khoảng 109k token hội thoại trước đó), model trả lời gpt-5, tokenizer o200k_base, cùng một loạt chạy được đếm theo ba cách:
| Đếm cái gì | Token mỗi lời gọi |
|---|---|
| Toàn bộ transcript, không cắt | 109.079 |
| Ngữ cảnh memory đã lắp ráp | 6.671 |
| Input bị tính tiền (tập con 27 câu) | 9.908 |
Tác giả quy ra -93,9% token ngữ cảnh và khoảng -91% input bị tính tiền trên tập con — đồng thời tự lưu ý rằng tập con đó được chọn tay nên chỉ mang tính tham khảo, và bài viết không đưa ra bất kỳ số nào về chất lượng câu trả lời.
Phần trung thực nhất là kết quả không trụ được: một bước retrieval nhiều lượt nâng số câu đúng từ 16 lên 20 trên 27 câu chọn tay, nhưng trên mẫu ngẫu nhiên 103 câu thì hiệu ứng quy được chỉ là +2, nằm trong biên nhiễu ±5,2, trong khi tốn khoảng 2,9 lần token input và 2,6 lần độ trễ. Nhóm đó quyết định không ship. Đây chính là hình mẫu bạn nên áp cho mọi con số tiết kiệm mà vendor đưa: hỏi mẫu được chọn thế nào, và hỏi biên nhiễu là bao nhiêu.
Checklist đo chi phí agent cho đội của bạn
- Coi mọi trường tổng chi phí của SDK là chỉ số công-tơ. Lưu số đọc gần nhất theo session id, báo cáo phần chênh lệch, chặn dưới ở 0.
- Reset mốc trừ về 0 khi phiên bị tạo mới — kiểm tra sự tồn tại của file phiên trước khi quyết định resume.
- Gắn khóa idempotency ghép từ định danh công việc và số lần chạy, để retry không nhân đôi con số.
- Ghi chi phí ở nơi người ra quyết định đang nhìn (ticket, PR), không phải trong file log không ai mở.
- Trước khi đầu tư vào tầng retrieval, thử viết skill cấp cao mô tả quy ước repo — chiến lược duy nhất trong ba chiến lược được đo cho thấy mức giảm chi phí đáng kể.
- Với mọi con số tiết kiệm token từ bên thứ ba, hỏi ba câu: đếm ngữ cảnh hay đếm input bị tính tiền, mẫu có chọn tay không, biên nhiễu bao nhiêu.
Con số cần theo dõi tiếp là chi phí trên mỗi task thành công, đã tính cả retry và sửa lỗi. Không nguồn nào trong bài này đo được nó — tác giả bài đo lường nói thẳng là chưa đo. Nếu đội bạn đã ghi chi phí ở mức lượt, đó là con số kế tiếp đáng dựng, vì nó là thứ duy nhất so sánh được giữa hai model hay hai cấu hình agent.
Không spam, hủy đăng ký bất kỳ lúc nào.


