Skip to main content
BlogAI

Semantic Caching untuk LLM: Hemat Biaya Pertanyaan Berulang

Sebagian besar trafik chatbot adalah pertanyaan yang sama dengan kata-kata berbeda. Semantic caching menangkap kemiripan itu dan melewati panggilan model sepenuhnya.

Matthews Wong

Software Engineer

Juli 20269 menit baca
Semantic Caching untuk LLM: Hemat Biaya Pertanyaan Berulang

Foto oleh PantheraLeo1359531 on Wikimedia Commons

Amati analitik chatbot produksi mana pun selama seminggu dan sebuah pola akan terlihat jelas: sekelompok kecil pertanyaan menyumbang sebagian besar trafik, dan hampir tidak ada yang ditulis dengan kata-kata identik. Pengguna bertanya apa kebijakan pengembalian dana, lalu bagaimana jika saya ingin uang saya kembali, lalu apakah saya bisa dapat refund. Tiga kalimat berbeda, satu maksud yang sama, tiga panggilan model penuh dengan biaya penuh.

Exact-match caching tidak bisa melihat pola ini. Ia melakukan hashing terhadap string prompt secara literal, sehingga perubahan kata, tanda baca, atau urutan kata langsung dianggap cache miss. Semantic caching mengatasi masalah ini dengan membandingkan makna, bukan karakter, menggunakan vektor embedding dan ambang batas kemiripan untuk memutuskan kapan jawaban tersimpan cukup mirip untuk digunakan kembali. Artikel ini membahas cara kerjanya, cara menentukan ambang batas, cara melakukan invalidasi entri yang basi, dan kapan teknik ini lebih unggul dibanding exact-match prompt caching bawaan penyedia seperti Anthropic dan Amazon Bedrock.

Exact match versus semantic match

Prompt caching sisi penyedia, seperti yang disediakan secara native oleh Anthropic dan Amazon Bedrock, bekerja pada prefix yang identik byte demi byte. Ini sangat efektif untuk konteks panjang dan statis seperti system prompt, dokumen, atau skema tool yang berulang di setiap giliran percakapan, karena penyedia layanan cukup melewati perhitungan ulang status attention untuk prefix yang persis sama itu. Namun ia tidak berbuat apa-apa untuk bagian pertanyaan pengguna yang sesungguhnya, karena bagian itu memang berubah di setiap permintaan. Semantic caching menyasar tepat pada celah tersebut, yaitu bagian bahasa alami yang variatif dari permintaan yang tidak bisa disentuh oleh cache milik penyedia.

  • Exact-match caching mengandalkan hash dari teks literal, sehingga satu spasi tambahan atau kalimat yang ditulis ulang langsung menjadi cache miss penuh.
  • Semantic caching mengandalkan vektor embedding, sehingga parafrasa, salah ketik, dan susunan kata yang berbeda masih bisa terdeteksi sebagai hit.
  • Keduanya saling melengkapi, bukan bersaing: gunakan prompt caching bawaan penyedia untuk prefix yang statis, dan semantic cache untuk bagian pertanyaan yang variatif di atasnya.

Bagaimana pencarian ini sebenarnya bekerja

Mekanismenya sederhana meskipun manfaatnya besar. Setiap kueri yang masuk diubah menjadi vektor embedding berpanjang tetap menggunakan model embedding yang kecil dan murah, lalu dibandingkan dengan vektor kueri yang tersimpan sebelumnya menggunakan cosine similarity, yang mengukur sudut antara dua vektor, bukan jarak mentahnya. Jika vektor tersimpan yang paling dekat melewati ambang batas kemiripan, jawaban yang tersimpan langsung dikembalikan dalam hitungan milidetik dan permintaan tidak pernah menyentuh model bahasa. Jika tidak ada yang melewati ambang batas, permintaan diteruskan ke model seperti biasa, lalu kueri baru, embeddingnya, dan jawaban segar tersebut ditulis kembali ke dalam cache untuk digunakan berikutnya. Di balik layar, sebagian besar penerapan produksi tidak melakukan pemindaian brute-force ke setiap vektor tersimpan. Mereka mengandalkan indeks tetangga terdekat aproksimasi, umumnya graf HNSW atau struktur berbasis IVF, sehingga pencarian tetap berada di kisaran milidetik meskipun ada jutaan entri tersimpan. Redis, Postgres dengan pgvector, dan basis data vektor terkelola semuanya mendukung pola ini, dan pemilihan indeks lebih banyak bergantung pada apa yang sudah dioperasikan tim Anda daripada performa mentah, karena perbedaannya baru terasa pada skala yang sangat besar.

