Vì sao nói "hi" với Claude Code tốn 44 nghìn token

Nếu bạn dùng Claude Code và thấy quota cứ tụt vèo vèo dù hôm đó chẳng làm gì to tát thì bài viết này dành cho bạn. Mình cũng bị y như vậy, và thay vì ngồi đoán mò thì lần này mình quyết định mở transcript ra đếm từng token một (¬_¬")

À nếu bạn thắc mắc bài này có phải AI viết không thì câu trả lời vẫn là đúng rồi đấy. Từ lúc mổ transcript, sửa config cho tới viết bài đều do Claude Opus 5.5 làm hết, còn mình chỉ ngồi gõ “hi” với “ok” thôi :D

Bối cảnh

Setup của mình thì cũng không có gì đặc biệt, chỉ là cài hơi nhiều đồ:

  • Claude Code 2.1.311 chạy model Opus
  • Một mớ plugin: code-review, commit-commands, claude-code-council, claude-security, cả hai output style explanatory và learning…
  • Hơn 30 skill tự cài, trong đó có nguyên một bộ skill AWS
  • Các connector của claude.ai: Gmail, Calendar, Drive, Docs, Spotify, Hugging Face, Mermaid
  • Vài MCP server như codegraph, aws-mcp

Cái nào cài vào lúc đó cũng có lý do cả, nhưng cài xong thì… quên luôn là mình có nó =))))

Vấn đề gặp phải

Mình mở một session mới, gõ đúng hai ký tự hi, rồi xem usage mà API trả về cho request đầu tiên:

input_tokens:                 2
cache_creation_input_tokens:  44.382
cache_read_input_tokens:      0

44.382 input token cho một chữ “hi”. Prompt chỉ có 2 ký tự thôi, vậy hơn 44 nghìn token còn lại đi đâu? (╯°□°)╯︵ ┻━┻

Phân tích nguyên nhân

Bước 1: Lấy số liệu từ transcript

Claude Code ghi mỗi session thành một file JSONL ở ~/.claude/projects/<thư-mục-đã-mã-hóa>/<session-id>.jsonl. Mỗi dòng có type == "assistant" đều kèm trường usage do API trả về, nên đây là số thật chứ không phải ước lượng:

python3 -I - ~/.claude/projects/<project>/<session-id>.jsonl <<'EOF'
import json, sys
for line in open(sys.argv[1]):
    d = json.loads(line)
    if d.get("type") == "assistant":
        u = d["message"].get("usage") or {}
        print(u.get("input_tokens"),
              u.get("cache_creation_input_tokens"),
              u.get("cache_read_input_tokens"))
EOF

Lưu ý là phải đọc ba con số cùng nhau. Tổng input của một request bằng input_tokens + cache_creation_input_tokens + cache_read_input_tokens. Với Claude Code thì input_tokens gần như lúc nào cũng chỉ 2–3, vì hầu hết mọi thứ đều đi qua cache.

Bước 2: Dựng lại toàn bộ request

Từ transcript, mình dựng lại nguyên request đầu tiên, gồm system prompt, định nghĩa tool và các message được chèn vào, thành một file markdown khoảng 132 KB. Sau đó đếm số ký tự của từng phần. Và đây là bãi chiến trường:

Phần Ký tự Tỉ lệ
Schema của 17 tool 77,5k ~62%
↳ Artifact 37,0k ~30%
↳ SendFeedback 5,6k
↳ Workflow 5,5k
↳ AskUserQuestion 5,1k
↳ ScheduleWakeup 4,8k
↳ Agent 3,6k
↳ Bash 3,3k
↳ 10 tool còn lại ~12,5k
Danh sách skill (nằm trong tool Skill) 10,1k 8%
Danh sách loại agent 6,7k 5%
System prompt 6,8k 5%
Tên các tool deferred (Gmail, Calendar, Drive, Spotify, …) 3,3k 3%
Các file CLAUDE.md ~4k 3%
Hook output-style, claude-mem, hướng dẫn của MCP server, env/git status ~5,5k 4%
Tổng ~125k ký tự ≈ 44k token

Bước 3: Đọc bảng

