Billing theo token — bạn tự kiểm lại được từng con số
Đọc 7 phút
CLF AI Gateway chạy theo mô hình trả trước: bạn nạp credit, mỗi request trừ dần vào đó. Bài này là toàn bộ mô hình tính tiền — công thức, phần số học nguyên đằng sau, và cách bạn tự tính lại bất kỳ khoản trừ nào từ những con số chúng tôi vốn đã hiển thị cho bạn. Không có gì được giản lược để làm marketing; đây đúng là điều code settlement đang làm.
Ba mức giá theo token, số học nguyên
Mỗi model có tối đa ba mức giá theo token: input, cached input và output, niêm yết theo mỗi triệu token ở trang models — ví dụ kimi-k2.6 tính $0.57/M input, $0.096/M cached input, $2.40/M output. Hiện tại mọi model đều tính thuần theo token; không model nào có thêm phí cố định per-request.
Các mức trên đã gồm đợt trợ giá 40% chạy từ 11/08/2026: mọi model đều bán thấp hơn 40% so với giá niêm yết — chính là mức giá Cloudflare Workers AI công bố cho các model này — và trang models hiện cả hai con số, giá niêm yết gạch ngang. Không phải kích hoạt gì cả; mức giảm nằm sẵn trong từng request.
Bên trong hệ thống không có số thực dấu phẩy động nào cả. Giá lưu dạng số nguyên nano-USD trên mỗi token (1 nano-USD = 10⁻⁹ đô), nên $0.57 mỗi triệu token chính xác là 570 nano/token. Chi phí một request là tổng các phép nhân số nguyên, số dư của bạn cộng dồn đúng từng nano, và việc làm tròn về cent chỉ xảy ra đúng một lần — lúc xuất sao kê, theo kiểu half-even — không bao giờ làm tròn từng request.
Công thức
billable_input = prompt_tokens − cached_tokens
cost = billable_input × giá input
+ cached_tokens × giá cached input
+ completion_tokens × giá outputprompt_tokens,cached_tokens,completion_tokenslấy từ objectusagecủa response — đúng object bạn nhìn thấy.completion_tokenstính trọn theo giá output. Token reasoning nằm bên trong nó, không phải một dòng riêng (giải thích ở dưới).- Giá là mức đang bán ở trang models, chốt tại thời điểm request đến — đổi giá giữa chừng không bao giờ chạm vào request đã bắt đầu.
Một request thật, tính lại bằng tay
Đây là một request thật gọi kimi-k2.6: prompt dài trúng prefix cache, câu trả lời ngắn. Response báo:
"usage": {
"prompt_tokens": 12907,
"completion_tokens": 300,
"total_tokens": 13207,
"prompt_tokens_details": { "cached_tokens": 12864 }
}Áp công thức với giá kimi-k2.6 (570 / 96 / 2400 nano mỗi token):
billable_input = 12,907 − 12,864 = 43 token
43 × 570 = 24,510 nano
12,864 × 96 = 1,234,944 nano
300 × 2400 = 720,000 nano
─────────────
1,979,454 nano = $0.001979454Đúng con số đó nằm trên response ở header x-gw-cost-nano: 1979454, và cùng dòng đó nằm trong usage log trên dashboard. Nếu không trúng cache, request này tốn 12,907 × 570 + 300 × 2400 = 8,076,990 nano ($0.0081) — prefix cache đã cắt 75,5% chi phí của nó.
Token reasoning: hiển thị, không bao giờ tính hai lần
Kimi, GLM và DeepSeek V4 là model reasoning: một phần completion là chuỗi suy nghĩ, stream về dưới dạng reasoning_content trước phần trả lời nhìn thấy được. Những token đó đã nằm bên trong completion_tokens, và đó là nơi duy nhất chúng được tính tiền — theo giá output bình thường.
Chúng tôi vẫn đếm riêng và trả về usage.completion_tokens_details.reasoning_tokens, vì khi một câu trả lời hai dòng tốn nhiều hơn bạn nghĩ, bạn xứng đáng thấy lý do. Nhưng cố tình không có chiều giá "reasoning" nào cả: cộng thêm nó lên trên completion_tokens là tính cùng một token hai lần.
Bảo hiểm zero-completion
Request không sinh ra gì thì không tốn gì. Điều kiện chính xác:
Điều kiện này quan trọng. Request kết thúc bằng finish_reason: "stop" hay "length" với 0 completion — ví dụ bạn gửi max_tokens: 0 — là request model đã hoàn thành đúng yêu cầu, phần prompt tính tiền bình thường. Thiếu vế đó, "0 output thì miễn phí" thành lỗ hổng: cứ đặt max_tokens: 0 là được xử lý prompt miễn phí.
Cache ảnh hưởng hóa đơn thế nào
Prefix cache — tự động
Khi prompt của bạn trùng phần đầu với một request gần đó — cùng system prompt, cùng định nghĩa tool, cùng ví dụ few-shot — nền tảng inference tái dùng phần đã tính và báo lại qua cached_tokens. Phần đó tính theo giá cached input: trên kimi-k2.6 là 96 so với 570 nano/token, rẻ hơn khoảng 6 lần. Đó là lý do request 12.9 nghìn token ở trên chỉ tốn khoảng một phần năm cent. Muốn hưởng lợi: để phần ổn định lên đầu messages, phần thay đổi xuống cuối.
Một điểm nói thật: glm-4.7-flash không có giá cached input (bảng giá hiện — ở ô đó), nên token cached của nó tính theo giá input thường. Chúng tôi cũng không được giảm giá cached ở model đó, nên không bịa ra một mức giảm cho đẹp.
Exact cache — bật theo request
Với các lời gọi lặp lại và tất định (temperature: 0), bạn bật cache response theo từng request bằng "cache": {"mode": "on", "ttl_seconds": 3600}. Trúng trọn vẹn thì bỏ qua inference hoàn toàn và tính đúng 10% chi phí theo giá thường của request được phát lại. Response mang x-gw-cache: hit, nên lưu lượng cache nhìn thấy rõ trong log chứ không bị trộn lẫn.
Stream, ngắt kết nối, output dở dang
- Bạn ngắt giữa stream: phần sinh chữ ở thượng nguồn không dừng ngay khoảnh khắc bạn cúp máy, nên token đã sinh tới chunk cuối chúng tôi nhận được vẫn tính. Hãy đặt
max_tokens— đó là trần chi tiêu cứng cho mỗi request. - Thượng nguồn đứt giữa stream: bạn nhận chunk cuối mang
finish_reason: "error"rồi[DONE]. Chỉ trả tiền cho token thực sự đã tới tay bạn; request bị đánh dấupartialtrong log. - Đứt trước byte đầu tiên: bảo hiểm zero-completion áp dụng — $0.
Với stream, truyền stream_options: {"include_usage": true} rồi đọc usage ở chunk cuối — hoặc gọi GET /v1/generation?id=<x-request-id> sau đó. Hai đường cùng một con số.
Trả trước: hold, settle, và một lỗi 402 parse được
Trước khi request đi lên thượng nguồn, chúng tôi tạm giữ một khoản trên số dư — ước lượng từ độ dài prompt và max_tokens, có chặn trần để model context 262K không giam cả đống tiền cho một request nửa cent. Khi request chốt sổ, chi phí thật thay chỗ khoản tạm giữ. Nếu số dư khả dụng không đủ cho ước lượng, bạn nhận 402 với các con số máy đọc được:
{
"error": {
"message": "Insufficient credits. Available: $0.0041. This request requires an estimated hold of $0.0269. Top up at https://app.clfaigateway.dev/billing/topup",
"type": "insufficient_credits",
"code": "insufficient_credits",
"metadata": {
"available_nano": 4100000,
"required_estimate_nano": 26927600,
"topup_url": "https://app.clfaigateway.dev/billing/topup"
}
}
}Hai hành vi đáng biết: stream đang chạy không bao giờ bị cắt vì số dư chạm 0 giữa chừng — request đó vẫn chốt sổ dù có kéo số dư âm nhẹ. Và request mới bị từ chối cho tới khi bạn nạp thêm. Trả trước nghĩa là trường hợp xấu nhất có trần và nhìn thấy được, chứ không phải câu trả lời chết giữa câu.
Tự kiểm chứng
- Từng request: object
usage, cùng các headerx-gw-cost-nano,x-request-id,x-gw-cache. - Cả tài khoản: usage log trên dashboard — token, trạng thái cache, chi phí từng request, xuất được CSV, khớp header từng nano.
- Từng model: giá đang bán ở /models, kèm cả ID model thượng nguồn (
@cf/...) — bạn biết chính xác model nào đang phục vụ mình.
Toàn bộ mô hình là vậy. Nếu bạn tính lại một khoản trừ mà ra số khác, đó là bug — báo chúng tôi và chúng tôi sửa con số, không sửa câu chuyện.
Câu hỏi thường gặp
Request lỗi có bị tính tiền không?
Không — request có 0 completion token và finish_reason là null hoặc error chốt sổ ở $0. Nếu stream đứt sau khi đã phát token, bạn chỉ trả cho phần đã nhận và request được đánh dấu partial.
Hết tiền giữa stream thì sao?
Stream chạy hết và chốt sổ bình thường; số dư có thể âm nhẹ đúng ở request đó. Request mới trả về 402 cho tới khi bạn nạp thêm.
Xem cached_tokens và reasoning_tokens ở đâu?
Trong mọi response: usage.prompt_tokens_details.cached_tokens và usage.completion_tokens_details.reasoning_tokens — đúng các con số công thức billing dùng, và cũng thấy theo từng request trên dashboard.