# Read-through semantic cache lookup (pseudocode)
def handle_query(user_message: str) -> dict:
    query_vec = embed(user_message)                # e.g. 1024-d model
    hit = vector_store.search(query_vec, k=3)       # cosine distance index

    if hit and hit.score >= SIMILARITY_THRESHOLD:   # e.g. 0.85
        return {"response": hit.answer, "source": "cache"}

    answer = call_llm(user_message)                 # cache miss -> real call
    vector_store.upsert(query_vec, answer, ttl=86400)
    return {"response": answer, "source": "llm"}

Simpan versi model embedding bersama setiap entri cache. Jika suatu saat Anda mengganti model embedding, vektor lama tidak bisa dibandingkan dengan vektor baru dan setiap entri harus dihitung ulang, bukan hanya dibaca ulang.

Menentukan ambang batas kemiripan

Ambang batas adalah satu-satunya pengaturan yang menentukan apakah cache Anda menghemat biaya atau justru menyajikan jawaban yang salah. Terlalu rendah, pertanyaan yang tidak berkaitan mulai mengembalikan jawaban satu sama lain, yang lebih buruk daripada cache miss karena pengguna mendapat informasi yang salah dengan penuh keyakinan tanpa sinyal kesalahan. Terlalu tinggi, Anda hampir tidak memperoleh peningkatan dibanding exact-match caching, karena hanya frasa yang hampir identik yang lolos. Implementasi yang dipublikasikan cenderung berkumpul pada rentang sempit: cosine similarity sekitar 0,8 hingga 0,85 menjadi titik awal umum untuk tanya jawab umum, mengetat menuju 0,9 atau lebih tinggi untuk konten yang jawabannya salah bisa berdampak nyata, seperti harga, kelayakan refund, atau konten medis maupun hukum.

Rentang ambang batasKasus penggunaan umumProfil risiko
0,60 hingga 0,75Pengelompokan topik luas, saran pencarian internalRisiko false-hit tinggi, hindari untuk jawaban langsung
0,80 hingga 0,88FAQ umum dan chatbot dukungan pelangganSeimbang, perlu pemantauan dan umpan balik
0,90 ke atasJawaban harga, kepatuhan, medis, atau hukumRisiko false-hit rendah, hit rate lebih rendah

Jangan menentukan ambang batas sekali lalu melupakannya. Perilaku model embedding bisa bergeser antar versi, dan ambang batas yang dikalibrasi untuk satu model bisa diam-diam menghasilkan false hit setelah pembaruan. Validasi ulang menggunakan set kueri berlabel setiap kali Anda mengganti model embedding.

Invalidasi cache, bagian yang sering dilewatkan semua orang

Semantic cache yang tidak pernah kedaluwarsa adalah beban, bukan fitur, karena dunia di balik jawaban yang tersimpan terus berubah meskipun pertanyaannya tetap sama. Bangun mekanisme invalidasi sejak hari pertama, bukan sebagai tugas tambahan belakangan.

  1. Lekatkan time-to-live pada setiap entri. Rentang beberapa jam hingga satu hari cukup untuk sebagian besar konten dukungan; pertanyaan tentang harga dan stok butuh jendela waktu yang jauh lebih pendek, kadang hanya beberapa menit.
  2. Lakukan invalidasi berdasarkan tag atau namespace saat sumber datanya berubah. Jika dokumen kebijakan diperbarui, hapus setiap entri cache yang bertanda dokumen tersebut daripada menunggu TTL masing-masing habis satu per satu.
  3. Beri versi pada ruang kunci cache setiap kali system prompt, model, atau model embedding berubah, agar entri lama tidak bocor ke konfigurasi baru.
  4. Catat setiap cache hit beserta skor kemiripannya. Lonjakan tiba-tiba pada skor yang mengumpul tepat di garis ambang batas adalah tanda peringatan dini bahwa cache sedang dipaksakan terlalu jauh.

Di mana semantic caching membuahkan hasil, dan di mana tidak

Teknik ini bukan peningkatan universal. Ia unggul pada pola trafik tertentu dan justru bisa merugikan pada pola lainnya.

  • Target bernilai tinggi: bot dukungan pelanggan dan FAQ, asisten pengetahuan internal, serta chatbot apa pun yang menangani sekelompok kecil maksud yang sama dari banyak pengguna dengan banyak variasi kalimat berbeda.
  • Kurang cocok: penulisan kreatif, pembuatan kode, atau beban kerja apa pun di mana setiap permintaan benar-benar baru, karena tidak ada yang bisa digunakan ulang dan pencarian embedding hanya menambah latensi tanpa manfaat.
  • Berisiko tanpa perhatian ekstra: hal apa pun di mana jawaban yang basi atau kira-kira benar menimbulkan kerugian nyata, seperti panduan finansial, medis, atau hukum, kecuali ambang batas diatur sangat konservatif dan dipadukan dengan invalidasi yang ketat.

