Penyimpanan Singgahan Persis dengan Redis
Simpan respons LLM dalam singgahan dengan membuat hash dari perintah lengkap dan menyimpan hasilnya di Redis bersama TTL, sehingga permintaan identik dapat dilayani seketika tanpa panggilan API.
Penyimpanan Singgahan Persis dengan Redis adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.
Mengapa Menyimpan Respons LLM dalam Cache?
Panggilan API LLM mahal: satu permintaan GPT-4o dapat berbiaya $0.005–$0.15, bergantung pada jumlah token. Dalam banyak aplikasi, sebagian besar kueri yang masuk identik atau hampir identik dengan kueri sebelumnya—misalnya pada bot FAQ, sistem dukungan pelanggan, atau alat peninjau kode ketika pengguna berulang kali mengajukan pertanyaan yang sama. Penyimpanan dalam cache dapat menghilangkan 20–50 persen panggilan API dalam kasus penggunaan ini, sehingga langsung mengurangi biaya dan latensi.
Cache Eksak: Merancang Kunci Cache
Cache eksak menyimpan respons LLM berdasarkan hash deterministik dari input. Kunci cache harus mencakup setiap input yang memengaruhi output: array pesan, nama model, suhu, dan parameter lain yang mengubah respons. Jika salah satu unsur ini tidak dimasukkan ke dalam kunci, dapat terjadi benturan cache sehingga respons tersimpan diberikan untuk permintaan efektif yang berbeda.
import hashlib
import json
def make_cache_key(messages: list[dict], model: str, temperature: float) -> str:
# Create a canonical, order-stable representation
key_data = {
'model': model,
'temperature': temperature,
'messages': messages, # list order matters
}
# Serialize to JSON with sorted keys for determinism
serialized = json.dumps(key_data, sort_keys=True, ensure_ascii=False)
# Hash to a fixed-length key safe for Redis
return 'llm_cache:' + hashlib.sha256(serialized.encode()).hexdigest()Menghubungkan ke Redis
Redis merupakan pilihan standar untuk menyimpan respons LLM dalam cache karena latensi pembacaannya di bawah satu milidetik dan dukungan TTL bawaannya. Gunakan pustaka redis-py untuk akses sinkron atau aioredis (sekarang telah digabungkan ke redis-py sebagai redis.asyncio) untuk akses asinkron dalam aplikasi FastAPI. Simpan koneksi Redis sebagai singleton agar kumpulan koneksi tidak kehabisan kapasitas.
import redis
import redis.asyncio as aioredis
# Synchronous Redis client
r = redis.Redis(
host='localhost',
port=6379,
db=0,
decode_responses=True, # return str instead of bytes
)
# Async Redis client (for FastAPI)
async_r = aioredis.Redis(
host='localhost',
port=6379,
db=0,
decode_responses=True,
)
# Test connection
print(r.ping()) # True if Redis is runningPenerapan Pola Cache-Aside
Pola cache-aside adalah strategi standar untuk menyimpan respons API LLM dalam cache. Pada setiap permintaan: (1) hitung kunci cache, (2) periksa apakah Redis memiliki respons yang tersimpan, (3) jika ditemukan (cache hit), segera kembalikan respons tersebut, (4) jika tidak ditemukan (cache miss), panggil API LLM, (5) simpan respons di Redis dengan TTL, (6) kembalikan respons. Pola ini menjaga logika cache tetap terpisah dari pemanggilan LLM itu sendiri.
import json
from openai import OpenAI
client = OpenAI()
def cached_completion(
messages: list[dict],
model: str = 'gpt-4o-mini',
temperature: float = 0.7,
ttl_seconds: int = 3600,
) -> str:
cache_key = make_cache_key(messages, model, temperature)
# Cache hit?
cached = r.get(cache_key)
if cached is not None:
print('[CACHE HIT]')
return json.loads(cached)
# Cache miss: call API
print('[CACHE MISS]')
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=temperature,
)
result = response.choices[0].message.content
# Store in cache with TTL
r.setex(cache_key, ttl_seconds, json.dumps(result))
return resultCache-Aside Asinkron untuk FastAPI
Dalam aplikasi FastAPI asinkron, gunakan klien Redis asinkron agar pencarian cache tidak memblokir loop peristiwa. Polanya sama dengan versi sinkron, tetapi menggunakan await untuk semua operasi Redis. Dengan demikian, lapisan cache sepenuhnya tidak memblokir dan kompatibel dengan klien LLM asinkron.
from openai import AsyncOpenAI
import redis.asyncio as aioredis
import json
async_client = AsyncOpenAI()
async_r = aioredis.Redis(host='localhost', port=6379, decode_responses=True)
async def async_cached_completion(
messages: list[dict],
model: str = 'gpt-4o-mini',
temperature: float = 0.0,
ttl: int = 86400,
) -> str:
key = make_cache_key(messages, model, temperature)
cached = await async_r.get(key)
if cached:
return json.loads(cached)
response = await async_client.chat.completions.create(
model=model, messages=messages, temperature=temperature
)
result = response.choices[0].message.content
await async_r.setex(key, ttl, json.dumps(result))
return resultMemilih TTL yang Tepat
TTL (Time To Live) mengatur berapa lama respons yang tersimpan dalam cache tetap valid. Untuk tanya jawab faktual dengan basis pengetahuan yang stabil, TTL yang panjang (24–72 jam) memaksimalkan rasio cache hit. Untuk respons yang harus mencerminkan data terbaru (ringkasan berita, harga langsung), TTL yang singkat (5–15 menit) atau tanpa cache sama sekali lebih sesuai. Untuk tugas kreatif dengan suhu bukan nol, cache dapat menghasilkan respons yang sudah usang—pertimbangkan untuk melakukan cache hanya pada temperature=0.
# TTL strategy by use case
TTL_STRATEGY = {
'faq_answering': 86400 * 7, # 7 days — stable facts
'code_explanation': 86400, # 1 day — code rarely changes
'document_summarization': 3600 * 6, # 6 hours
'news_analysis': 300, # 5 minutes — stale quickly
'creative_writing': 0, # 0 = don't cache (non-deterministic)
}
def get_ttl_for_use_case(use_case: str) -> int:
return TTL_STRATEGY.get(use_case, 3600) # default 1 hourMetrik dan Pemantauan Cache
Pantau rasio cache hit sebagai metrik utama pengurangan biaya. Rasio cache hit sebesar 30 persen berarti 30 persen panggilan API berhasil dihindari. Simpan jumlah hit dan miss di Redis itu sendiri menggunakan perintah INCR pada penghitung terpisah. Sediakan endpoint /metrics dalam aplikasi FastAPI yang melaporkan rasio hit saat ini, total permintaan, dan perkiraan penghematan biaya untuk mengukur ROI penyimpanan dalam cache.
CACHE_HITS_KEY = 'llm_cache_metrics:hits'
CACHE_MISSES_KEY = 'llm_cache_metrics:misses'
async def async_cached_completion_instrumented(messages, model, temperature=0.0):
key = make_cache_key(messages, model, temperature)
cached = await async_r.get(key)
if cached:
await async_r.incr(CACHE_HITS_KEY)
return json.loads(cached)
await async_r.incr(CACHE_MISSES_KEY)
response = await async_client.chat.completions.create(
model=model, messages=messages, temperature=temperature
)
result = response.choices[0].message.content
await async_r.setex(key, 3600, json.dumps(result))
return result
async def get_cache_stats():
hits = int(await async_r.get(CACHE_HITS_KEY) or 0)
misses = int(await async_r.get(CACHE_MISSES_KEY) or 0)
total = hits + misses
return {'hit_rate': hits / total if total > 0 else 0, 'total': total}Strategi Invalidasi Cache
Invalidasi cache eksak mudah dilakukan karena kuncinya deterministik. Untuk membatalkan entri tertentu, hitung ulang kuncinya dan panggil r.delete(key). Untuk membatalkan semua entri dengan pola perintah tertentu, gunakan awalan kunci Redis dengan pemindaian wildcard. Untuk membatalkan seluruh cache setelah pembaruan besar pada basis pengetahuan, panggil r.flushdb() (gunakan dengan hati-hati—perintah ini menghapus semua kunci dalam basis data).
async def invalidate_cache_entry(messages, model, temperature):
key = make_cache_key(messages, model, temperature)
deleted = await async_r.delete(key)
print(f'Deleted {deleted} cache entries')
async def invalidate_all_llm_cache():
# Scan for all keys with prefix 'llm_cache:'
keys_to_delete = []
async for key in async_r.scan_iter(match='llm_cache:*'):
keys_to_delete.append(key)
if keys_to_delete:
await async_r.delete(*keys_to_delete)
print(f'Invalidated {len(keys_to_delete)} cache entries')Menyerialkan Respons Kompleks
Jika aplikasi Anda menyimpan seluruh objek respons API dalam cache (bukan hanya isi teksnya), lakukan serialisasi dengan hati-hati. Objek ChatCompletion lengkap mencakup penggunaan token, versi model, dan alasan penyelesaian—berguna untuk logging dan pelacakan biaya. Gunakan metode .model_dump_json() milik SDK untuk menserialkan objek respons Pydantic menjadi string JSON, lalu bangun kembali objek tersebut dengan ChatCompletion.model_validate_json() saat mengambilnya dari cache.
from openai.types.chat import ChatCompletion
async def cached_completion_full_response(
messages, model='gpt-4o-mini', temperature=0.0
):
key = make_cache_key(messages, model, temperature) + ':full'
cached = await async_r.get(key)
if cached:
return ChatCompletion.model_validate_json(cached) # reconstruct object
response = await async_client.chat.completions.create(
model=model, messages=messages, temperature=temperature
)
# Serialize Pydantic model to JSON
await async_r.setex(key, 3600, response.model_dump_json())
return responseCaching dan Ketidakdeterministikan
Cache eksak hanya masuk akal untuk permintaan yang deterministik atau hampir deterministik. Pada temperature=0 dan top_p=1.0, sebagian besar LLM menghasilkan output yang sama untuk input yang sama (meskipun tidak dijamin karena ketidakdeterministikan floating-point). Pada suhu yang lebih tinggi, respons yang tersimpan dalam cache menjadi usang karena model mungkin menghasilkan output yang berbeda. Selalu gunakan cache pada temperature=0 atau jelaskan dengan tegas dalam kunci cache bahwa respons dapat bervariasi.
Klaster Redis dan Penyiapan Produksi
Untuk penerapan produksi dengan volume cache yang tinggi, gunakan Redis Cluster untuk melakukan sharding horizontal di beberapa node, atau layanan Redis terkelola seperti AWS ElastiCache atau Redis Cloud. Tetapkan kebijakan maxmemory (biasanya allkeys-lru untuk mengeluarkan entri yang paling lama tidak digunakan saat memori penuh) agar Redis tidak kehabisan memori dan ukuran cache dapat dikelola secara otomatis.
# Redis configuration for production LLM caching
# In redis.conf:
# maxmemory 2gb
# maxmemory-policy allkeys-lru
# Connection with retry and connection pool
import redis
from redis.retry import Retry
from redis.backoff import ExponentialBackoff
retry = Retry(ExponentialBackoff(base=0.1), 3)
production_redis = redis.Redis(
host='your-redis-host.cache.amazonaws.com',
port=6379,
ssl=True,
decode_responses=True,
max_connections=50,
retry=retry,
retry_on_error=[redis.ConnectionError, redis.TimeoutError],
)Pemeriksaan Singkat
Uji pemahaman Anda tentang penyimpanan respons LLM eksak dalam cache dengan Redis dari pelajaran ini.
Rangkuman Pelajaran
Dalam pelajaran ini Anda mempelajari bahwa cache eksak melakukan hashing terhadap semua input LLM untuk menghasilkan kunci cache deterministik, pola cache-aside memeriksa Redis sebelum memanggil API dan menyimpan hasil setelah cache miss, serta pemilihan TTL harus mencerminkan seberapa sering konten Anda berubah—lebih panjang untuk pengetahuan yang stabil dan lebih pendek untuk data dinamis. Pantau rasio cache hit sebagai metrik utama pengurangan biaya. Selanjutnya, kita akan membangun cache semantik untuk kueri yang mirip tetapi tidak identik.
Belajar Python dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 30
- Pelajaran
- 120
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Penyimpanan Singgahan Persis dengan Redis” gratis?
Ya — teks lengkap “Penyimpanan Singgahan Persis dengan Redis” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Penyimpanan Singgahan Persis dengan Redis”?
Simpan respons LLM dalam singgahan dengan membuat hash dari perintah lengkap dan menyimpan hasilnya di Redis bersama TTL, sehingga permintaan identik dapat dilayani seketika tanpa panggilan API. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?
Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.
Berapa lama pelajaran “Penyimpanan Singgahan Persis dengan Redis” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?
Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Penyimpanan Singgahan Persis dengan Redis
- Penyimpanan Singgahan Semantik dengan Embedding
- Penyimpanan Singgahan Awalan Perintah OpenAI
- Pengelompokan, Perutean Model, dan Dasbor Biaya