Quay lại blog

Tối ưu chi phíHướng dẫn

Claude Code token usage: giữ output công cụ ngoài context

Cách một hook PreToolUse và plugin context-mode giữ log test ngoài context của Claude Code, kèm ước tính chi phí phiên có và không có lọc.

Bởi CheapTokens TeamĐã xuất bản 6 phút đọc

Terminal hiển thị lệnh test được pipe qua grep và head để chỉ lỗi đến được Claude Code
Trên trang này
  1. Vì sao một log bị trả tiền nhiều lần
  2. Cách 1: hook PreToolUse lọc output test
  3. Cách 2: context-mode cho kết quả công cụ lớn
  4. Một phiên dài tốn bao nhiêu, có và không có lọc
  5. Chạy Claude Code trên model CheapTokens
  6. Danh sách kiểm tra nhanh

Agent của bạn đã chạy bộ test ba lần, và hóa đơn còn lớn hơn cả công việc. Nguyên nhân hiếm khi là code nó viết. Mà là log test: một khi kết quả công cụ lọt vào context của Claude Code, mọi request sau đó đều mang nó theo lần nữa. Cách khắc phục là thu nhỏ output công cụ trước khi model nhìn thấy. Cách chính thức là hook PreToolUse trên Bash; cách của bên thứ ba là plugin context-mode. Cả hai ở dưới, kèm ước tính chi phí cho một phiên dài trên model CheapTokens.

Vì sao một log bị trả tiền nhiều lần#

Theo trang chi phí của Claude Code (https://code.claude.com/docs/en/costs, kiểm tra ngày 23 tháng 10 năm 2026), Claude Code gửi toàn bộ cuộc hội thoại trong mỗi request, và mỗi lần dùng công cụ lại kích hoạt một request khác mang theo kết quả công cụ. Prompt caching đọc lại lịch sử với mức giá cache rẻ hơn, nhưng token vẫn ở đó.

Giả sử agent chạy npm test và nhận về log 10.000 dòng. Tài liệu nói loại log đó có thể lên tới hàng chục nghìn token. Giả định 30.000 token. Dù bạn làm gì tiếp theo, 30.000 token đó vẫn là một phần input của bước 11, bước 12, bước 13, và cứ thế cho tới khi bạn /clear hoặc compact. Và đó là cái bẫy: log chỉ hữu ích cho một bước, mà bạn trả tiền cho nó suốt ba mươi bước.

Cách 1: hook PreToolUse lọc output test#

Cũng trang tài liệu đó gợi ý dùng hook để tiền xử lý: hook PreToolUse trên Bash viết lại các lệnh test (npm test, pytest, go test) để chúng đi qua grep -A 5 -E '(FAIL|ERROR|error:)' | head -100. Agent sau đó chỉ thấy các lỗi cùng vài dòng ngữ cảnh, chứ không phải 10.000 dòng chấm xanh. Tài liệu nói cách này có thể biến hàng chục nghìn token thành hàng trăm.

Những gì agent thấy trước và sau hook
Output npm test thô so với chỉ các lỗi

Đây là script từ trang tài liệu đó (kiểm tra ngày 23 tháng 10 năm 2026). Nó cần jq. Tạo thư mục bằng mkdir -p ~/.claude/hooks, lưu script thành ~/.claude/hooks/filter-test-output.sh và chạy chmod +x trên nó:

bash
#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

pattern='^(npm test|pytest|go test)( [^;&|<>`$#\\[:cntrl:]]*)?$'

if [[ "$cmd" =~ $pattern ]]; then
  filtered_cmd="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
  echo "$input" | jq --arg filtered "$filtered_cmd" '{hookSpecificOutput: {hookEventName: "PreToolUse", updatedInput: (.tool_input + {command: $filtered})}}'
else
  echo "{}"
fi

Sau đó đăng ký nó trong ~/.claude/settings.json:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/filter-test-output.sh" }]
      }
    ]
  }
}

Để kiểm tra nó hoạt động, mở /hooks trong Claude Code và tìm mục PreToolUse, hoặc bắt đầu bằng claude --debug-file ./claude-debug.txt và yêu cầu agent chạy npm test. Khi hook đã viết lại lệnh, file có một dòng modified tool input keys với trường command. Nếu test pass, output rỗng, nên agent nhận một thành công im lặng; điều chỉnh pattern nếu runner của bạn in lỗi theo cách khác.

Cách 2: context-mode cho kết quả công cụ lớn#

