Tokens & Context Windows — The Hard Budget Every AI Agent Must Respect
Tokens are the atomic unit of LLM memory and cost. Learn subword tokenization, context window math, and agent budgeting before you ship.
Mọi LLM agent đều chạy trên một nguồn tài nguyên khan hiếm duy nhất: tokens. Không phải đô la, không phải giây GPU — token là đơn vị cơ bản của bộ nhớ, độ trễ, và thanh toán. Nếu bạn xây agent mà chưa nắm vững ngân sách này, bạn sẽ ship hệ thống âm thầm cắt history, bỏ tool results, hoặc đốt gấp 10 lần chi phí ước tính.
Bài này là Phần 1 của loạt Building AI Agents: nền tảng mà mọi chủ đề sau — sampling, prompting, memory, tool use — đều giả định bạn đã hiểu.
Phần 1 của loạt bài Building AI Agents. Tiếp theo:
Token là gì?
Một token là mẩu văn bản mà model đọc và ghi dưới dạng một integer ID trong vocabulary. Model không bao giờ thấy ký tự thô hay Unicode code point lúc inference — nó thấy chuỗi token ID.
"Hello, agent!" → [9906, 11, 8475, 0] (example IDs — model-specific)
Ba hệ quả cho agent engineer:
- Không thể ước lượng bằng mắt — số từ, số ký tự, và số token khác nhau, đôi khi chênh lớn.
- Mọi thứ trong prompt đều tốn token — system instructions, JSON schemas, few-shot examples, retrieved documents, prior turns, tool definitions.
- Output token dùng chung ngân sách — generation không miễn phí; nó tiêu thụ cùng context window với input.
Mental model: Coi token như ô RAM, không phải từ. Context window 128K là mảng cố định 128.000 ô. Nhét history và RAG vào, còn ít chỗ cho model suy nghĩ và trả lời.
Về tính giá và trade-off subscription vs API, xem bài AI tokens and pricing — bài này tập trung vào hệ quả kiến trúc agent.
Subword tokenization: vì sao token ≠ từ
LLM hiện đại dùng subword tokenization, phổ biến nhất là Byte Pair Encoding (BPE) hoặc biến thể byte-level. Thuật toán merge các cặp ký tự xuất hiện cùng nhau thường xuyên khi training cho đến khi vocabulary đạt kích thước mục tiêu (thường 50K–200K entries).
Trực giác trong bốn bước:
- Bắt đầu với byte hoặc ký tự đơn.
- Đếm cặp kề nhau trong corpus lớn.
- Merge cặp phổ biến nhất thành token mới.
- Lặp đến khi vocabulary đầy.
Kết quả: từ tiếng Anh phổ biến thành một token; từ hiếm tách thành mảnh tái sử dụng; chuỗi lạ fallback về byte-level.
"the" → 1 token
"tokenization" → 2 tokens ["token", "ization"]
"pneumonoultra…"→ many subword pieces
Quy tắc space đầu: Tokenizer họ GPT thường gắn whitespace vào từ sau —
" world"khác token với"world". Format prompt (newline, indent, space thừa) đổi token count mà không đổi nghĩa.
Về bảng merge BPE, byte-level fallback, và quirks theo tokenizer, xem LLM tokenization and sampling deep dive — không lặp lại nội dung internals ở đây.
Số token ≠ số từ ≠ số ký tự
Engineer thường ước lượng sai context vì dùng proxy sai.
| Proxy | Typical English prose | Why it fails for agents |
|---|---|---|
| Words ÷ 0.75 | ~1.3 tokens/word | Ignores code, JSON, URLs, non-Latin scripts |
| Chars ÷ 4 | ~4 chars/token | OK as rough heuristic; breaks on CJK, emoji, dense symbols |
| Actual tokenizer | Exact | Required for production budgets |
Ví dụ chênh lệch gây hại pipeline agent:
{"tool":"search","query":"context window budgeting","top_k":5}
Một dòng JSON đó có thể tokenize thành nhiều ID hơn câu natural language cùng độ dài ký tự — punctuation và key hiếm khi merge thành subword hiệu quả.
Base64 blob (512 chars) → often 150–200+ tokens, not ~128
UUID repeated in logs → each hyphenated segment may split
Markdown code fences → backticks + language tag add overhead
Quy tắc cho agent: luôn đo bằng tokenizer của provider (tiktoken, Anthropic SDK, v.v.) lúc tích hợp; char÷4 chỉ dùng ước lượng sơ bộ.
Đa ngôn ngữ và code: mật độ token không đều
Hiệu quả token không đồng đều giữa ngôn ngữ hay format. Vocabulary BPE phản ánh phân phối training — chủ yếu web text tiếng Anh.
| Content type | Relative token cost | Agent impact |
|---|---|---|
| English prose | Baseline (~1 token per 4 chars) | Cheap system prompts, summaries |
| Vietnamese, Thai, Arabic | 2–3× vs equivalent English | User messages + RAG in local languages inflate fast |
| Source code | 1.2–1.8× vs prose | Tool outputs dumping stack traces dominate budget |
| JSON / XML logs | 1.5–2.5× vs prose | Structured tool returns are expensive |
| Base64, hashes, binary | Very high | Never paste raw blobs into context |
English: "The agent retrieved three documents."
~8 tokens
Vietnamese equivalent meaning:
"Agent đã truy xuất ba tài liệu."
~15–20 tokens (approximate — verify with tokenizer)
Hệ quả cho agent đa ngôn ngữ:
- Cùng context window, capacity thực tế thấp hơn cho user không dùng tiếng Anh.
- Summarize trước khi inject — RAG chunk tiếng Việt nên nén mạnh trước khi ghép.
- Tool code nên trả summary có cấu trúc, không dump full file, trừ khi task cần chi tiết từng dòng.
Context window: một bucket cho input và output
Context window (context length, max tokens) là số token tối đa model xử lý trong một forward pass. Quan trọng: input token + output token ≤ window size.
┌──────────────────────────────────────────────────────────────┐
│ CONTEXT WINDOW (e.g. 128K) │
├──────────────────────────────┬───────────────────────────────┤
│ INPUT │ OUTPUT │
│ system + history + tools │ model generation │
│ + RAG + user message │ (completion) │
└──────────────────────────────┴───────────────────────────────┘
Kích thước window phổ biến production (2026):
| Tier | Tokens | Typical use |
|---|---|---|
| Small | 8K–16K | Legacy APIs, cheap classifiers |
| Standard | 32K–128K | Most agent loops, RAG Q&A |
| Long | 200K–1M | Codebase agents, document analysis |
| Extended | 1M+ | Research previews; latency/cost still scale linearly |
Hiểu lầm: “128K context” không có nghĩa paste 128K token input và expect câu trả lời 32K token. Nghĩa là chuỗi gộp phải vừa.
Demo tương tác: tokenization xấp xỉ & thanh ngân sách
Thử paste system prompt, tool result, hoặc RAG chunk bên dưới. Demo dùng heuristic client-side (tách từ + ~4 chars/token) — BPE thật sẽ khác, nhưng thanh ngân sách minh họa câu hỏi thiết kế agent: input chiếm bao nhiêu window, còn bao nhiêu cho output?.
Mở demo đầy đủ:
Cách agent phá context window
Vòng lặp agent tích lũy token nhanh hơn chat UI gợi ý. Each turn adds multiple segments:
Turn N input =
system prompt
+ tool definitions (JSON schema × N tools)
+ conversation history (all prior turns)
+ tool call arguments (model output)
+ tool results (often the largest slice)
+ retrieved documents (RAG)
+ user message
Các chế độ lỗi
| Failure | Symptom | Root cause |
|---|---|---|
| Silent truncation | Agent “forgets” early instructions | Provider drops middle or oldest messages |
| Tool amnesia | Re-queries same API | Prior tool output truncated from history |
| RAG flooding | Answers degrade, latency spikes | Top-k chunks pasted verbatim |
| Runaway generation | Input fits, output hits limit mid-JSON | No output reserve in budget |
| Cost explosion | Bill 10× estimate | Full history resent every turn |
Agent loop (simplified):
User message ──► LLM ──► tool_call(search, "…")
│
▼
search returns 50KB JSON
│
▼
Next turn input = EVERYTHING ABOVE + 50KB ◄── budget crisis
Vấn đề cộng dồn: Trong vòng ReAct, mọi turn trước được tokenize lại mỗi lần gọi trừ khi bạn implement compaction hoặc summarization. Hội thoại agent 10 turn không phải 10× một message — mà là tổng mọi turn, gửi lại lặp lại.
Chiến lược compaction sâu (summarization, memory tiers, selective recall) là Phần 5: Context Engineering & Memory.
Ngân sách token cho agent
Agent production cần chính sách ngân sách rõ ràng, không hy vọng mù.
1. Đo overhead cố định trước
Trước nội dung user, các phần này đã tiêu:
fixed_cost =
system_prompt
+ tool_definitions
+ response_format / JSON schema
+ few_shot_examples (if any)
Log fixed_cost lúc khởi động. Nếu 8K token và window 32K, bạn còn 24K cho nội dung động — không phải 32K.
2. Dành headroom cho output
Không bao giờ lấp window 100% bằng input.
max_input_tokens = context_window - reserved_output - safety_margin
Typical reserves:
reserved_output = 15–30% of window (or fixed floor, e.g. 4K)
safety_margin = 256–512 tokens (provider rounding, special tokens)
Ví dụ window 128K, reserve output 20%:
| Slice | Tokens |
|---|---|
| Total window | 128,000 |
| Reserved output (20%) | 25,600 |
| Safety margin | 512 |
| Max input budget | 101,888 |
3. Phân bổ ngân sách động theo slice
Khi biết max_input, chia cho các slice cạnh tranh:
dynamic_budget =
conversation_history (40–60%)
+ rag_context (20–40%)
+ current_user_message (5–15%)
+ tool_results_buffer (10–25%)
Điều chỉnh tỷ lệ theo loại agent: Q&A bot ưu tiên RAG; coding agent ưu tiên tool results; support bot ưu tiên history.
4. Enforce trước khi gọi API
function buildPrompt(budget) {
const layers = [
{ name: 'system', tokens: systemPrompt, priority: 0, truncatable: false },
{ name: 'tools', tokens: toolDefs, priority: 1, truncatable: false },
{ name: 'history', tokens: history, priority: 2, truncatable: true },
{ name: 'rag', tokens: ragChunks, priority: 3, truncatable: true },
{ name: 'user', tokens: userMsg, priority: 4, truncatable: false },
];
let used = 0;
const included = [];
for (const layer of layers.sort((a, b) => a.priority - b.priority)) {
if (used + layer.tokens <= budget.maxInput) {
included.push(layer);
used += layer.tokens;
} else if (layer.truncatable) {
included.push(truncate(layer, budget.maxInput - used));
break;
} else {
throw new Error(`Budget exceeded on non-truncatable layer: ${layer.name}`);
}
}
return assemble(included);
}
Priority hơn FIFO: Khi truncate, bỏ slice priority thấp, truncatable trước — thường là history cũ nhất hoặc RAG chunk score thấp, không phải system prompt.
Chi phí và latency scale theo token
Token tuyến tính cả tiền lẫn thời gian (xấp xỉ bậc một).
cost_per_turn ≈ (input_tokens × input_price) + (output_tokens × output_price)
latency ≈ f(input_tokens) + g(output_tokens) // prefill + decode
Hệ số nhân đặc thù agent:
| Pattern | Token multiplier | Why |
|---|---|---|
| Single-shot Q&A | 1× | One call, bounded RAG |
| ReAct loop (5 steps) | 3–8× | History resent each step |
| Sub-agent delegation | 2–5× per sub-agent | Parallel branches each carry full context |
| Self-reflection | 2–3× | Critique pass duplicates prior output |
Output token thường đắt gơp 2–5× input trên API thương mại — JSON tool-call dài hoặc chain-of-thought verbose ăn margin trực tiếp. Xem AI tokens and pricing cho bảng giá và tactic tối ưu.
Truncation và cơ bản compaction
Khi input vượt budget, phải bỏ cái gì đó. Provider và SDK xử lý khác nhau — đừng giả định graceful.
| Strategy | Behavior | Agent-safe? |
|---|---|---|
| Hard error | 400 context_length_exceeded | Yes — fail loud |
| Drop oldest messages | Silent removal from start | Risky — loses system context |
| Drop middle | Keep system + recent | Common default; verify per provider |
| Summarize then replace | Compress history into summary block | Best for long sessions |
| Vector recall | Store full history externally; inject relevant slices | Scales beyond window |
Compaction tối thiểu cho agent v1:
- Giới hạn kích thước tool result — truncate JSON, giữ field top-level + error summary.
- Giới hạn RAG top-k và chunk size — ngưỡng score trước khi concat.
- Rolling summary — mỗi N turn, thay turn 1…N-2 bằng summary message.
- Token counter trên hot path — reject hoặc trim trước HTTP request.
Before (turn 12, ~90K tokens):
[system][turn1][turn2]…[turn11][user]
After rolling summary (turn 12, ~35K tokens):
[system][summary_of_turns_1-9][turn10][turn11][user]
Phần 5 cover kiến trúc memory (working vs episodic vs semantic), external store, và khi summarization mất fidelity.
Checklist trước khi ship agent
- Tokenizer tích hợp đúng model + version
fixed_cost(system + tools) được log và monitor- Output reserve cấu hình (không bằng zero)
- Truncation policy rõ — thứ tự priority có tài liệu
- Tool results giới hạn size tại nguồn
- Đường đa ngôn ngữ / code test với số tokenizer thật
- Cost model tính re-tokenization multi-turn
Kết luận: Token không phải chi tiết billing — chúng là ràng buộc scheduling của agent runtime. Thiết kế vòng lặp quanh window, đo mọi slice, và dành chỗ cho model hoàn thành suy nghĩ.
Tiếp theo
Phần 2 cover sampling — model chọn token tiếp theo thế nào sau khi budget đã ghép.
Temperature, top_p, và top_k điều khiển creativity vs determinism trong agent gọi tool.
Continue to Sampling: temperature, top_p, top_k.
Loạt bài Building AI Agents
- Tokens & Context Windows (current)
- Sampling: temperature, top_p, top_k
- Prompt Engineering for Agents
- Stopping Criteria & Output Control
- Context Engineering & Memory
- Fine-tuning vs Prompting vs RAG
- Evaluating LLMs & Agents
- Choosing a Model
- Function Calling & Tool Use
- Agent Patterns: ReAct, Reflection, Planning