Một người dùng báo cáo rằng plugin dịch thuật của chúng tôi trả về cùng một kết quả được lưu trong cache cho mọi yêu cầu, bất kể đầu vào là gì. Chúng tôi đã điều tra và phát hiện một vấn đề tồi tệ hơn: 95% tất cả các lượt truy cập semantic cache trên nền tảng của chúng tôi là dương tính giả (false positive). 199 yêu cầu dịch thuật khác nhau, 198 nội dung yêu cầu riêng biệt, nhưng chỉ một phản hồi duy nhất từ cache được phục vụ cho tất cả.
Nếu bạn quan tâm đến trạng thái agent lâu dài và xử lý yêu cầu trong môi trường production, bài viết này rất phù hợp để đọc cùng với Tại sao AI Agent của bạn liên tục mất trí nhớ, hướng dẫn về chatbot dùng một khóa API, và hướng dẫn giới hạn tốc độ AI API.
Các điểm chính
- 95% các lượt truy cập semantic cache trên nền tảng là dương tính giả, với 198 yêu cầu riêng biệt đều nhận được cùng một phản hồi từ cache.
- Nguyên nhân gốc rễ là đầu vào có cấu trúc. Văn bản mẫu cố định chiếm ưu thế trong vector embedding, khiến nội dung thay đổi hầu như không làm thay đổi độ tương đồng cosine.
- Việc nâng ngưỡng tương đồng không giải quyết được vấn đề này, vì phân phối của các lượt truy cập đúng và sai bị chồng lấp. Các nghiên cứu gần đây về độ tin cậy của semantic cache cũng xác nhận mô hình tương tự.
- Giải pháp thực hiện qua hai lớp: trích xuất nội dung có ý nghĩa trước khi embedding, sau đó xác minh từng lượt truy cập bằng mã băm vân tay FNV-1a nhanh. Điều này đã giảm tỷ lệ dương tính giả từ khoảng 95% xuống dưới 5%.
- Việc chọn model ảnh hưởng đến mức độ rủi ro. Các system prompt dài và đầu vào được bao bọc trong JSON làm vấn đề trở nên tồi tệ hơn bất kể model nào thực hiện hoàn thiện (completion); hãy kiểm tra danh mục model của TokenLab (quan sát ngày 07/07/2026) để biết các tùy chọn model hiện tại nếu bạn đang quyết định chọn model nào để định tuyến lưu lượng truy cập qua cache.
Báo cáo lỗi
Báo cáo rất đơn giản: "Tôi đã tắt semantic cache, nhưng mọi bản dịch vẫn trả về cùng một kết quả."
Ba ID yêu cầu, ba phân đoạn dịch thuật khác nhau, nhưng phản hồi từ cache lại giống hệt nhau. Nội dung yêu cầu dao động từ 1.564 đến 8.676 byte. ID phản hồi từ cache giống nhau trên tất cả các yêu cầu: chatcmpl-DG6J03nhdvcF7Ek0C8rJkjh7lN9pF.
Nghi ngờ đầu tiên: cài đặt cache của người dùng không được áp dụng. Hóa ra đó là một lỗi đồng bộ hóa nguồn dữ liệu riêng biệt (bảng điều khiển quản trị ghi vào một bảng, cổng API đọc từ một bảng khác). Việc sửa lỗi đó chỉ giải quyết được một nửa vấn đề. Ngay cả khi cache được bật và hoạt động chính xác, semantic cache vẫn khớp các yêu cầu không bao giờ nên khớp.
Dữ liệu thực tế (Production)
Chúng tôi đã lấy dữ liệu truy cập cache trong 24 giờ từ ClickHouse. Các con số rất tệ.
| Model | Tổng yêu cầu | Lượt truy cập Cache | Yêu cầu duy nhất | Phản hồi duy nhất | Tỷ lệ truy cập |
|---|---|---|---|---|---|
| DeepSeek V4 Flash | 200 | 199 | 198 | 1 | 99.5% |
| glm-4.6-thinking | 100 | 38 | 13 | 1 | 38% |
| gpt-5-nano | 31 | 29 | 28 | 2 | 93.5% |
| gpt-oss-120b | 18 | 17 | 17 | 1 | 94.4% |
| qwen3-vl-flash | 17 | 16 | 16 | 1 | 94.1% |
198 yêu cầu dịch thuật riêng biệt, tất cả đều trả về cùng một phản hồi từ cache. Đó không phải là cache. Đó là một hàm bị lỗi luôn trả về một hằng số.
Mọi model bị ảnh hưởng đều có chung hai đặc điểm: tất cả yêu cầu đến từ một người dùng duy nhất và tất cả đều sử dụng một mẫu system prompt cố định với nội dung người dùng thay đổi. Để có danh sách các model hiện có trên nền tảng, danh mục model của TokenLab (quan sát ngày 07/07/2026) là nguồn thông tin chính xác vì danh sách thay đổi thường xuyên.
Cách phát hiện vấn đề này trong hệ thống của bạn
Bạn không cần nhật ký của chúng tôi để biết liệu mình có gặp vấn đề tương tự hay không. Tín hiệu nhanh nhất là sự đa dạng phản hồi trên mỗi model. Nếu một model có tỷ lệ truy cập cache cao nhưng hầu như không có phản hồi duy nhất nào, bạn đang phục vụ một câu trả lời cho nhiều câu hỏi khác nhau.
Đây là truy vấn kiểu ClickHouse mà chúng tôi đã sử dụng, đã được tổng quát hóa:
SELECT
model,
count() AS total_hits,
uniqExact(substring(response_body, 1, 200)) AS unique_responses,
round(uniqExact(substring(response_body, 1, 200)) / count(), 3) AS diversity_ratio
FROM request_logs
WHERE cache_hit = true
GROUP BY model
ORDER BY total_hits DESC;
Một bộ cache khỏe mạnh có diversity_ratio gần bằng 1.0, nghĩa là hầu hết các lượt truy cập trả về phản hồi riêng biệt cho các đầu vào riêng biệt. Tỷ lệ gần bằng 0 nghĩa là nhiều yêu cầu bị gộp vào một vài câu trả lời được lưu trong cache. Bất kỳ tỷ lệ nào dưới 0,5 trên một model có sự đa dạng đầu vào thực tế đều đáng để điều tra.
Nếu bạn không ghi nhật ký nội dung phản hồi, một proxy rẻ hơn cũng có tác dụng: so sánh số lượng nội dung yêu cầu duy nhất với số lượng phản hồi duy nhất được phục vụ từ cache. Khi 198 yêu cầu duy nhất ánh xạ tới 1 phản hồi, cache không khớp về ý nghĩa, nó đang khớp với các đoạn văn bản mẫu (boilerplate).
Dấu hiệu thứ hai là các khiếu nại của người dùng tập trung vào các khối lượng công việc có cấu trúc. Các plugin dịch thuật, công cụ tóm tắt, điền biểu mẫu và các công cụ JSON-in/JSON-out là những đối tượng thường gặp vì chúng bao bọc nội dung thay đổi trong một mẫu cố định.
Tại sao Embeddings thất bại với đầu vào có cấu trúc
Plugin dịch thuật gửi các yêu cầu như sau:
System: "Hãy đóng vai trò là API dịch thuật. Chỉ xuất ra một đối tượng JSON thô duy nhất.
Input: {"targetLanguage":"<lang>","title":"...","segments":[...]}"
User: {"targetLanguage":"zh","title":"Trang sản phẩm",
"description":"Dịch mô tả sản phẩm",
"tone":"trang trọng",
"segments":[{"text":"nội dung thay đổi thực tế ở đây"}]}
System prompt giống hệt nhau trên tất cả các yêu cầu. Tin nhắn người dùng là một đối tượng JSON trong đó targetLanguage, title, description và tone là cố định. Chỉ có segments[].text thay đổi.
Khi semantic cache của chúng tôi trích xuất văn bản để embedding, nó nối system prompt và tin nhắn người dùng lại với nhau. Mẫu cố định chiếm khoảng 80% văn bản. Model embedding (all-mpnet-base-v2, 768 chiều) nén điều này thành một vector nơi cấu trúc mẫu chiếm ưu thế. Nội dung dịch thuật thực tế hầu như không làm thay đổi kết quả.
Kết quả: độ tương đồng cosine giữa "dịch 'Hello world'" và "dịch 'Báo cáo tài chính quý cho thấy doanh thu tăng 15%'" vượt quá 0,95. Ngưỡng của chúng tôi là 0,95. Mọi yêu cầu dịch thuật đều khớp với mục được lưu trong cache đầu tiên.
Đào sâu vào nhật ký, chúng tôi tìm thấy ba cách mà điều này gây lỗi:
Plugin dịch thuật là thủ phạm tồi tệ nhất. Các khóa và giá trị JSON cố định lấn át các phân đoạn dịch thuật thực tế. Cả DeepSeek V4 Flash và gpt-5-nano đều gặp lỗi này.
Một trợ lý tóm tắt ngữ cảnh có một biến thể khác của cùng vấn đề. System prompt của nó dài đến mức nội dung người dùng, từ 5KB đến 47KB, hầu như không được ghi nhận trong embedding. Đó là lý do tại sao glm-4.6-thinking lại trả về cùng một bản tóm tắt cho mọi cuộc trò chuyện.
Mô hình thứ ba tinh vi hơn. Đối với gpt-oss-120b và qwen3-vl-flash, 500 ký tự đầu tiên của mọi yêu cầu đều giống hệt nhau từng byte. Nội dung thay đổi xuất hiện sau đó, nhưng embedding đã bị chiếm ưu thế bởi tiền tố dùng chung.
Nghiên cứu nói gì
Đây không phải là vấn đề mới lạ. Các bài báo gần đây đã định lượng được nó.
Dự án vCache của UC Berkeley nhận thấy rằng phân phối độ tương đồng của các lượt truy cập cache đúng và sai bị chồng lấp rất nhiều, nghĩa là không có ngưỡng cố định nào tách biệt rõ ràng một kết quả khớp đúng với một kết quả sai nhưng có cấu trúc tương tự. Phát hiện đó khớp chính xác với những gì chúng tôi thấy trong môi trường production: các dương tính giả của plugin dịch thuật tập trung trên 0,95, nằm ngay trong phạm vi mà các kết quả khớp diễn giải hợp lệ cũng tồn tại.
Các công trình nghiên cứu gần đây khác về độ tin cậy của semantic caching cũng đi đến kết luận tương tự: độ tương đồng embedding thô là một tín hiệu cần thiết nhưng không đủ cho tính chính xác của cache, và bất kỳ hệ thống production nào chỉ dựa vào nó đều nên dự đoán một tỷ lệ dương tính giả đáng kể trên lưu lượng truy cập có cấu trúc, nặng về mẫu.
Giải pháp hai lớp
Lớp 1 là trích xuất nội dung. Trước khi embedding, hãy loại bỏ system prompt cố định và các phần khung mẫu, chỉ embedding phần payload thay đổi: nội dung segments[].text thực tế, không phải các khóa JSON xung quanh và boilerplate. Chỉ riêng điều này đã làm tăng đáng kể tỷ lệ tín hiệu trên nhiễu trong vector embedding.
Lớp 2 là xác minh vân tay. Ngay cả với việc trích xuất tốt hơn, nội dung gần như trùng lặp vẫn có thể tạo ra điểm tương đồng cao. Trước khi phục vụ một lượt truy cập cache, hãy tính toán một mã băm nhanh (chúng tôi đã sử dụng FNV-1a) trên nội dung đã trích xuất của cả yêu cầu đến và mục đã lưu trong cache. Nếu các mã băm khớp chính xác, hãy phục vụ cache. Nếu không, hãy chuyển sang thực hiện hoàn thiện mới hoặc, đối với lưu lượng truy cập có giá trị cao hơn, hãy định tuyến đến một cuộc gọi xác minh giá rẻ để chấm điểm ý nghĩa, không phải byte.
Sai lầm là bỏ qua hoàn toàn việc xác minh và tin tưởng vào độ tương đồng cosine thô. Mọi cách tiếp cận trong bảng đều tốt hơn cách đó. Hãy bắt đầu với cách rẻ nhất phù hợp với loại truy vấn của bạn và chỉ tiến lên nấc thang cao hơn khi bạn đo lường được các trường hợp bỏ lỡ diễn giải thực tế.
Cùng với nhau, hai lớp này đã giảm tỷ lệ dương tính giả của chúng tôi từ khoảng 95% xuống dưới 5% trong lưu lượng truy cập bị ảnh hưởng.
Khi nào Semantic Caching là công cụ sai lầm
Caching không phải là kỹ thuật miễn phí, và một số khối lượng công việc không đáng để cache chút nào.
- Lưu lượng truy cập có độ đa dạng cao, độ lặp lại thấp. Nếu hầu như mọi yêu cầu đều là duy nhất, ví dụ như tạo nội dung sáng tạo một lần, tỷ lệ truy cập là quá thấp để biện minh cho chi phí embedding. Bạn trả tiền để embedding mọi thứ nhưng hiếm khi thu lại được lợi ích.
- Các đầu ra cần phải mới. Bất cứ thứ gì nhạy cảm với thời gian, dữ liệu trực tiếp, kết quả cá nhân hóa, bất cứ thứ gì có chữ "hôm nay" trong đó, đều có thể trả về câu trả lời cũ từ cache ngay cả khi kết quả khớp về mặt kỹ thuật là đúng. Câu trả lời đúng một giờ trước nhưng sai bây giờ.
- Các lĩnh vực yêu cầu độ chính xác nghiêm ngặt. Đối với các câu trả lời về y tế, pháp lý hoặc tài chính, một dương tính giả duy nhất có thể tồi tệ hơn chi phí mà nó tiết kiệm được. Nếu bạn cache ở đây, lớp xác minh là bắt buộc, không phải tùy chọn, và kiểm tra ở cấp độ LLM có thể là cách duy nhất có thể chấp nhận được.
- Các prompt nhỏ nơi cuộc gọi model vốn đã rẻ. Embedding, tìm kiếm tương đồng và xác minh đều có chi phí riêng. Nếu việc hoàn thiện cơ bản chỉ là vài trăm token trên một model rẻ tiền, caching có thể tốn kém hơn là tiết kiệm.
Caching tỏa sáng trên các công việc hoàn thiện lặp đi lặp lại, nặng về mẫu, đắt đỏ, chính xác là những khối lượng công việc mà dương tính giả cũng dễ dàng xuất hiện nhất. Sự căng thẳng đó là lý do tại sao lớp xác minh lại quan trọng. Nếu mục tiêu của bạn chủ yếu là kiểm soát chi phí, bạn cũng nên kết hợp caching với định tuyến model rẻ hơn. So sánh giá và hướng dẫn các model AI tốt nhất cho lập trình bao gồm nơi thực sự tiết kiệm chi phí trên mỗi token, và danh mục model của TokenLab (quan sát ngày 07/07/2026) hiển thị các tùy chọn hiện tại, bao gồm các lựa chọn định tuyến chi phí thấp như DeepSeek V4 Flash và Gemini 3.5 Flash, nếu bạn đang cân nhắc model nào để định tuyến lưu lượng truy cập qua cache so với không qua cache. Hãy xác minh giá hiện tại trên danh mục được liên kết trước khi cam kết với một kế hoạch định tuyến.
Tại sao không chỉ nâng ngưỡng?
Ngưỡng của chúng tôi đã là 0,95. Nâng nó lên không giúp ích gì. Vấn đề là các đầu vào tương tự về cấu trúc tạo ra điểm tương đồng trên 0,95 bất kể nội dung thực tế nói gì.
Dữ liệu của vCache hỗ trợ điều này: phân phối độ tương đồng của các lượt truy cập đúng và sai chồng lấp nhiều đến mức không có điểm cắt nào tách biệt chúng. Đẩy ngưỡng lên 0,99 và bạn sẽ loại bỏ các lượt truy cập cache hợp lệ cho các diễn giải chính hãng trong khi các yêu cầu giống hệt nhau về cấu trúc, như payload JSON dịch thuật của chúng tôi, vẫn sẽ tập trung trên 0,99 bất kể nội dung. Ngưỡng không phải là đòn bẩy. Đại diện đầu vào mới là đòn bẩy. Đó là lý do tại sao Lớp 1 (trích xuất nội dung) và Lớp 2 (xác minh vân tay) hoạt động trong khi việc tăng ngưỡng thì không: chúng thay đổi những gì được so sánh, không phải mức độ nghiêm ngặt của việc so sánh.
Nếu bạn đang xây dựng hoặc duy trì một semantic cache, hãy coi ngưỡng như một bộ lọc thô, không phải là sự đảm bảo về tính chính xác. Hãy kết hợp nó với trích xuất nội dung để embedding thực sự đại diện cho phần thay đổi của yêu cầu, sau đó thêm một bước xác minh giá rẻ để một kết quả khớp embedding gần đúng không bao giờ có thể âm thầm trở thành câu trả lời sai trong môi trường production.
Bắt đầu với danh mục model của TokenLab để so sánh giá và điểm chuẩn hiện tại trên các model tiên phong, lập trình và định tuyến chi phí thấp trước khi bạn kết nối lớp xác minh cache của mình. Bất kể model nào đứng sau endpoint hoàn thiện của bạn, cách tiếp cận trích xuất cộng với vân tay mới là thứ thực sự sửa lỗi dương tính giả.
Câu hỏi thường gặp
Việc nâng ngưỡng tương đồng có sửa được các dương tính giả của semantic cache không? Không. Nghiên cứu từ vCache và các nghiên cứu liên quan cho thấy phân phối lượt truy cập đúng và sai chồng lấp trên phạm vi ngưỡng, vì vậy việc đẩy điểm cắt cao hơn sẽ chặn các kết quả khớp hợp lệ mà không lọc bỏ đáng tin cậy các yêu cầu có cấu trúc tương tự nhưng khác nhau về ngữ nghĩa.
Cách rẻ nhất để xác minh một lượt truy cập semantic cache là gì? Mã băm vân tay (FNV-1a hoặc tương tự) trên nội dung có ý nghĩa đã trích xuất thêm độ trễ dưới một mili giây và miễn phí tính toán. Nó sẽ không bắt được các diễn giải, nhưng nó loại bỏ các dương tính giả chính xác như những cái được mô tả ở đây, vốn là nơi gây ra hầu hết thiệt hại trong các khối lượng công việc có cấu trúc.
Vấn đề này có phụ thuộc vào model nào thực hiện hoàn thiện không? Không, vấn đề dương tính giả nằm ở lớp embedding và khớp, không phải ở model hoàn thiện. Bất kỳ model nào đứng sau một semantic cache, cho dù đó là DeepSeek V4 Flash, glm-4.6-thinking, hay thứ gì đó mới hơn, đều sẽ bị ảnh hưởng theo cùng một cách nếu cache embedding văn bản mẫu cố định cùng với nội dung thay đổi. Kiểm tra danh mục model của TokenLab (quan sát ngày 07/07/2026) để biết tính khả dụng của model hiện tại khi quyết định model nào cần định tuyến qua đường ống được cache.
Nguồn
Giá quan sát ngày 2026-07-07
- TokenLab model directoryQuan sát ngày 2026-07-07
- Generative Caching for Structurally Similar Prompts and ResponsesQuan sát ngày 2026-07-09
- GPTCache paperQuan sát ngày 2026-07-09
- RedisVL semantic caching docsQuan sát ngày 2026-07-09
- GPTCache quick startQuan sát ngày 2026-07-09



