Đếm token ChatGPT / Claude / Gemini | Ước tính chi phí API trước khi dính bill
Token ≠ chữ cái. Bill API = mọi thứ bạn gửi (system + history + RAG + tools + user) cộng mọi thứ model trả. Freelancer VN hay dính hóa đơn bất ngờ vì đếm ký tự, quên system prompt, hoặc nhân “500 token/row” rồi chạy 10k dòng. Đo trước bằng Token Counter (ước lượng nhanh) hoặc tokenizer chính thức — rồi mới nhân số lượng.
Freelance ship chatbot / pipeline tóm tắt cho khách: demo vài request ổn, tuần sau dashboard OpenAI/Anthropic báo số token gấp nhiều lần spreadsheet. Nguyên nhân gần như luôn giống nhau — không đếm đúng những gì được gửi mỗi lần gọi, và tokenizer không bằng string.length.
Bài này tập trung góc ước tính chi phí API cho ChatGPT (GPT-5.6…), Claude và Gemini: input vs output, tiếng Việt, RAG, và checklist trước batch — không phải định nghĩa “token là gì” chung chung.
Bài viết này giúp bạn
- Phân biệt ký tự / từ / token (và vì sao tiếng Việt dễ ước sai)
- Biết thành phần nào tính vào input mỗi request
- Ước chi phí batch bằng p95 + retry, không bằng trung bình lạc quan
- Giảm bill thật: rút system, cắt history, giới hạn output, prompt caching (khi có)
- Dùng tool local để sanity-check trước khi đốt credit
Token không phải chữ cái
LLM không “đọc từng chữ cái” như con người. Tokenizer (BPE / SentencePiece…) cắt văn bản thành token — đơn vị billing và context.
| Nội dung | Ước thô (chỉ để định hướng) | Thực tế |
|---|---|---|
| Tiếng Anh prose | ~0.75 từ / token | Khá ổn với văn xuôi |
| Code / JSON | Nhiều token hơn cùng số ký tự | Dấu { } " : tốn token |
| Tiếng Việt có dấu | Thường cao hơn EN cùng độ dài | Đừng dùng “ký tự ÷ 4” |
| Prompt template + markup | Thêm token “ẩn” | Chat template, XML tags… |
Công thức dân gian chars ÷ 4 là trung bình cũ cho tiếng Anh trên một số model — sai khi có tiếng Việt, JSON, stack trace, hoặc HTML.
"Xin chào" ≠ 1 token mỗi chữ cái
{"status":"ok"} ≠ "ngắn nên rẻ"
system 1200 token × 10_000 request = 12M token input — trước cả user message
Cùng một đoạn tiếng Việt, GPT-5.6 / Claude / Gemini có thể lệch vài % vì tokenizer khác. Khi migrate model, đo lại — đừng copy max_tokens cũ.
Cái gì tính vào bill?
Input (prompt side)
| Thành phần | Tính input? | Ghi chú |
|---|---|---|
| System / developer message | Có | Mỗi request — dễ quên vì nằm trong code |
| Lịch sử chat | Có | Trừ khi server truncate |
| User message | Có | Payload từng row |
| Tool / function schema | Có | JSON schema dài = đắt |
| Chunk RAG | Có | Mỗi lần retrieve lại trả tiền |
| Ảnh (vision) | Có | Theo tile / độ phân giải — screenshot Full HD có thể hàng nghìn token |
Output (completion)
Chỉ token model sinh ra. Streaming vẫn tính token đã generate; abort sớm tiết kiệm output nhưng input đã gửi không hoàn tiền.
Context window 128k là sức chứa, không phải “gửi free”. 100k token input × giá $/1M vẫn là 100k token tính tiền.
Case study: freelancer VN và bill bất ngờ
Bối cảnh: Outsource chatbot FAQ cho shop. System prompt ~800 token (tiếng Việt + quy tắc trả lời). Mỗi câu hỏi khách kèm 5 chunk RAG (~600 token/chunk). User message ~80 token. Output trung bình ~250 token.
Ước spreadsheet ban đầu: “prompt ~100 token × 50.000 câu/tháng” → số quá thấp.
Thực tế mỗi turn:
input ≈ 800 (system) + 5×600 (RAG) + 80 (user) = 3880
output ≈ 250
→ ~4130 token / câu hỏi thành công
× 50_000 ≈ 206M token
× (1 + 15% retry / rate-limit) ≈ 237M token
Spreadsheet sai vì quên system + RAG. Đây là pattern phổ biến khi team Việt Nam gắn embedding search vào chat “cho chắc”.
Cách xử lý:
- Giảm top-k RAG (5 → 2–3) hoặc chunk ngắn hơn; đo lại token trước khi ship.
- Rút system: bỏ đoạn trùng trong user message.
- Đặt
max_tokensoutput hợp lý (không để model viết essay khi chỉ cần JSON 5 field). - Log
usagetừ response API; đối chiếu hàng tuần với finance.
Ước chi phí batch (công thức dùng được)
cost ≈ rows
× (input_tokens_p95 + expected_output)
× price_per_token
× (1 + retry_rate)
Ritual trước khi green-light 10k row:
- Sample 50–100 document thật — gồm PDF dài, log rỗng, HTML bẩn.
- Đo system + tools + từng sample (cùng model sẽ chạy).
- Lấy p95, không lấy mean (mean che row làm nổ context).
- Cộng biên 10–20% cho template drift / wrapper phía provider.
- Nhân số row và giả định retry.
- Đặt hard cap: vượt ngưỡng thì summarize / map-reduce, đừng fail giữa chừng.
# Ví dụ đo chính xác với tiktoken (OpenAI-compatible)
import tiktoken
enc = tiktoken.encoding_for_model("gpt-5.6")
prompt = open("system.txt").read() + open("row_sample.txt").read()
print(len(enc.encode(prompt)))
Với Claude / Gemini: dùng tokenizer / SDK tương ứng hoặc field usage sau vài call thử — đừng giả định số OpenAI áp dụng y nguyên.
Tiếng Việt trong prompt: vài mẹo thực tế
- Viết ngắn, bullet thay vì lời mở đầu lịch sự dài (“Em chào anh/chị, em xin phép hỏi…”).
- Đưa quy tắc cố định vào system ngắn; data biến thiên vào user message một lần.
- Strip HTML / boilerplate lặp giữa các row trước khi gửi.
- Prefer “trả JSON keys X,Y,Z” thay vì “viết bài phân tích dài” khi chỉ cần field.
- Ảnh UI / screenshot: resize trước khi vision — Full HD không cần nếu chỉ đọc label.
ChatGPT UI vs API
| ChatGPT app / Plus | API | |
|---|---|---|
| Thanh toán | Subscription | Token $/1M (input/output khác giá) |
| Đếm token | Không map bill API | Dashboard + usage |
| System / tools | Ẩn sau product | Bạn tự gửi — tự trả tiền |
| Phù hợp | Tra cứu cá nhân | Production, batch, khách thuê |
Đừng báo khách “Plus của em cover được API shop” — hai sản phẩm khác nhau.
Giảm bill mà vẫn giữ chất lượng
- Đếm trước khi ship — gắn bước đo token vào CI / checklist PR cho prompt template.
- Rút system — xóa hướng dẫn trùng; tránh paste cả wiki vào system.
- Prompt caching (khi provider hỗ trợ) — prefix ổn định giảm cost lặp.
- Model routing — classify bằng model nhỏ; escalate model đắt chỉ khi cần.
- Batch API (nếu có) — cùng số token, giá/SLA khác; hợp embed / tóm tắt offline.
- Không log full prompt lên Slack — vừa tốn chỗ vừa rủi ro bảo mật.
Đo nhanh trên trình duyệt
Trước khi đốt credit production, dán system + một payload mẫu vào Token Counter để thấy ước lượng theo model (GPT / Claude / Gemini) và cảm giác chi phí tương đối.
Tool chạy local trên trình duyệt, phù hợp prompt nội bộ / dữ liệu khách (không upload server lạ). Đây là ước lượng nhanh — khi ký SLA hoặc báo cáo tài chính, xác nhận bằng tokenizer chính thức và usage API.
Quy trình gợi ý:
- Dán system + tools + 1 row p95.
- Ghi lại ước lượng; nhân số batch.
- Nếu số “đáng sợ” — cắt RAG / system trước, đừng chạy 10k rồi khóc.
- Sau deploy: so sánh ước lượng với invoice tuần đầu.
Checklist trước khi chạy job LLM
- Đã liệt kê system + tools + history + RAG vào budget
- Đã đo trên mẫu thật (có outlier), dùng p95
- Có biên độ + giả định retry
- Có
max_tokens/ schema output giới hạn độ dài - Có chiến lược truncate / summarize khi vượt context
- Biết ChatGPT Plus ≠ API credit
- Đã sanity-check bằng Token Counter hoặc tokenizer chính thức
Tóm tắt
Bill bất ngờ gần như luôn đến từ ước ký tự và quên phần gửi lặp mỗi request. Token là đơn vị tokenizer — tiếng Việt, JSON, RAG làm heuristic “÷4” sụp. Đo input đầy đủ, lấy p95, rồi mới nhân. Tool local giúp lập ngân sách nhanh; production vẫn cần tokenizer/usage thật.
Liên kết liên quan
- Token Counter — ước lượng token & chi phí API trên trình duyệt
- JSON Formatter — rút gọn / kiểm payload JSON trước khi nhét vào prompt
- Danh sách công cụ