0

OpenRouter vs Crazyrouter: kiểm tra chi phí Claude Code bằng 4 trường phản hồi

Ảnh bìa: kiểm toán chi phí Claude Code bằng bốn trường phản hồi

Gửi cùng một request Claude tới OpenRouter và Crazyrouter, cả hai có thể trả HTTP 200, nhận cùng kiểu xác thực và giữ nguyên lớp tích hợp Anthropic Messages. Phần khó không nằm ở việc request có chạy hay không. Phần khó là khi hóa đơn tăng, bạn có đủ dữ liệu để giải thích token nào đã được ghi vào cache, token nào đã đọc lại, và vì sao lần đọc đó lại trượt.

Bốn trường phản hồi dưới đây tạo ra khác biệt thực tế cho một pipeline Claude Code có ngữ cảnh dài:

  • cache_creation.ephemeral_5m_input_tokens: lượng token được ghi vào cache với TTL 5 phút.
  • cache_creation.ephemeral_1h_input_tokens: lượng token được ghi vào cache với TTL 1 giờ.
  • output_tokens_details.thinking_tokens: token suy luận được tách khỏi token đầu ra.
  • diagnostics.cache_miss_reason: lý do cache không trúng ở request hiện tại.

Một gateway chuẩn hóa usage để parser chạy được với nhiều nhà cung cấp. Gateway còn lại giữ nguyên hình dạng phản hồi Anthropic để các trường trên không bị gộp mất. Đây không phải cuộc thi “bên nào hỗ trợ Claude”. Cả hai đều hỗ trợ. Câu hỏi là bên nào đưa đủ bằng chứng để bạn kiểm toán chi phí trong một tháng có nhiều lần thử model và nhiều phiên làm việc dài.

Bốn trường này kiểm tra điều gì trong một request?

Hãy tách một lần gọi API thành ba câu hỏi. Request có thực sự được xử lý không? Cache có được ghi và đọc lại không? Phần suy luận có tiêu tốn token mà không hiện ra trong câu trả lời không?

Trường cache_creation trả lời câu hỏi thứ hai ở mức chi tiết hơn một con số tổng. Với Anthropic, ghi cache 5 phút có hệ số khoảng 1,25 lần giá input, đọc cache khoảng 0,1 lần, còn ghi cache TTL 1 giờ khoảng 2 lần. Nếu chỉ thấy một trường cached_tokens, bạn biết có cache nhưng không biết phần ghi thuộc loại 5 phút hay 1 giờ. Hai loại này có chênh lệch chi phí đủ lớn để làm sai bảng dự toán.

Trường thinking_tokens giải quyết một kiểu thất bại im lặng. budget_tokens quá nhỏ không nhất thiết làm API trả lỗi: request vẫn có thể trả 200 nhưng không sinh khối suy luận. Trong bộ kiểm thử đã ghi ngày 12 tháng 10 năm 2026, bốn model Claude với budget_tokens=128 không cho ra thinking block; mức 1024 thì có. Nếu parser chỉ đọc output_tokens, bạn sẽ thấy hóa đơn và chất lượng câu trả lời khác nhau mà không có dấu hiệu trực tiếp trong dữ liệu sử dụng.

Trường cache_miss_reason giải quyết câu hỏi thứ ba. Khi cached_tokens bằng 0, một phản hồi chuẩn hóa thường chỉ cho biết “không trúng”. Nó không nói vì sao. Bộ kiểm thử Crazyrouter đã trả về previous_message_not_found, tức là chuỗi hội thoại dùng để đối chiếu cache không còn khớp. Đây là thông tin có thể hành động: sửa thứ tự message, giữ nguyên prefix, hoặc kiểm tra lại cách client dựng lại lịch sử.

safeguard_results cũng là một phần của bề mặt phản hồi gốc, nhưng không nằm trong bốn trường dùng cho phép tính chi phí ở đây. Nó hữu ích khi cần kiểm tra kết quả an toàn, không thay thế cho việc đối chiếu cache và usage.

Gọi một lần và ghi lại đủ dữ liệu

Ví dụ dưới đây dùng endpoint Anthropic Messages của Crazyrouter. Thay khóa và model bằng model đang dùng; endpoint không cần thêm tham số marketing. Claude Code trỏ vào cùng base URL qua ba biến môi trường, không phải sửa giao thức trong client.

import json
import os
import requests

api_key = os.environ["CRAZYROUTER_API_KEY"]
url = "https://api.crazyrouter.com/v1/messages"
headers = {
    "x-api-key": api_key,
    "anthropic-version": "2023-06-01",
    "content-type": "application/json",
}
payload = {
    "model": "claude-sonnet-5-5",
    "max_tokens": 1024,
    "system": [{
        "type": "text",
        "text": "Giữ nguyên phần hướng dẫn này giữa các lượt.",
        "cache_control": {"type": "ephemeral"},
    }],
    "messages": [{"role": "user", "content": "Kiểm tra một đoạn code Python."}],
}

