Cache thông thường khớp key chính xác, nên "thủ đô VN?" và "Việt Nam có thủ đô gì?" là hai key khác nhau dù cùng một ý. Semantic cache embed câu hỏi thành vector, tìm câu đã hỏi gần giống, đủ giống thì trả luôn câu trả lời cũ.
Với bot hỏi đáp hoặc hỗ trợ khách hàng, tỉ lệ trúng thực tế thường rơi vào khoảng 20–40% — giảm được đúng chừng đó chi phí và độ trễ.
THRESHOLD = 0.92 # ngưỡng cosine similarity
def cached_llm(query: str) -> tuple[str, bool]:
vec = embed(query)
hits = qdrant.search(collection_name=CACHE, query_vector=vec, limit=1)
if hits and hits[0].score >= THRESHOLD:
return hits[0].payload["response"], True # trúng cache
answer = call_llm(query)
qdrant.upsert(collection_name=CACHE, points=[PointStruct(
id=stable_id(query), vector=vec,
payload={"query": query, "response": answer,
"expires_at": iso(now() + timedelta(hours=24))},
)])
return answer, FalseBốn thứ quyết định cache này an toàn hay gây hoạ:
- Đừng cache nội dung gắn với một người dùng cụ thể. "Phí chuyển khoản bao nhiêu?" thì cache được; "số dư của tôi bao nhiêu?" thì tuyệt đối không — trả nhầm câu trả lời của người khác là sự cố dữ liệu, không phải vấn đề hiệu năng. Phải phân loại trước khi lưu, và tách namespace theo tenant.
- Ngưỡng tương đồng phải đo, đừng đoán. Trên 0,95 thì ít trúng nhưng chắc; quanh 0,85 thì trúng nhiều nhưng bắt đầu trả nhầm cho hai câu chỉ nghe giống nhau. Cách chỉnh đúng: lấy 100 truy vấn thật, xem tay xem các ca trúng cache có thực sự đúng không, rồi mới chốt.
- TTL là bắt buộc với nội dung có thời hạn — giá cả, tỉ giá, tồn kho, chính sách. Không có TTL thì cache biến thành nguồn phát tán thông tin cũ.
- Invalidate cache khi nguồn thay đổi. Cập nhật tài liệu mà cache vẫn giữ câu trả lời cũ thì công cập nhật thành vô ích. Gắn thẻ phiên bản nguồn vào bản ghi cache.
Không hợp để cache: hội thoại nhiều lượt (câu trả lời phụ thuộc lịch sử nên khớp theo một câu là sai), nội dung cá nhân hoá, và việc mang tính sáng tạo — người dùng nhờ viết email hai lần mà nhận đúng một kết quả sẽ thấy hỏng.
Lưu ý tuân thủ: bản ghi cache là dữ liệu lưu trữ, nên phải quét PII và mã hoá như mọi kho dữ liệu khác.
Công cụ: GPTCache thay được thẳng client OpenAI nếu muốn nhanh; Redis có sẵn vector search; các gateway như Portkey, Helicone cung cấp semantic cache ở tầng hạ tầng.
Thứ tự nên làm: bật theo dõi chi phí trước, biết truy vấn nào lặp nhiều rồi mới bật cache, sau đó chỉnh ngưỡng theo số liệu thật. Bật mù thì không biết mình tiết kiệm được bao nhiêu và trả nhầm bao nhiêu.