Hook chỉ bao phủ các lệnh bạn có thể pipe. Ảnh chụp trang từ Playwright hay danh sách hai mươi issue GitHub đến từ các công cụ MCP. Đó là thứ context-mode nhắm tới. Theo README của nó (https://github.com/mksglu/context-mode, kiểm tra ngày 23 tháng 10 năm 2026; nó không hiển thị phiên bản hay ngày), nó là một MCP server và plugin giữ output công cụ thô ngoài context window, lưu trạng thái phiên trong SQLite và định tuyến các lệnh gọi công cụ qua hook. Nó cần Claude Code v1.0.33 trở lên, và giấy phép của nó là Elastic License 2.0, không phải giấy phép mã nguồn mở OSI.

Cài đặt trong Claude Code:

text
/plugin marketplace add mksglu/context-mode
/plugin install context-mode@context-mode

Khởi động lại hoặc chạy /reload-plugins, rồi xác minh bằng /context-mode:ctx-doctor. Biến thể chỉ MCP, claude mcp add context-mode -- npx -y context-mode, thêm các công cụ nhưng không có định tuyến tự động.

Dự án báo cáo mức giảm lớn: 315 KB thành 5,4 KB (98%), ảnh chụp trang 56 KB thành 299 byte, 986 KB thành 62 KB. Đó là số của chính tác giả: hãy coi chúng là mức trần và đo trên phiên của bạn bằng /context trước và sau.

Một phiên dài tốn bao nhiêu, có và không có lọc#

Đây là phép tính trên một phiên giả định. Đó là phiên lập trình 40 bước với context nền trung bình 20.000 token, 500 token output mỗi bước, và ba lần chạy test, ở các bước 10, 20 và 30. Mỗi log thô là 30.000 token; bản đã lọc là 500.

  • Log từ bước 10 được gửi lại trong 30 request sau nó: 30 × 30.000 = 900.000 token. Bước 20: 20 × 30.000 = 600.000. Bước 30: 10 × 30.000 = 300.000. Input thêm: 900.000 + 600.000 + 300.000 = 1.800.000.
  • Đã lọc: (30 + 20 + 10) × 500 = 30.000 input thêm.
  • Input nền: 40 × 20.000 = 800.000. Output: 40 × 500 = 20.000.
  • Vậy phiên đó là 800.000 + 1.800.000 = 2.600.000 token input khi không lọc và 800.000 + 30.000 = 830.000 khi lọc, với 20.000 token output trong cả hai trường hợp.

Phép tính đếm mọi token input ở mức giá đầy đủ. Caching làm giảm con số thực tế, nhưng nó giảm cả hai trường hợp theo cùng logic. Giá trực tiếp cho MiniMax-M2.7 (MiniMaxAI/MiniMax-M2.7, context 180K, tối đa 8.192 token output), là model phù hợp với các vòng lặp agent nặng input như thế này, nằm trong biểu đồ dưới đây.

Chi phí phiên trên MiniMax-M2.7, 40 bước
  • Không lọc$0.133
  • Có hook$0.0445

Giả định: 40 bước, context nền 20.000 token, 500 token output mỗi bước, ba lần chạy test 30.000 token (đã lọc: 500).

Trên MiniMax-M2.7, phiên đó tốn $0.133 khi không lọc và $0.0445 khi lọc, và tổng cộng, tính cả input lẫn output, nó rẻ hơn giá tham chiếu của OpenRouter. Khoảng hai phần ba input trong trường hợp không lọc là log mà agent chỉ đọc một lần.

Điểm mấu chốt không phải con số đô la chính xác. Mà là bộ lọc loại bỏ khoảng 1.770.000 trong 2.600.000 token input (2.600.000 − 830.000 = 1.770.000) trên bất kỳ model nào, và một model rẻ hơn làm giảm giá của mọi token còn lại.

Chạy Claude Code trên model CheapTokens#

Claude Code nói giao thức Anthropic Messages, và CheapTokens hỗ trợ nó. Base URL cho Claude Code không có /v1. Hướng dẫn đầy đủ ở cách kết nối Claude Code với CheapTokens. Bản ngắn, với key giữ chỗ:

bash
export ANTHROPIC_BASE_URL=https://api.cheaptokens.dev
export ANTHROPIC_AUTH_TOKEN=YOUR_CHEAPTOKENS_KEY
export ANTHROPIC_MODEL=MiniMaxAI/MiniMax-M2.7
claude

Dùng id đầy đủ từ tài liệu; tên ngắn từ bảng giá không được API chấp nhận. Giá cho mọi model nằm trên trang giá. Với những thói quen khác giúp giảm hóa đơn Claude Code (/clear, /compact, /mcp, subagent), xem Cách làm Claude Code rẻ hơn. Để xem input và output được đếm thế nào trên một request thực tế, đọc Một request API dùng bao nhiêu token.

Danh sách kiểm tra nhanh#

  1. Chạy /context trong một phiên dài và xem cái gì đang chiếm chỗ.
  2. Thêm hook Bash cho các lệnh test; xác nhận việc viết lại trong /hooks hoặc debug log.
  3. Nếu công cụ MCP trả về ảnh chụp lớn, thử context-mode và so sánh /context trước và sau.
  4. /clear giữa các tác vụ không liên quan, để log cũ không còn đi kèm nữa.