Cost, Latency & Token Economics for LLM Apps
Kinh tế token — Chi phí, độ trễ và hiệu quả
CEO hỏi: 'Chatbot hỗ trợ khách hàng tốn bao nhiêu một tháng?' Bạn nên trả lời dựa trên số nào để vừa đúng, vừa an toàn cho quyết định?
Trước khi vào lý thuyết, hãy tự kéo slider. Chọn model, set input/output tokens, đẩy cache hit rate, bật cascade. Quan sát $/ngày, phân rã latency, và vạch break-even với lương nhân viên thật sự chuyển động.
Hình minh họa
Cấu hình
Kéo slider, bật toggle — mọi ô bên phải cập nhật ngay.
Cached read tính 10% giá gốc (discount 0.9×)
Ước tính
Dùng làm điểm khởi đầu — hãy xác thực bằng số đo thực tế trước khi báo cáo sếp.
Chi phí / ngày
$500.00
$/request = $0.01000
Phân rã latency (ước tính p95)
7.82s
So với nhân viên lương 15tr / tháng
Cao hơn 3× lương người — cần dừng traffic không cần thiết
Cost history · 1/20
min $500.00 · max $500.00
Token là đơn vị tính tiền kỹ thuật. Nhưng business mới cần biết $/task hoặc $/user. Giữa hai đó có 5 bước chuyển đổi: token → $/call → $/task → $/user-session → $/ngày → $/tháng. Mỗi bước có đòn bẩy tối ưu riêng. Nếu chỉ nhìn "tổng token" bạn sẽ bỏ qua 4 điểm can thiệp có giá trị.
get_user_profile trong 1-5 phút). Đừng tối ưu model khi nút cổ chai nằm ở tool graph.Bill LLM của bạn $10k/tháng. Breakdown: 70% input tokens, 30% output. Chiến thuật nào đáng ưu tiên đầu tiên?
p95 latency = 8s, user phàn nàn. Bạn phân rã: 60% decode, 15% TTFT, 15% tool calls, 10% retrieval. Bước đi đúng?
Giải thích
Kinh tế token là khung tư duy biến đơn vị kỹ thuật (token) thành đơn vị quyết định (chi phí / tác vụ, độ trễ, break-even so với nhân công). Trong production, bạn cần ba phương trình: công thức chi phí, công thức độ trễ, và công thức chi phí kỳ vọng khi có cascade.
Công thức chi phí cho một task (một lần gọi model):
N: số lần gọi model trong một task (1 với chatbot đơn giản, 5-20 với agent).t_in,t_out: input và output tokens trung bình mỗi lần gọi.p_in,p_out: giá USD / token (tính từ bảng giá $/1M ÷ 1,000,000).r: cache hit rate (0..1);d: discount factor cho cached input (thường 0.9 — tức cached tính 10%).
Phân rã độ trễ (latency):
TTFT là thời gian từ gửi request đến token đầu tiên — phụ thuộc network, prompt length, và prompt caching. R_decode là tốc độ sinh token (tokens/s) đặc trưng cho từng model. L_retrieval gồm vector search / rerank / reading file. L_tools là tổng thời gian các tool call (tuần tự hoặc song song). Phần nào lớn nhất chính là nơi bạn nên tối ưu trước — xem KV cache và inference optimization để đi sâu.
Với model cascade (cheap-first routing), chi phí kỳ vọng trên toàn phân phối traffic:
Thiết kế gate (quyết định có escalate không) quan trọng: gate quá lỏng → nhiều câu khó vẫn dừng ở tier rẻ → quality sụt; gate quá chặt → không ai đi qua tier rẻ → tiết kiệm không có. Calibrate bằng A/B trên một subset thật.
from dataclasses import dataclass
from typing import Callable
@dataclass
class TokenBudget:
"""Theo dõi token usage theo task. Emit metric + cảnh báo khi vượt 80%."""
task_id: str
max_input: int
max_output: int
emit_metric: Callable[[str, float, dict], None]
used_input: int = 0
used_output: int = 0
def record(self, in_tok: int, out_tok: int) -> None:
self.used_input += in_tok
self.used_output += out_tok
# Gửi metric realtime — dashboard \$/task dựng trên metric này.
self.emit_metric(
"llm.tokens.used",
in_tok + out_tok,
{"task": self.task_id, "kind": "total"},
)
self._warn_if_over_budget()
def _warn_if_over_budget(self) -> None:
in_pct = self.used_input / max(1, self.max_input)
out_pct = self.used_output / max(1, self.max_output)
if max(in_pct, out_pct) >= 0.8:
self.emit_metric(
"llm.budget.warning",
max(in_pct, out_pct),
{"task": self.task_id},
)
def cost_usd(self, p_in_per_m: float, p_out_per_m: float,
cache_hit: float = 0.0, discount: float = 0.9) -> float:
eff_in = (p_in_per_m / 1_000_000) * (1 - cache_hit * discount)
eff_out = p_out_per_m / 1_000_000
return self.used_input * eff_in + self.used_output * eff_outimport type { NextRequest, NextResponse } from "next/server";
interface Usage {
inputTokens: number;
outputTokens: number;
cachedInputTokens: number;
model: string;
latencyMs: number;
}
// Middleware bọc tầng gọi LLM. Mỗi request emit đúng một record usage.
export async function withTokenMeter<T>(
req: NextRequest,
run: () => Promise<{ result: T; usage: Usage }>,
sink: (u: Usage & { route: string; userId?: string }) => void,
): Promise<T> {
const started = performance.now();
const { result, usage } = await run();
const latencyMs = performance.now() - started;
// Báo về observability (Datadog, Honeycomb, OTLP...) — một record / request.
sink({
...usage,
latencyMs,
route: req.nextUrl.pathname,
userId: req.headers.get("x-user-id") ?? undefined,
});
return result;
}
// Dashboard dùng dữ liệu này để tính $/task realtime:
// SELECT route, SUM(input_tokens * p_in + output_tokens * p_out) / COUNT(DISTINCT task_id)
// FROM llm_usage WHERE ts > now() - interval '1 hour' GROUP BY route;Để theo dõi những con số này realtime, bạn cần tầng quan sát phù hợp — xem observability for AI. Kết hợp ba topic này (token economics + inference optimization + observability) là nền tảng cost discipline cho LLM production.
Bối cảnh. Một đội ở MoMo triển khai chatbot hỗ trợ CSKH: tra đơn, hủy giao dịch, hướng dẫn liên kết thẻ. Volume: ~180k conversation/ngày, mỗi conversation trung bình 4 turn, dùng gpt-4o-full cho toàn bộ.
Trước khi đo.Team nghĩ tốn "khoảng vài nghìn đô". Không có dashboard $/task, không có alert khi spike. Cuối tháng hóa đơn về: $18.000 — gần bằng 30 nhân viên CSKH. Sếp hỏi tại sao, không ai trả lời chắc.
Đo trước, tối ưu sau. Tuần 1-2: chỉ thêm observability. Kết quả phân rã:
- 72% cost ở input tokens (system prompt 3.2k + FAQ 4k + lịch sử hội thoại).
- 28% ở output. Trong output, 30% là câu trả lời đơn giản (yes/no/status).
- p95 latency 6.4s — decode 55%, TTFT 20%, tool 15%, retrieval 10%.
Ba can thiệp.
- Prompt caching cho system prompt + FAQ: hit rate steady-state đạt 88% → input cost giảm ~79%.
- Cascade gpt-4o-mini → gpt-4o-full: gate là một classifier nhỏ kiểm intent. 73% traffic (status, FAQ đơn giản) dừng ở mini; 27% khó (policy edge, refund) lên full. $/req giảm thêm ~45%.
- Tóm tắt context > 5 turn: history dài tóm thành 300 token thay vì gửi full 2-3k token. Input tiếp tục giảm 15% ở phần variable.
Kết quả sau 4 tuần. Hóa đơn: $4.200/tháng(giảm 77%). CSAT không đổi (lấy từ 2k rating sampling mỗi tuần). p95 latency: 3.8s (nhờ mini nhanh hơn cho 73% traffic). Dashboard $/task realtime thay cho "đoán cuối tháng"; alert khi spike > 20% so với baseline 7 ngày.
Bài học. Thứ tự đúng: đo → tìm Pareto → tối ưu đúng chỗ → theo dõi CSAT. Nếu team đi thẳng vào "đổi model rẻ hơn" từ đầu, khả năng cao CSAT tụt rồi phải rollback — mất cả tiền và niềm tin của sếp vào AI team.
- Đơn vị tính tiền là token, nhưng đơn vị quyết định phải là $/task hoặc $/user — có 5 bước chuyển đổi giữa hai đó.
- Luôn đo trước khi tối ưu: observability tokens/request + dashboard $/task realtime là tiền đề, không phải bonus.
- Latency có 4 thành phần (TTFT + decode + retrieval + tool) — tối ưu theo khối to nhất, không theo khối dễ nhất.
- Prompt caching là đòn bẩy lớn nhất, rủi ro thấp nhất — tiết kiệm 70-90% chi phí input cho system prompt dài.
- Model cascade (Haiku → Sonnet → Opus) tính chi phí kỳ vọng, không chi phí tối đa — gate calibration là phần khó nhất.
- Break-even với human baseline (15tr VND/tháng ≈ $600) là cách nhanh nhất giúp sếp hiểu giá trị đầu tư — đừng chỉ đưa con số USD trần trụi.
Kiểm tra hiểu biết
Công thức $/task gần đúng cho LLM là gì? (giả sử không có cache)