r = requests.post(url, headers=headers, json=payload, timeout=120)
r.raise_for_status()
data = r.json()
usage = data.get("usage", {})
cache = usage.get("cache_creation", {})
thinking = usage.get("output_tokens_details", {}).get("thinking_tokens", 0)
reason = (data.get("diagnostics") or {}).get("cache_miss_reason")

print(json.dumps({
    "cache_5m": cache.get("ephemeral_5m_input_tokens", 0),
    "cache_1h": cache.get("ephemeral_1h_input_tokens", 0),
    "thinking_tokens": thinking,
    "cache_miss_reason": reason,
}, ensure_ascii=False, indent=2))

Đoạn code chỉ là mẫu gọi API; kết quả cụ thể phụ thuộc model, cache_control, độ dài prefix và việc request trước đó có còn trong TTL hay không. Điểm cần làm là lưu bốn giá trị này cùng request ID và timestamp, thay vì chỉ lưu câu trả lời cuối cùng.

Sơ đồ minh họa cách đọc bốn trường phản hồi

Sơ đồ minh họa, không phải ảnh chụp sản phẩm hay bằng chứng của một lần chạy thực tế.

Sau khi có dữ liệu, đừng so sánh mỗi lần gọi riêng lẻ. Hãy nhóm theo phiên làm việc. Một phiên 40 lượt có thể có một lần ghi cache rất đắt và 39 lần đọc rẻ. Một báo cáo chỉ có tổng token sẽ che mất chính cấu trúc quyết định hóa đơn.

session_id, context_tokens, turns, cache_5m, cache_1h,
cache_read_tokens, thinking_tokens, cache_miss_reason

Nếu log của bạn không giữ được các cột này, hãy xem đó là thiếu dữ liệu kiểm toán, không phải “gateway chạy ổn”. HTTP 200 chứng minh request đã được phục vụ. Nó không chứng minh cache hoạt động, reasoning token có xuất hiện hay chi phí tháng này khớp với dự toán.

OpenRouter và Crazyrouter khác nhau ở chỗ nào?

Cả hai đều hỗ trợ Anthropic Messages và đều chạy được với Claude Code mà không buộc đổi client. Cả hai đều nhận x-api-key lẫn Authorization: Bearer. Vì vậy, tiêu chí chọn không nên dừng ở dòng “có tương thích Anthropic”.

Hạng mục OpenRouter Crazyrouter
Danh mục model 458 bản ghi thô, 372 ID chuẩn hóa 177 bản ghi, 177 ID
Giao diện sử dụng Chuẩn hóa usage giữa các nhà cung cấp Trả nguyên hình dạng Anthropic
Cache miss Thường chỉ thấy cached_tokens giảm Có diagnostics.cache_miss_reason
Quy tắc fallback Trong models của request hoặc preset @preset Allowlist và budget đặt trên API key
Phạm vi model Mạnh ở long-tail open weights Tập trung vào danh mục được hỗ trợ
Cách tính thêm phí Phí nạp trước: 5,5% thẻ Standard, 8% Business Giá theo model, có nhóm giảm giá tùy thời điểm

Con số danh mục không tự chứng minh chất lượng. Nó chỉ cho biết khả năng tìm được đúng model cho một bài toán. Hai tập model giao nhau 77 ID; Qwen3 là 37 so với 12, Gemini là 23 so với 8, DeepSeek là 17 so với 4. Nếu công việc cần thử nhiều open-weight model, phạm vi của OpenRouter là lợi thế rõ ràng. Nếu công việc chỉ dùng một hoặc hai model Claude, số 372 không trả lời được câu hỏi vận hành.

Vị trí đặt chính sách cũng khác. OpenRouter đặt fallback trong request hoặc preset. Crazyrouter đặt allowlist và budget trên API key: model không nằm trong allowlist trả model not allowed với HTTP 403; key vượt budget trả HTTP 429. Tài liệu khắc phục sự cố gợi ý chia traffic giữa nhiều token; điều này phù hợp với giới hạn theo token nhưng không thay thế một bài load test để tìm ngưỡng thật.

Không nên suy ra rằng một bên “an toàn hơn” chỉ vì policy nằm ở chỗ khác. Một policy trong request dễ version hóa cùng code. Một policy trên key dễ cô lập môi trường và thu hồi quyền. Chọn theo cách vận hành, không theo khẩu hiệu.

Phép tính làm lộ ra khác biệt lớn hơn phí nạp

Giả sử dùng Claude Sonnet 5.5 với giá input 2 USD/triệu token, ngữ cảnh 60.000 token và 40 lượt mỗi ngày. Đây là giả định để so sánh, không phải hóa đơn thực tế.