Nhìn bảng thì có ba điểm khá rõ:

  1. Đây là chi phí cố định cho mỗi request. Schema của tool được gửi lại ở mọi lượt. Gõ “hi” hay nhờ refactor nguyên một module thì cũng phải trả mức nền khoảng 44k token trước khi model kịp viết chữ nào.
  2. Một tool chiếm gần một phần ba. Riêng phần mô tả tool Artifact, dùng để publish trang HTML lên claude.ai, đã khoảng 37 nghìn ký tự, trong khi lúc code mình gần như không bao giờ đụng tới nó.
  3. Phần còn lại phần lớn là đồ cài rồi quên. Repo không dùng AWS nhưng danh sách skill vẫn có cả bộ skill AWS. Hai plugin claude-code-council và claude-security thêm cả chục agent vào danh sách. Hai output style bật cùng lúc và cả hai đều chèn hướng dẫn “Insight”. Trong ~/.claude/CLAUDE.md còn một đoạn hướng dẫn CodeGraph khoảng 2,9k ký tự, trùng gần y nguyên với phần hướng dẫn mà MCP server codegraph đã tự gửi.

Vậy là rõ rồi. Prompt không có vấn đề gì, thủ phạm là cái context mà Claude Code tự đính kèm vào mọi request.

Lần thử đầu: phân tích xong rồi… để đó

Phân tích xong thì mình lập ngay một danh sách những thứ nên tắt, kèm mức tiết kiệm ước tính dựa trên số ký tự. Có danh sách rồi thì yên tâm đi làm việc khác.

Vài session sau mình đo lại thì:

Session Repo cache_creation cache_read Tổng lượt đầu
436ed126 (gốc) kiro-on-vscode 44.382 0 ~44,4k
d1ce4aec kiro-on-vscode 11.716 31.081 ~42,8k
8fb713e2 kiro-on-vscode 11.887 31.081 ~43,0k
0ef5d565 niits.github.io 42.871 0 ~42,9k

Tổng gần như không đổi, vẫn quanh 43k. Đương nhiên rồi, vì mình chưa sửa cái gì cả (;⌣̀_⌣́) Danh sách “nên làm” mà không làm thì con số không tự giảm được.

Dù vậy bảng này cũng cho thấy một điều thú vị: prompt caching đang gánh phần lớn chi phí, với điều kiện mở session mới đủ nhanh:

  • Hai session mở lại trong cùng repo vài phút sau đọc được khoảng 31k token từ cache, chỉ phải ghi mới khoảng 11,7k. Tức là khoảng 72% phần nền được tính theo giá cache read.
  • Session mở ở repo khác thì cache_read = 0 và phải ghi lại toàn bộ khoảng 43k. Mình đoán là do phần đầu request khác đi nên prefix không khớp, nhưng chưa kiểm chứng.

Về giá, theo tài liệu prompt caching của Anthropic, đọc từ cache chỉ tốn khoảng 0,1 lần giá input thường, còn ghi vào cache lại đắt hơn input thường (1,25 lần với TTL 5 phút, 2 lần với TTL 1 giờ). Vì vậy lượt đầu “lạnh” như session gốc là trường hợp tệ nhất: trả giá ghi cache cho toàn bộ 44k token. Có một chỗ mình chưa rõ là token cache read được tính vào usage limit của gói subscription theo tỉ lệ nào, nên mình không dám quy đổi mấy con số này ra phần trăm quota.

Giải pháp: tắt thật

Lần này thì làm thật. Có một điểm hay là tên setting mình không tìm trong docs mà grep thẳng trong binary của Claude Code. Các thông báo lỗi trong đó lộ ra khá đủ thông tin:

... the enableArtifact setting, CLAUDE_CODE_DISABLE_ARTIFACT, or a deny rule on Artifact ...
... disableClaudeAiConnectors setting or ENABLE_CLAUDEAI_MCP_SERVERS env var ...

Nhờ vậy mới biết tool Artifact có công tắc riêng. Nếu chỉ tắt connector thì tool này vẫn nằm đó và vẫn ngốn 37k ký tự.

Sửa ~/.claude/settings.json

{
  "enableArtifact": false,
  "disableClaudeAiConnectors": true,
  "enabledPlugins": {
    "claude-code-council@niits-ds-skills": false,
    "claude-security@claude-plugins-official": false,
    "explanatory-output-style@claude-plugins-official": false
  }
}

Giải thích từng dòng:

Setting Tác dụng
enableArtifact: false Bỏ tool Artifact, mục to nhất (~37k ký tự)
disableClaudeAiConnectors: true Bỏ Gmail, Calendar, Drive, Docs, Spotify, … khỏi Claude Code
Tắt claude-code-council, claude-security Bỏ agent và skill của hai plugin này khỏi danh sách
Tắt explanatory-output-style Output style learning vốn đã bao gồm phần explanatory nên bật cả hai là thừa

Lưu ý: Nhớ backup settings.json trước khi sửa. Ngoài ra nếu shell của bạn bật noclobber (zsh hay bị) thì kiểu jq ... > settings.json sẽ bị chặn, phải ghi ra file tạm rồi mv đè lên.

Dọn skill

Bộ skill AWS thì mình chuyển hết 24 thư mục từ ~/.claude/skills/ sang ~/.claude/skills-disabled/. Lúc nào cần thì chuyển ngược về là xong. Đoạn CodeGraph trong CLAUDE.md thì đã xóa từ trước.

Áp dụng và kiểm tra

Config chỉ có hiệu lực ở session mới, nên mình mở session mới, gõ hi, rồi so với một session cũ cùng repo, cũng là lượt đầu và cũng không có cache:

Session Cấu hình cache_creation cache_read Tổng lượt đầu
6fe27d3f cũ 50.558 0 50,6k
faa976fb mới 25.355 0 25,4k

Giảm khoảng 25k token, tức khoảng một nửa ☆*:.。.o(≧▽≦)o.。.:*☆

Để chắc chắn số giảm là do đúng mấy thay đổi trên chứ không phải ăn may, mình đếm xem từng thành phần còn xuất hiện trong transcript hay không:

Thành phần Cũ Mới
Tool Artifact có mất
Connector Gmail, Drive, Calendar, … có mất
Skill AWS có mất
Agent của claude-code-council và claude-security có mất
Hướng dẫn output style có mất
MCP server aws-mcp có vẫn còn

Vài lưu ý để đọc con số này cho đúng:

  • Mỗi cấu hình mới chỉ có một mẫu đo. Phần context thay đổi theo từng session (git status, trạng thái claude-mem, …), nên 50% là con số xấp xỉ.
  • Hướng dẫn của learning cũng biến mất theo, dù mình chỉ tắt explanatory. Lý do thì mình chưa rõ.
  • Cái giá phải trả: trong Claude Code CLI không còn dùng được Gmail, Drive hay Artifact nữa. Repo nào cần thì bật lại riêng bằng .claude/settings.local.json.

Tổng kết

Bài viết này ghi lại quá trình đi tìm lý do vì sao một chữ “hi” lại tốn 44 nghìn token trong Claude Code. Tóm lại thì:

  • Prompt không phải vấn đề. Phần lớn token là context cố định đi kèm mọi request: schema tool, danh sách skill và agent, hướng dẫn của plugin và MCP server.
  • Thủ phạm chính là đồ cài rồi quên. Riêng tool Artifact đã chiếm khoảng 30%.
  • Fix gồm 3 phần: tắt Artifact và connector bằng setting, tắt các plugin không dùng, và dọn các skill không liên quan. Kết quả là lượt đầu giảm khoảng một nửa.
  • Prompt caching giúp rất nhiều, nhưng chỉ khi mở session mới đủ nhanh và trong cùng repo. Vì vậy đừng mở session mới hay /clear liên tục chỉ để hỏi mấy câu lặt vặt.

Việc còn lại là tắt nốt aws-mcp ở những repo không dùng AWS, và đo thêm vài session nữa để xem mức giảm có ổn định không.

Bài học lớn nhất của mình lần này không nằm ở con số. Muốn biết token đi đâu thì phải mở transcript ra đếm, và đếm xong rồi thì phải sửa thật và đo lại. Danh sách “nên làm” mà không có số đo đi kèm thì mới chỉ là giả thuyết thôi.

Bài viết đến đây là hết, cảm ơn mọi người đã dành thời gian đọc (b ᵔ▽ᵔ)b

Tài liệu tham khảo