Tim yang melaporkan penghematan terbesar hampir selalu memadukan semantic caching dengan normalisasi kueri dasar terlebih dahulu, yaitu mengubah ke huruf kecil, menghapus spasi berlebih, dan membuang kata pengisi sebelum di-embed. Satu langkah itu saja seringkali menaikkan hit rate lebih banyak daripada perubahan ambang batas apa pun.

Daftar periksa implementasi minimal

Jika Anda menambahkan ini ke chatbot atau pipeline RAG yang sudah ada, versi paling minimal membutuhkan empat komponen: model embedding yang sudah Anda percaya, indeks vektor yang mendukung pencarian tetangga terdekat aproksimasi dengan skor kemiripan yang dikembalikan bersama setiap hit, ambang batas yang telah Anda validasi terhadap set kueri nyata berlabel, bukan sekadar tebakan, serta jalur TTL dan invalidasi yang terikat pada konten apa pun yang menjadi dasar jawaban tersebut. Mulailah dengan ambang batas yang konservatif, ukur hit rate dan false-hit rate secara terpisah menggunakan umpan balik yang tercatat, dan longgarkan ambang batas secara bertahap daripada mulai longgar lalu mengetat setelah terjadi insiden. Pantau tiga angka sejak minggu pertama: cache hit rate, estimasi penghematan biaya per hari berdasarkan harga per token model, dan sampel hit yang ditinjau secara manual untuk menangkap false positive yang tidak bisa terlihat oleh logging otomatis Anda sendiri. Sebagian besar tim menemukan penghematan nyata pertama dalam hitungan hari, dan penghematan tambahan terbesar setelah itu datang dari normalisasi kueri dan penyetelan ambang batas, bukan dari mengganti model embedding atau basis data vektor.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa itu semantic caching untuk LLM?

Semantic caching menyimpan vektor embedding bersama setiap pasangan pertanyaan dan jawaban yang di-cache, lalu membandingkan embedding kueri baru dengan vektor-vektor tersimpan itu menggunakan cosine similarity. Jika kueri tersimpan cukup dekat dengan kueri baru, jawaban yang tersimpan dikembalikan tanpa perlu memanggil model lagi. Ini memungkinkan pertanyaan dengan kata-kata berbeda namun makna sama berbagi satu respons cache yang sama.

Apa bedanya semantic caching dengan prompt caching?

Prompt caching, seperti yang dibangun ke dalam Anthropic dan Amazon Bedrock, mencocokkan prefix yang identik byte demi byte seperti system prompt atau dokumen yang berulang, lalu melewati perhitungan ulang bagian tersebut. Semantic caching mencocokkan berdasarkan makna, bukan teks persis, sehingga bisa menangkap pertanyaan pengguna yang diparafrasakan yang tidak bisa dilihat oleh prompt caching. Kedua teknik ini menyasar bagian request yang berbeda dan bekerja baik jika digabungkan.

Bagaimana cara memilih ambang batas kemiripan untuk semantic cache?

Mulailah dengan konservatif, sekitar 0,85 hingga 0,9 cosine similarity, dan validasikan terhadap set kueri pengguna nyata berlabel sebelum melonggarkannya. Ambang batas yang lebih rendah meningkatkan hit rate tetapi juga meningkatkan kemungkinan mengembalikan jawaban untuk pertanyaan yang sebenarnya tidak ditanyakan pengguna. Konten yang jawabannya salah bisa berdampak nyata, seperti harga atau kepatuhan, sebaiknya menggunakan ambang batas lebih tinggi dibanding trafik FAQ umum.

Bisakah semantic caching mengembalikan jawaban yang salah?

Ya, ini disebut false hit dan menjadi risiko utama teknik ini. Hal ini terjadi ketika dua pertanyaan memiliki embedding yang berdekatan meskipun maksudnya berbeda secara signifikan, dan ambang batasnya cukup longgar untuk menganggap keduanya cocok. Mitigasinya adalah menetapkan ambang batas yang konservatif, mencatat skor kemiripan pada setiap hit, dan memvalidasi ulang ambang batas setiap kali model embedding diganti.

Kapan sebaiknya saya tidak menggunakan semantic caching?

Hindari untuk beban kerja di mana setiap permintaan benar-benar baru, seperti penulisan kreatif atau pembuatan kode, karena tidak ada yang bisa digunakan ulang dan pencarian embedding hanya menambah latensi. Berhati-hatilah juga pada domain berisiko tinggi seperti saran medis atau hukum kecuali ambang batas diatur sangat konservatif dan dipadukan dengan invalidasi cache yang ketat, karena jawaban yang basi atau kira-kira benar di sana bisa menimbulkan kerugian nyata.