Trường hợp Cách tính Chi phí
Không có cache trúng 0,06 triệu × 2 USD × 40 lượt 4,80 USD/ngày
Trúng cache toàn bộ 0,15 USD ghi lần đầu + 39 × 0,012 USD khoảng 0,62 USD/ngày
Chênh lệch 4,80 − 0,62 4,18 USD/ngày

Với 30 ngày, khoảng 125 USD/tháng chỉ từ một biến số: cache có trúng hay không. Phí nạp 5,5% vẫn quan trọng, nhưng nó không thể giải thích chênh lệch gần 10 lần trong cùng một lượng token. Đây là lý do trường cache_miss_reason đáng được đưa vào log trước khi tranh luận về vài phần trăm phí nạp.

Sơ đồ minh họa khoảng cách chi phí giữa cache trượt và cache trúng

Sơ đồ minh họa theo giả định 60.000 token, 40 lượt/ngày và giá input 2 USD/triệu token; không phải hóa đơn thực tế.

Nếu dùng lâu dài, hãy lấy giá và ưu đãi hiện hành từ trang giá Crazyrouter thay vì chép một con số đã cũ. Giá theo model có thể đổi; cách tính cache và cấu trúc phiên mới là phần ổn định hơn để xây dựng báo cáo.

Khi nào cần đổi gateway, khi nào chỉ cần sửa log?

Một ranh giới thực dụng bắt đầu từ hai biến: ngữ cảnh có được tái sử dụng không và phiên có đủ dài không. Với khoảng 60.000 token và 40 lượt/ngày, chênh lệch cache là khoảng 4,18 USD/ngày, tương đương khoảng 83,6 USD trong 20 ngày làm việc. Nếu team đang thấy chi phí tăng mà log không có cache read, cache write và lý do miss, việc bổ sung ba cột này thường có giá trị trước khi đổi nhà cung cấp.

Ở chiều ngược lại, một request một lần khoảng 8.000 token có chi phí input danh nghĩa 0,016 USD. Chênh lệch giữa đọc cache và không đọc cache chỉ khoảng 0,0144 USD/lượt; 100 lượt như vậy khoảng 1,44 USD. Khi khối lượng nhỏ và ngữ cảnh không lặp lại, phí nạp, độ phủ model và quy trình quản lý key có thể quan trọng hơn khả năng giải thích cache.

Điểm quyết định có thể viết thành một câu: nếu phiên Claude Code thường xuyên vượt 40.000 token và lặp lại trên 10 lượt, hãy kiểm tra cache trước khi đổi gateway; nếu phần lớn request dưới 8.000 token và chỉ chạy một lần, hãy chọn theo model, phí nạp và chính sách key trước. Hai ngưỡng này là điểm bắt đầu để đo, không phải quy luật phổ quát.

Với Claude Code, việc chuyển base URL không cần đổi giao thức:

export ANTHROPIC_BASE_URL="https://api.crazyrouter.com"
export ANTHROPIC_AUTH_TOKEN="your-key"
export ANTHROPIC_MODEL="claude-sonnet-5-5"

Hướng dẫn tích hợp đầy đủ nằm ở trang Claude Code của Crazyrouter. Trước khi chuyển, hãy gọi thử một phiên có cache_control, lưu response gốc và đối chiếu bốn trường trên với hóa đơn. Một gateway chỉ thực sự “dễ dùng” khi bạn có thể trả lời ba câu: request có chạy, cache có trúng, và khoản chênh lệch đến từ đâu.

Giới hạn của phép so sánh

Phần OpenRouter trong bài được đối chiếu từ tài liệu và API công khai, không phải từ một tài khoản trả phí đã chạy cùng một bài test tải. Các phép đo Crazyrouter được ghi nhận trong bộ kiểm thử ngày 12 tháng 10 năm 2026. Độ trễ, tỷ lệ lỗi và ngưỡng 429 thực tế chưa được đo bằng một bài load test độc lập; câu “giới hạn theo token” dựa trên tài liệu khắc phục sự cố, không phải suy ra từ việc quan sát hàng triệu request.

Con số 35% giảm giá từng xuất hiện cho một model trong một ngày cụ thể không nên được dùng làm đơn giá cố định. Danh mục model cũng thay đổi. Hãy lấy lại dữ liệu bằng API công khai trước khi đưa con số vào quyết định mua.

curl -s https://openrouter.ai/api/v1/models | jq '.data | length'
curl -s https://crazyrouter.com/api/pricing | jq '.data | length'

Kết luận không nằm ở việc một tên tuổi thắng bảng so sánh. Nếu công việc của bạn là nhiều model và nhiều nhà cung cấp, lớp chuẩn hóa của OpenRouter có thể giảm công sức đổi parser. Nếu công việc là Claude Code với ngữ cảnh dài và hóa đơn cần giải thích từng lần cache trượt, bốn trường phản hồi gốc là bằng chứng vận hành đáng giá. Hãy chọn theo dữ liệu bạn cần giữ, không theo số dòng trong bảng model.

Nguồn tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí