İlk Lab: Cache ON vs OFF — Gerçek Dolar Karşılaştırma
Teori bitti, kollar sıvanır zamanı. Bu derste Anthropic API ile aynı uzun prompt'u 100 kez göndereceğiz; biri cache açık, biri kapalı. Gerçek maliyet, gerçek latency, gerçek hit rate metriklerini göreceksin.
Şükrü Yusuf KAYA
18 min read
IntermediateLab #1: Cache ON vs OFF — Kendi Dolarınla Ölç
Şu ana kadar her şey teori. Şimdi parmaklarını klavyeye koy. Bu lab'i bitirince elinde:
- Anthropic Claude API ile çalışan, cache toggle edilebilen bir Python betiği
- Yan yana koyduğunda %85+ tasarruf gösteren bir çıktı tablosu
- "Cache hit/miss" telemetri'sini API yanıtından okuyabilen kod
- Türk Lirası cinsinden bir maliyet raporu
Süre: ~20 dakika. Maliyet: ~$0.50 (50 cent).
API Key Gerekiyor
Bu lab gerçek API çağrısı yapacak — Anthropic API key'in gerekiyor. console.anthropic.com'da hesap aç, hiç kullanmadıysan $5 ücretsiz kredi geliyor. Sonra Settings → API Keys'den anahtarını al.
Adım 1 — Çevreyi Kur#
bash
$ pip install anthropic python-dotenv tiktokenSuccessfully installed anthropic-0.39.0 ... $ python -c "import anthropic; print(anthropic.__version__)"0.39.0Şimdi API anahtarını çevre değişkenine yaz:
export ANTHROPIC_API_KEY="sk-ant-..."
Adım 2 — Test Prompt'u Hazırla#
Cache anlamlı sonuçlar verebilmesi için en az 1024 token statik içerik gerekiyor (Anthropic minimum eşiği). Biz büyük gideceğiz: ~15.000 token'lık bir bilgi metni kullanacağız.
Aşağıdaki Türkçe lorem'i hayali bir şirket dokümanı gibi düşün — gerçek üründe burası senin company knowledge base'in olacak.
python
# Sahte ama yeterince uzun bir "şirket dokümanı" üretirdef make_long_document(num_paragraphs: int = 200) -> str: para = ( "Şirketimiz 2008 yılında İstanbul'da kurulmuştur ve fintech alanında " "Türkiye'nin önde gelen teknoloji firmalarından biri haline gelmiştir. " "Müşterilerimize KVKK ve PCI-DSS uyumlu, ISO 27001 sertifikalı altyapı " "üzerinde uçtan uca ödeme çözümleri sunmaktayız. 2024 yılında 1.2 milyar " "TL işlem hacmine ulaştık ve 450'den fazla kurumsal müşteriye hizmet " "veriyoruz. Ürün portföyümüz arasında sanal POS, fiziksel POS, mobil " "ödeme, ön ödemeli kart, ve kripto ödeme çözümleri yer almaktadır.\n\n" ) return (para * num_paragraphs).strip()Sahte dokümanı üreten yardımcı fonksiyon
Adım 3 — Cache OFF Versiyonu#
Önce cache olmadan bir baseline çekelim. 5 sorgu yapacağız ve her birinde aynı 15K dokümanı tekrar tekrar göndereceğiz.
python
import osimport timeimport anthropic client = anthropic.Anthropic() # ANTHROPIC_API_KEY env'i bekler def make_long_document(num_paragraphs: int = 200) -> str: para = ( "Şirketimiz 2008 yılında İstanbul'da kurulmuştur ve fintech alanında " "Türkiye'nin önde gelen teknoloji firmalarından biri haline gelmiştir. " "Ürün portföyümüz arasında sanal POS, fiziksel POS, mobil ödeme, " "ön ödemeli kart, ve kripto ödeme çözümleri yer almaktadır.\n\n" ) return (para * num_paragraphs).strip() DOC = make_long_document(num_paragraphs=200)QUERIES = [ "Şirketin kuruluş yılı nedir?", "Hangi sertifikalara sahibiz?", "Ürün portföyümüzde neler var?", "Yıllık işlem hacmi ne kadar?", "Kaç kurumsal müşterimiz var?",] total_input_tokens = 0total_output_tokens = 0total_latency = 0.0 print(f"{'Sorgu':<40} {'In':>7} {'Out':>5} {'Süre':>7}")print("─" * 65) for q in QUERIES: start = time.time() resp = client.messages.create( model="claude-sonnet-4-6", max_tokens=200, system=DOC, # ← Cache olmadan, normal system messages=[{"role": "user", "content": q}], ) latency = time.time() - start total_input_tokens += resp.usage.input_tokens total_output_tokens += resp.usage.output_tokens total_latency += latency print(f"{q[:38]:<40} {resp.usage.input_tokens:>7} {resp.usage.output_tokens:>5} {latency:>6.2f}s") # Maliyet hesabı (Sonnet 4.6 fiyatları)cost = ( total_input_tokens / 1_000_000 * 3.00 + total_output_tokens / 1_000_000 * 15.00)print(f"\nToplam input: {total_input_tokens:>10,} token")print(f"Toplam output: {total_output_tokens:>10,} token")print(f"Toplam süre: {total_latency:>10.2f} sn")print(f"Toplam cost: ${cost:.4f} | {cost * 33.5:.2f} TL")Cache KAPALI: aynı doküman 5 kez gönderiliyor, her seferinde full input ücretlendirilir
Baseline
Gözlem: 5 sorgu → ~12 saniye + 8 TL. Her sorgu birbirinden bağımsız işleniyor; doküman her seferinde sıfırdan prefill ediliyor. Şimdi caching'i açalım.
Adım 4 — Cache ON Versiyonu#
Anthropic'te caching'i açmak için ekliyoruz. Bu, "buradan öncesi cache'lenebilir" demek.
cache_control: {"type": "ephemeral"}python
import osimport timeimport anthropic client = anthropic.Anthropic() def make_long_document(num_paragraphs: int = 200) -> str: para = ( "Şirketimiz 2008 yılında İstanbul'da kurulmuştur ve fintech alanında " "Türkiye'nin önde gelen teknoloji firmalarından biri haline gelmiştir. " "Ürün portföyümüz arasında sanal POS, fiziksel POS, mobil ödeme, " "ön ödemeli kart, ve kripto ödeme çözümleri yer almaktadır.\n\n" ) return (para * num_paragraphs).strip() DOC = make_long_document(num_paragraphs=200)QUERIES = [ "Şirketin kuruluş yılı nedir?", "Hangi sertifikalara sahibiz?", "Ürün portföyümüzde neler var?", "Yıllık işlem hacmi ne kadar?", "Kaç kurumsal müşterimiz var?",] # system, list[dict] olarak verilirse cache_control kullanabilirsinsystem_blocks = [ { "type": "text", "text": DOC, "cache_control": {"type": "ephemeral"}, # ← Sihirli satır }] # Telemetri toplamak içintotal_input = 0total_cache_create = 0total_cache_read = 0total_output = 0total_latency = 0.0 print(f"{'Sorgu':<40} {'In':>5} {'CW':>6} {'CR':>6} {'Out':>5} {'Süre':>6}")print("─" * 75) for q in QUERIES: start = time.time() resp = client.messages.create( model="claude-sonnet-4-6", max_tokens=200, system=system_blocks, # ← Liste, dict değil messages=[{"role": "user", "content": q}], ) latency = time.time() - start u = resp.usage cw = getattr(u, "cache_creation_input_tokens", 0) cr = getattr(u, "cache_read_input_tokens", 0) total_input += u.input_tokens total_cache_create += cw total_cache_read += cr total_output += u.output_tokens total_latency += latency print(f"{q[:38]:<40} {u.input_tokens:>5} {cw:>6} {cr:>6} {u.output_tokens:>5} {latency:>5.2f}s") # Maliyet (Sonnet 4.6)cost = ( total_input / 1_000_000 * 3.00 + total_cache_create / 1_000_000 * 3.75 + total_cache_read / 1_000_000 * 0.30 + total_output / 1_000_000 * 15.00)print(f"\nFresh input: {total_input:>10,} token")print(f"Cache write: {total_cache_create:>10,} token")print(f"Cache read: {total_cache_read:>10,} token")print(f"Output: {total_output:>10,} token")print(f"Toplam süre: {total_latency:>10.2f} sn")print(f"Toplam cost: ${cost:.4f} | {cost * 33.5:.2f} TL")Cache AÇIK: ilk sorguda 'cache write', sonrakilerde 'cache read'
Sonuç
5 sorguda 8.06 TL → 2.74 TL (%66 düşüş). Süre 12.2sn → 5.06sn (~%59 hızlanma). 1000 sorgu yapsak yaklaşık %88'e ulaşırdı (ilk cache write'ın etkisi seyrekleştikçe).
Adım 5 — Telemetri Detayı#
Yukarıdaki çıktıda dikkat etmen gereken üç field var:
| Field | Anlamı | Fiyat |
|---|---|---|
input_tokens | Fresh, cache'lenmemiş input | $3/M |
cache_creation_input_tokens | İlk yazımda cache'e yazılan | $3.75/M |
cache_read_input_tokens | Sonraki okumalarda cache'ten gelen | $0.30/M |
İlk istek: cache_creation > 0, cache_read = 0
Sonraki istekler: cache_creation = 0, cache_read > 0
Cache miss (TTL bitti): cache_creation > 0 yeniden
Adım 6 — Cache Hit Rate Hesapla#
Production'da bu metrik temel KPI'ndır. Formül:
Yukarıdaki sonuçta: 63.200 / (63.200 + 15.800) = %80. İlk istek mi cache write yapıyor, sonraki 4'ü read; bu nedenle %80 mantıklı.
python
def cache_hit_rate(read_tokens: int, write_tokens: int) -> float: total = read_tokens + write_tokens if total == 0: return 0.0 return read_tokens / total * 100 # Yukarıdaki testtenprint(f"5 sorgu sonrası hit rate: {cache_hit_rate(63200, 15800):.1f}%") # 100 sorgu simülasyonu (ilk cache write sonrası hepsi read)read_100 = 15800 * 99 # 99 cache hitwrite_100 = 15800 # 1 cache writeprint(f"100 sorgu sonrası hit rate: {cache_hit_rate(read_100, write_100):.2f}%") # 1000 sorgu (TTL 5dk olsa da hep aynı, 1 write)read_1k = 15800 * 999write_1k = 15800print(f"1000 sorgu sonrası hit rate: {cache_hit_rate(read_1k, write_1k):.2f}%")Cache hit rate'i fonksiyona dökelim
Adım 7 — TTL'yi Kırın: Cache Miss Görmek#
Şimdi caching'in tek zayıflığını gör: TTL bitince cache miss olur.
Anthropic'in default TTL'si 5 dakika. Aşağıdaki kodu çalıştır, ortadaki (5 dk 5 sn) ile cache'in expire olmasını izle:
sleep(305)python
import time # İlk sorgu — cache writeresp1 = client.messages.create(...)print("İlk:", resp1.usage.cache_creation_input_tokens, "write") # Hemen ardından — cache readresp2 = client.messages.create(...)print("İkinci:", resp2.usage.cache_read_input_tokens, "read") # 5 dakika bekle — TTL bitertime.sleep(305) # Üçüncü sorgu — yeniden cache WRITEresp3 = client.messages.create(...)print("305sn sonra:", resp3.usage.cache_creation_input_tokens, "yeniden write")TTL expire davranışı — production'da bu pattern'i izlemelisin
Production Uyarısı
Production'da TTL miss patlamalarına dikkat: trafik seyrek bir saatte cache sürekli expire olur ve maliyet baseline'a döner. Modül 11'de "cache warming" stratejilerini göstereceğim.
Adım 8 — 1 Saatlik TTL (Beta)#
Anthropic'te 1 saatlik TTL de var ama daha pahalı (yazma maliyeti 2× input). Kullanım:
python
system_blocks = [ { "type": "text", "text": DOC, "cache_control": { "type": "ephemeral", "ttl": "1h", # ← Default 5m, alternatif 1h }, }]1 saatlik TTL — cache write 2× pahalı
Ne zaman 1h? Trafik seyrek (saatte 10-20 sorgu) ama burst'lü. 5dk sürekli expire olur, 1h hayatta kalır. Break-even hesabı:
Detayları Modül 11'de yapacağız.
✓ Pekiştir#
Bir Sonraki Derste#
Bu modülü bitirme sınavıyla taçlandıracağız: 10 gerçek soru, %70 ile geçme. Hazır olduğunda devam et 🎯
Frequently Asked Questions
Anthropic'te minimum cache eşiği 1024 token. Altı için cache_control yazsan da hiçbir şey olmaz, normal input gibi ücretlendirilir. Bu yüzden çok kısa promptlarda caching anlamsız.
Yorumlar & Soru-Cevap
(0)Yorum yazmak için giriş yap.
Yorumlar yükleniyor...
Related Content
1. Temeller — Context Penceresi Ekonomisi
Bu Eğitim Hakkında ve Prompt Caching Neden Önemli?
Start Learning1. Temeller — Context Penceresi Ekonomisi
Token Ekonomisi 101: Input vs Output Cost Asimetrisi
Start Learning1. Temeller — Context Penceresi Ekonomisi