03 · Context engineering — prompt caching, context rot, compaction, memory
Khi agent chạy nhiều vòng, thứ quyết định chất lượng và hoá đơn không còn là một câu prompt hay, mà là toàn bộ những gì nằm trong context ở mỗi vòng: system prompt, định nghĩa tool, lịch sử, kết quả tool, ghi chú. Bài này nói về cách quản lý "ngân sách chú ý" đó — và về một nghịch lý đo được trong lab: dọn context để tiết kiệm có thể làm hoá đơn tăng gần gấp đôi nếu không hiểu prompt cache.
Đã verify gì, chưa verify gì. Lab chạy thật: so byte tiền tố của hai request liên tiếp (PHP 8.4) để thấy các "silent invalidator" của prompt cache; mô hình chi phí 30 vòng agent theo bảng giá (Python). Mô hình chi phí là tính toán theo quy tắc giá công bố (ghi cache 1,25×, đọc cache $0,20/MTok trên Opus 5.5), không phải hoá đơn thật — chưa verify bằng API. Context rot, compaction, memory tool: dựa trên tài liệu Anthropic và báo cáo Chroma (nêu nguồn), chưa verify bằng model thật. Không có Context7 trong môi trường; dùng tài liệu tham chiếu Claude API cache 2026-09-25.
Câu trả lời 60 giây
"Context window là bộ nhớ làm việc có hạn của model: token nào cũng tranh sự chú ý với token khác, và chất lượng giảm dần khi context dài ra — kể cả khi còn xa giới hạn 1M. Tôi quản lý nó theo bốn thao tác: ghi ra ngoài (ghi chú, memory), chọn lọc (lấy đúng thứ cần qua tool/RAG khi cần), nén (compaction, dọn tool result cũ), cô lập (subagent có context riêng, trả về tóm tắt). Song song là prompt caching: cache là khớp tiền tố theo byte, nên phần ổn định phải đứng trước, phần thay đổi đứng sau. Lab của tôi cho thấy chỉ một dòng 'Bây giờ là 10:31' trong system prompt làm 98% prompt không dùng lại được cache; và dọn tool result cũ từng lượt làm phá cache liên tục, tốn gấp 1,7 lần so với không dọn — phải dọn theo lô."
Thuật ngữ
| Thuật ngữ | Nghĩa ngắn |
|---|---|
| context engineering | Thiết kế và quản lý toàn bộ token đưa vào model ở mỗi lượt, không chỉ câu prompt. |
| prompt caching | Nhà cung cấp giữ lại kết quả xử lý (KV cache) của phần đầu prompt; lần sau khớp tiền tố thì đọc lại, rẻ và nhanh hơn. |
breakpoint (cache_control) | Điểm đánh dấu "cache tới đây"; tối đa 4 điểm mỗi request. |
| context rot | Hiện tượng chất lượng giảm khi context dài ra, không chỉ khi gần giới hạn. |
| compaction | Tóm tắt phần lịch sử cũ thành một khối ngắn để tiếp tục phiên dài. |
| context editing | Xoá bớt (không tóm tắt) tool result / thinking cũ khỏi lịch sử. |
| memory | Lưu trữ ngoài context (file, DB) mà agent đọc/ghi qua tool, sống qua nhiều phiên. |
| subagent | Agent con chạy với context riêng cho một nhiệm vụ hẹp, trả về kết quả gọn cho agent cha. |
1. Bài toán gốc và bối cảnh ra đời
Thời "prompt engineering" (2022–2024), bài toán là viết một câu lệnh tốt cho một lần gọi. Khi agent chạy hàng chục đến hàng trăm vòng, context tự phình lên bởi kết quả tool, và ba giới hạn xuất hiện cùng lúc:
- Chi phí và độ trễ: mỗi vòng gửi lại toàn bộ lịch sử → input cộng dồn tăng bậc hai (lab bài 02). Prefill dài → TTFT dài.
- Chất lượng: báo cáo "Context Rot" của Chroma (7/2025) thử 18 model (có Claude 4, GPT-4.1, Gemini 2.5): độ tin cậy giảm khi input dài ra, ngay cả với tác vụ đơn giản như tìm và chép lại; nhiễu gần nghĩa (distractor) làm tệ hơn. Trước đó, "Lost in the Middle" (Liu et al., 2023) cho thấy thông tin nằm giữa context dài bị dùng kém hơn thông tin ở đầu/cuối.
- Giới hạn cứng: vượt cửa sổ là request bị từ chối.
Thuật ngữ "context engineering" phổ biến từ giữa 2025 (Tobi Lütke, Andrej Karpathy); Anthropic hệ thống hoá trong bài "Effective context engineering for AI agents" (9/2025) với ba kỹ thuật cho tác vụ dài: compaction, ghi chú có cấu trúc, và kiến trúc subagent.
Tối ưu cho: agent nhiều vòng, phiên dài, dùng lại prompt lớn. Không cần cho một lần gọi ngắn — ở đó chỉ cần prompt rõ ràng.
2. Mô hình tư duy cốt lõi
Context là RAM có hạn và đắt; mục tiêu là tập token nhỏ nhất có tín hiệu cao nhất cho bước hiện tại. Prompt cache là một tầng cache theo tiền tố đặt trước RAM đó — nó chỉ giúp khi phần đầu giữ nguyên từng byte.
flowchart TB
subgraph CTX["Context gửi mỗi lượt (thứ tự render: tools -> system -> messages)"]
T["Định nghĩa tool (ổn định)"] --> S["System prompt (ổn định)"]
S --> H["Lịch sử hội thoại (append-only, tăng dần)"]
H --> R["Tool result mới (to, sống ngắn)"]
R --> Q["Chỉ dẫn / câu hỏi lượt này (thay đổi)"]
end
M[("Memory / ghi chú ngoài context")] -.->|"đọc khi cần"| H
K[("RAG / search qua tool")] -.->|"lấy đúng đoạn cần"| R
SA["Subagent: context riêng"] -.->|"trả tóm tắt 1-2k token"| R
CP["Compaction / dọn tool result"] -.->|"nén phần cũ"| H
Hai hệ quả trái chiều nhau — chính là trọng tâm của bài:
- Muốn chất lượng và trần context tốt → nén, dọn, bỏ bớt phần cũ.
- Muốn cache hit → không được đụng vào phần đầu; mọi chỉnh sửa ở vị trí N làm mất cache từ N trở đi.
Thiết kế tốt là thiết kế mà hai lực này ít va nhau: phần ổn định ở đầu và không bao giờ đổi; phần thay đổi ở cuối; nén theo lô ở những mốc hiếm.
3. Internals và quyết định thiết kế
3.1 Prompt caching hoạt động thế nào
Nền tảng là KV cache ở bài 01: prefill một prompt tạo ra Key/Value cho từng token. Nếu request sau có cùng tiền tố, nhà cung cấp dùng lại KV đã tính. Các quy tắc (tài liệu Claude API, cache 2026-09-25):
| Quy tắc | Chi tiết | Vì sao lại thiết kế vậy |
|---|---|---|
| Khớp tiền tố theo byte | Khác 1 byte ở vị trí N → mất cache từ N trở đi | KV của token phụ thuộc mọi token trước nó |
| Thứ tự render | tools → system → messages | Đổi tool = mất toàn bộ cache |
| Breakpoint | Tối đa 4 cache_control; hoặc cache tự động ở cấp request (tự đặt ở block cuối) | Giới hạn số entry phải ghi |
| Độ dài tối thiểu | 512 token trên Opus 5.5/Sonnet 5.5; 1024–4096 trên model cũ (Haiku 4.5: 4096). Ngắn hơn thì im lặng không cache | Entry quá nhỏ không đáng quản lý |
| TTL | 5 phút (mặc định) hoặc 1 giờ; mỗi lần đọc làm mới TTL | RAM GPU/CPU của nhà cung cấp có hạn |
| Giá | Ghi: 1,25× (5 phút) hoặc 2× (1 giờ) giá input. Đọc: ~0,1× (Opus 5.5: $0,20 = 0,05×) | Ghi tốn thêm chỗ, đọc bỏ qua prefill |
| Lookback | Mỗi breakpoint dò ngược tối đa 20 vị trí để tìm entry cũ | Một lượt thêm quá 20 block sẽ miss im lặng |
| Song song | Entry chỉ đọc được sau khi request đầu bắt đầu stream | N request song song cùng tiền tố đều trả giá đầy đủ |
| Phạm vi | Tách theo workspace (Claude API), không chia sẻ giữa tổ chức | Cô lập dữ liệu |
Hoà vốn: TTL 5 phút hoà vốn từ lần đọc thứ nhất (1,25 + 0,1 = 1,35 < 2 lần giá không cache). TTL 1 giờ cần ít nhất 2 lần đọc. Chọn TTL theo khoảng cách giữa hai request cùng tiền tố: dưới 5 phút → 5 phút; 5–60 phút (người dùng trả lời chậm) → 1 giờ.
Kiểm tra cache có chạy không: đọc usage. Tổng prompt = input_tokens + cache_creation_input_tokens +
cache_read_input_tokens. Vòng lặp khoẻ mạnh: cache_read tăng dần mỗi lượt, cache_creation chỉ bằng phần vừa
thêm. Nếu cache_creation xấp xỉ toàn bộ context ở mọi lượt → có thứ gì đó đang sửa tiền tố.
3.2 Lab: "silent invalidator" — mất cache mà không có lỗi
Dựng request của lượt 1 và lượt 2 (65 giây sau) của cùng một hội thoại CSKH, render theo thứ tự API, tìm byte đầu tiên khác nhau:
A. system có giờ hiện tại request1= 4468 byte, khớp tiền tố 90 byte = 2.0% dùng lại được
B. tools lấy từ DB không ORDER BY request1= 4443 byte, khớp tiền tố 11 byte = 0.2% dùng lại được
C. system cố định, giờ đưa vào cuối messages request1= 4502 byte, khớp tiền tố 4468 byte = 99.2% dùng lại được
Cả A và B đều không báo lỗi gì — request vẫn thành công, chỉ là hoá đơn cao hơn. Những thủ phạm hay gặp trong code Laravel:
now() trong system prompt; "Xin chào {$user->name}" ở system (mỗi user một tiền tố, không chia sẻ được);
json_encode một mảng lấy từ query không ORDER BY; if ($feature) $system .= ... (mỗi tổ hợp flag một
tiền tố); tool list thay đổi theo quyền user. Cách sửa: đưa phần động xuống cuối (hoặc vào message role: "system" giữa hội
thoại — Opus 5.5 hỗ trợ, không phá cache), sắp xếp tool theo tên, giữ tool list cố định và kiểm quyền trong tool.
Anthropic có beta cache diagnostics (cache-diagnosis-2026-04-07): gửi id của response trước, API chỉ ra hai request lệch
nhau ở đâu (model, system, tools hay messages) — chưa verify.
3.3 Bốn thao tác quản lý context
| Thao tác | Kỹ thuật | Được | Mất |
|---|---|---|---|
| Ghi ra ngoài | File ghi chú/todo, memory tool (memory_20250818, client-side, thư mục /memories), bảng DB | Sống qua compaction và qua phiên; context nhỏ | Ghi chú có thể cũ/sai; là kênh bị đầu độc (prompt injection ghi vào memory) |
| Chọn lọc | RAG, search tool, "just-in-time": giữ con trỏ (đường dẫn, id), chỉ đọc nội dung khi cần | Chỉ trả tiền cho thứ liên quan | Thêm vòng gọi tool; chọn sai thì model không thấy thông tin |
| Nén | Compaction (tóm tắt), context editing (xoá tool result/thinking cũ) | Phiên dài hơn cửa sổ; bớt nhiễu | Mất chi tiết; phá cache từ điểm sửa |
| Cô lập | Subagent với context riêng, trả về 1–2k token tóm tắt | Context agent chính sạch; chạy song song | Token tổng tăng nhiều lần; mất ngữ cảnh chung (bài 05) |
Trên Claude API, ba cơ chế có sẵn (theo tài liệu, chưa verify):
- Compaction phía server (beta
compact-2026-01-12): khi gần ngưỡng (mặc định 150K token) API tự tóm tắt phần đầu thành block compaction. Bắt buộc append nguyênresponse.contentvào lịch sử — nếu chỉ lấy text, trạng thái compaction bị mất im lặng. - Context editing (beta
context-management-2025-06-27): chiến lượcclear_tool_uses_20250919xoá tool result cũ,clear_thinking_20251015xoá thinking cũ. - Memory tool: model gọi
view/create/str_replace/…trên thư mục/memories; bạn tự hiện thực lưu trữ và phải kiểm đường dẫn (chặn.., symlink) và tách thư mục theo user.
3.4 Lab: dọn context vs prompt cache — con số ngược trực giác
Mô phỏng một phiên agent 30 lượt: tiền tố 8 000 token (system + tool), mỗi lượt thêm 300 token output và 2 500 token tool result. Bốn chiến lược, tính theo bảng giá:
Phiên 30 lượt, tiền tố 8000 token, mỗi lượt +300 output +2500 tool result
model chiến lược tổng input đã gửi context đỉnh chi phí
claude-opus-5-5 không cache 1,462,500 89,350 6.030$
claude-opus-5-5 prompt cache 1,462,500 89,350 0.860$
claude-opus-5-5 cache + dọn mỗi lượt 592,020 24,870 1.462$
claude-opus-5-5 cache + dọn theo lô >60k 1,026,020 58,550 0.825$
claude-sonnet-5-5 không cache 1,462,500 89,350 3.015$
claude-sonnet-5-5 prompt cache 1,462,500 89,350 0.568$
claude-sonnet-5-5 cache + dọn mỗi lượt 592,020 24,870 0.766$
claude-sonnet-5-5 cache + dọn theo lô >60k 1,026,020 58,550 0.506$
claude-haiku-4-5 không cache 1,462,500 89,350 1.507$
claude-haiku-4-5 prompt cache 1,462,500 89,350 0.284$
claude-haiku-4-5 cache + dọn mỗi lượt 592,020 24,870 0.383$
claude-haiku-4-5 cache + dọn theo lô >60k 1,026,020 58,550 0.253$
Đọc kết quả:
- Prompt cache một mình giảm chi phí 7 lần (Opus 5.5: $6,03 → $0,86) mà không đổi gì về nội dung.
- Dọn tool result cũ mỗi lượt giảm context đỉnh 3,6 lần (tốt cho chất lượng) nhưng tăng chi phí 1,7 lần so với chỉ cache ($0,86 → $1,46): mỗi lần xoá một result ở giữa lịch sử là sửa tiền tố → phần sau phải ghi cache lại với giá 1,25×.
- Dọn theo lô (chỉ khi vượt 60k, xoá một lần nhiều result) vừa rẻ nhất vừa giữ context đỉnh dưới 60k. Đây là lý do cấu hình context editing có ngưỡng kích hoạt và lượng tối thiểu phải xoá mỗi lần (tên tham số cụ thể xem tài liệu context editing — chưa verify).
Giả định của mô hình: cache luôn còn sống (các lượt cách nhau dưới 5 phút), không có thinking token, mỗi lượt đọc được toàn bộ tiền tố đã ghi. Thực tế hit rate thấp hơn → khoảng cách giữa "không cache" và "có cache" sẽ nhỏ hơn. Mục đích là thấy hướng tác động.
3.5 Viết system prompt ở "đúng độ cao"
Hai kiểu hỏng đối xứng: quá cứng (một cây if-else dài dằng dặc trong prompt — giòn, model bám chữ, gặp tình huống ngoài danh sách là lúng túng) và quá mơ hồ ("hãy hữu ích" — không cho model tín hiệu cụ thể). Đích đến là: mô tả mục tiêu, ràng buộc cứng, cách xử lý tình huống mơ hồ, và vài ví dụ tiêu biểu (không phải danh sách mọi trường hợp). Chia phần bằng tiêu đề/thẻ XML để model và người đọc tìm được.
Progressive disclosure (tiết lộ dần) là mẫu chung của Claude Code và Agent Skills: chỉ mô tả ngắn của mỗi skill nằm sẵn trong
context; nội dung đầy đủ (SKILL.md, script) chỉ được đọc khi nhiệm vụ cần. CLAUDE.md của repo này là ví dụ của
"memory dự án" nạp sẵn — vì luôn nằm trong context, mỗi dòng trong đó phải đáng giá token của nó.
3.6 Ràng buộc mới: lịch sử phải append-only
Trên Opus 5.5, Sonnet 5.5, Fable 5.1, thinking block gắn với model và với chính hội thoại tạo ra nó ("preserved thinking"). Theo tài liệu,
sửa một lượt cũ (xoá một reminder đã chèn, viết lại một tool result) làm các thinking block phía sau mất hiệu lực; tài khoản tạo từ
31/8/2026 bị 400 khi gửi lịch sử đã sửa. Hệ quả kiến trúc: harness phải append-only; muốn "xoá" thì dùng cơ chế API cung cấp
(context editing, compaction, message system có clear_at) thay vì tự sửa mảng messages. Chưa verify bằng API thật.
4. Đảm bảo và giới hạn
| Cơ chế | Đảm bảo | Không đảm bảo |
|---|---|---|
| Prompt cache | Nếu hit: đúng kết quả như không cache (cache không làm đổi output) | Hit — có thể miss do TTL, song song, lookback, tiền tố quá ngắn; không có lỗi báo miss |
| Context window | Request vượt giới hạn bị từ chối rõ ràng | Chất lượng đều ở mọi độ dài |
| Compaction | Phiên chạy tiếp được sau ngưỡng | Giữ lại đúng chi tiết quan trọng (tóm tắt là lossy) |
| Context editing | Xoá đúng loại block đã cấu hình | Model không cần lại thứ đã xoá |
| Memory | Do bạn hiện thực → tuỳ bạn | Đúng đắn, không cũ, không bị đầu độc; không có transaction giữa nhiều agent |
Độ phức tạp: không nén thì tổng input của phiên n vòng là O(n²); nén theo lô đưa về gần O(n·C) với C là trần context mục tiêu.
5. Failure modes
| Lỗi | Hệ quả | Phát hiện | Phục hồi / phòng |
|---|---|---|---|
| Silent cache invalidation (lab 3.2) | Chi phí tăng 5–10 lần, TTFT tăng; không lỗi | cache_read_input_tokens ≈ 0 qua nhiều request; test tích hợp khẳng định request thứ 2 có cache_read > 0 | Sửa tiền tố; diff payload hai request liền nhau (bỏ cache_control trước khi diff) |
| Dọn context phá cache (lab 3.4) | Tăng chi phí dù context nhỏ đi | cache_creation lớn mỗi lượt | Dọn theo lô, ngưỡng cao |
| Compaction làm mất ràng buộc | Người dùng dặn "không đụng production" ở lượt 3, sau compaction agent quên | Eval phiên dài; kiểm tra tóm tắt có chứa các ràng buộc | Ràng buộc cứng đặt ở system/tool (hạ tầng), không để trong hội thoại; ghi chú có cấu trúc cho quyết định quan trọng |
| Context rot / lost in the middle | Bỏ sót dữ kiện có trong context | Eval với context dài + distractor | Chọn lọc chặt hơn; đặt thông tin then chốt gần cuối (gần câu hỏi) |
| Tràn cửa sổ | Request 400, phiên chết giữa chừng | Đếm token trước khi gửi | Compaction, giới hạn kích thước tool result |
| Memory cũ / sai | Agent hành động theo sự thật đã hết hạn | Ghi chú có ngày, nguồn | TTL cho memory; ưu tiên dữ liệu sống từ tool |
| Memory bị đầu độc | Prompt injection ghi chỉ dẫn độc vào memory, ảnh hưởng mọi phiên sau | Review/diff memory; tách theo user | Memory là dữ liệu không tin cậy; không cho nội dung web ghi thẳng vào memory |
| Song song không chia sẻ cache | Fan-out N worker trả N lần giá ghi | cache_creation nhân N | Gửi 1 request, chờ token đầu, rồi mới bắn N−1 |
Lab tái hiện: hai dòng đầu đã tái hiện (mục 3.2, 3.4). Các dòng còn lại cần model thật — chưa verify.
6. Vận hành trong production
- Cache hit ratio =
cache_read / (input + cache_creation + cache_read)theo route, theo ngày. Alert khi tụt đột ngột sau một lần deploy — thường là ai đó vừa thêm biến động vào system prompt. - Kích thước context p50/p95 theo lượt, số lần compaction/phiên, số lượt tới khi compaction.
- Chi phí / task tách phần ghi cache và đọc cache.
- Pre-warm khi lượt đầu nhạy độ trễ: gửi request
max_tokens: 0lúc worker khởi động để ghi cache system prompt (phải dùng cùng thinking/effort với traffic thật). Không cần nếu traffic liên tục dưới 5 phút. - Giữ một model cho vòng lặp chính: cache theo model; đổi model giữa phiên là mất sạch cache — tác vụ phụ rẻ tiền thì tách ra subagent.
- Chính sách transcript: context chứa PII của khách; quyết định thời gian lưu và ai được xem.
7. So sánh và ma trận quyết định
| Chiến lược | Chi phí | Chất lượng | Độ phức tạp | Hỏng kiểu gì | Dùng khi |
|---|---|---|---|---|---|
| Nhồi hết vào context | Cao (trừ khi cache tốt) | Tốt khi ngắn, giảm khi dài và nhiễu | Thấp | Context rot, TTFT | Tài liệu vừa phải, dùng lại nhiều lần (cache) |
| RAG trước khi hỏi | Thấp | Phụ thuộc retrieval | Trung bình (index, chunking) | Lấy sai đoạn → trả lời sai tự tin | Kho tài liệu lớn, câu hỏi độc lập (bài 04) |
| Agentic search (tool grep/search, đọc khi cần) | Trung bình (nhiều vòng) | Cao với dữ liệu có cấu trúc (code, log) | Thấp | Chậm, nhiều vòng | Codebase, dữ liệu thay đổi liên tục — cách Claude Code làm |
| Compaction | Giảm dài hạn | Mất chi tiết | Thấp nếu dùng của API | Quên ràng buộc | Phiên rất dài, liên tục |
| Context editing | Tuỳ cách dọn (lab) | Bớt nhiễu | Thấp | Phá cache nếu dọn lắt nhắt | Nhiều tool result to, dùng một lần |
| Subagent | Tổng token tăng mạnh | Context chính sạch | Cao | Mất ngữ cảnh chung, mâu thuẫn | Nhiệm vụ con độc lập, đọc nhiều (bài 05) |
| Memory ngoài | Thấp | Tốt cho kiến thức bền | Trung bình | Cũ, bị đầu độc | Sở thích người dùng, quyết định dự án qua nhiều phiên |
Mặc định hợp lý: system + tool ổn định có breakpoint riêng; cache tự động cho đuôi hội thoại; tool result giới hạn kích thước; dọn theo lô khi vượt ngưỡng; compaction của API cho phiên dài. Tránh: tự viết lại lịch sử, và nhồi hàng trăm nghìn token "cho chắc".
8. Góc nhìn tech lead: tác động tổ chức
- Context là code: system prompt, định nghĩa tool, CLAUDE.md nằm trong repo, qua review, có eval chạy khi đổi. Một PR thêm
{$now}vào system prompt có thể tăng hoá đơn gấp 5 — reviewer phải biết điều đó. - Ngân sách context là tài nguyên chung như connection pool: đặt trần kích thước tool result, số tool, độ dài system prompt; team muốn thêm phải "trả" bằng cách bớt chỗ khác hoặc chứng minh bằng eval.
- ADR mẫu: "Mọi request LLM được dựng qua
PromptBuilder: tools sắp theo tên, system không chứa dữ liệu động, dữ liệu động đi vào message cuối; CI có test khẳng định request thứ hai cócache_read > 0." - Lock-in: cơ chế cache khác nhau giữa nhà cung cấp (Anthropic: breakpoint tường minh + tự động; hãng khác: tự động theo tiền tố hoặc tạo cache object riêng). Compaction/context editing/memory tool là tính năng riêng của API. Exit strategy: logic quản lý context nằm trong harness của mình (ngưỡng, tóm tắt bằng lời gọi LLM thường) để có thể thay nếu đổi nhà cung cấp; chấp nhận mất tối ưu chi phí trong thời gian chuyển.
9. Anti-patterns và bài học thực tế
- Thời gian, tên user, request id trong system prompt (lab A).
- Tool list dựng động theo quyền user — vừa mất cache, vừa để model "không thấy" tool mà lẽ ra nên được từ chối rõ ràng.
- Tin vào "1M context" và nhồi cả knowledge base. Chroma đo được suy giảm từ rất sớm, không đợi gần giới hạn.
- Để ràng buộc an toàn trong hội thoại ("đừng xoá gì nhé") — compaction có thể làm mất; phải là quyền ở hạ tầng.
- CLAUDE.md 2 000 dòng. Nằm trong mọi phiên, tốn token, loãng chỉ dẫn. Giữ luật cứng ở đó, chi tiết chuyển thành skill/tài liệu đọc khi cần.
- Chỉ lấy
textcủa response rồi append — mất block compaction, tool_use, thinking. - Gửi N request song song cùng tiền tố lớn và ngạc nhiên vì không có cache hit.
Điều người vận hành lâu năm đều biết: lỗi cache không bao giờ tự báo. Hãy có một dashboard cache hit ratio trước khi có dashboard nào khác cho tính năng AI — nó là metric rẻ nhất phát hiện regression chi phí.
10. Câu hỏi phụ interviewer hay hỏi tiếp
- Prompt caching khác cache kết quả (response cache) thế nào?
- Prompt caching lưu kết quả xử lý đầu vào ở phía nhà cung cấp; output vẫn được sinh mới mỗi lần. Response cache (Redis theo hash câu hỏi) trả lại output cũ — chỉ đúng khi câu hỏi lặp y hệt và câu trả lời không phụ thuộc thời gian.
- Compaction hay RAG cho phiên dài?
- Khác mục đích: compaction nén lịch sử của chính phiên; RAG lấy kiến thức ngoài. Phiên dài thường cần cả hai, cộng ghi chú có cấu trúc cho quyết định quan trọng.
- Làm sao biết cache đang chạy?
- Đọc
usage.cache_read_input_tokens; có test tích hợp gửi hai request giống nhau và khẳng định lần hai đọc cache; theo dõi tỉ lệ theo route. - Subagent có tiết kiệm token không?
- Không — tổng token thường tăng. Nó tiết kiệm context của agent chính (chất lượng) và cho chạy song song (thời gian).
- Đặt thông tin quan trọng ở đâu trong prompt?
- Chỉ dẫn và ràng buộc ổn định ở system (đầu, cache được); tài liệu dài đặt trước câu hỏi; câu hỏi/nhiệm vụ cụ thể ở cuối. Tránh để dữ kiện then chốt chìm giữa một khối dài.
Phụ lục: lab đã chạy
Môi trường: PHP 8.4.19; Python 3.11.15. Output gốc: labs/ai/out/03-cache-prefix.txt,
labs/ai/out/03-context-cost.txt.
php labs/ai/php/cache_prefix.php # tìm byte đầu tiên khác nhau giữa 2 request liên tiếp
python3 labs/ai/py/context_cost.py # mô hình chi phí 30 lượt, 4 chiến lược, 3 model
Chưa verify: hit rate thật và hoá đơn thật (cần API key); compaction, context editing, memory tool, cache diagnostics, ràng buộc append-only với thinking block (lấy từ tài liệu tham chiếu API). Nguồn: Chroma, "Context Rot: How Increasing Input Tokens Impacts LLM Performance" (7/2025); Liu et al., "Lost in the Middle" (2023); Anthropic Engineering, "Effective context engineering for AI agents" (9/2025).
Bài trước: 02 · Tool use và agent loop · Bài tiếp: 04 · RAG production với pgvector.