Tầng 10 — Production
Phân rã latency budget
Phần tiêu đề “Phân rã latency budget”Ví dụ ngân sách 800 ms p95 cho một lượt trả lời:
query normalise + rewrite 50 ms (bỏ được nếu không cần)BM25 5 msdense embed truy vấn 30 ms (network tới API embedding)ANN search 15 msrerank top-50 (cross-encoder) 60 mscontext assembly 5 msLLM generation (streaming) 600 ms (time-to-first-token là cái người dùng cảm nhận)Bài học: generation chiếm phần lớn ngân sách. Tối ưu retrieval từ 100 ms xuống 50 ms gần như không ai cảm nhận được. Nhưng streaming để giảm time-to-first-token thì cảm nhận được ngay.
Ba tầng cache, hiệu quả giảm dần
Phần tiêu đề “Ba tầng cache, hiệu quả giảm dần”- Cache embedding của truy vấn (theo hash chuỗi đã chuẩn hoá) — rẻ, tỷ lệ hit cao.
- Cache kết quả retrieval — hiệu quả nếu phân bố truy vấn lệch (thường là vậy).
- Cache câu trả lời cuối (semantic cache: truy vấn gần giống dùng lại đáp án) — tiết kiệm nhiều nhất nhưng rủi ro nhất: hai truy vấn gần nhau về embedding có thể cần đáp án khác nhau. Cần ngưỡng chặt và phải đo tỷ lệ trả sai.
Riêng với LLM: prompt caching là món rẻ nhất. Đặt phần tĩnh (system prompt, hướng dẫn) lên trước, phần động (context vừa retrieve, câu hỏi) xuống sau — vì cache là khớp tiền tố, một byte đổi ở đầu làm mất cache toàn bộ phía sau.
Freshness
Phần tiêu đề “Freshness”Full reindex là kẻ thù. Cần: index tăng trưởng (thêm/sửa/xoá theo tài liệu), phiên bản hoá chunk, và tombstone cho tài liệu đã xoá — quên tombstone là bug rò rỉ dữ liệu, không chỉ là bug chất lượng.
Observability — log gì
Phần tiêu đề “Observability — log gì”Với mỗi truy vấn: truy vấn gốc, truy vấn sau chuẩn hoá, chunk id được lấy + điểm, chunk id được đưa vào prompt, câu trả lời, phản hồi người dùng, latency từng chặng. Không có log này thì mọi cải thiện sau đây đều là đoán:
- truy vấn không có kết quả → lỗ hổng nội dung hoặc lỗi tokenizer
- truy vấn có kết quả nhưng người dùng hỏi lại → lỗi ranking
- chunk chưa bao giờ được lấy → index rác, hoặc chunking sai