Skip to content

Quality-Monitored Compression: Scientifically Finding the Compression Boundary

Should compression be 50%, 70%, or 90%? You can't know by 'feel' — you need an eval framework. This lesson covers LLM-as-judge, golden test set, A/B test production rollout, and regression detection patterns.

Şükrü Yusuf KAYA
18 min read
Advanced
Kalite-Monitored Compression: Sıkıştırma Sınırını Bilimsel Olarak Bulmak
📐 Bilim, hisle yapılan optimizasyondan üstündür
Modül 5 ve 6'nın temel sorunu: "Bu compression çalışıyor mu?" sorusuna nasıl bilimsel cevap veririz? Bu derste o framework. Sonunda kendi compression eval pipeline'ını çalıştırabilirsin.

Golden Test Set — Hayati Başlangıç#

Bir compression değişikliği yapmadan önce:
  1. Production data'dan 100-200 representative örnek topla
  2. Bunlara ideal output etiketle (insan annotation veya senin onay verdiğin teacher output)
  3. Bu set kilitlenir — değişmez, ileride bütün karşılaştırmaların referansı

Set kompozisyonu#

TipSayı
Happy path örnekler60
Edge case'ler30
Adversarial örnekler10
Toplam100
100 örnek production'da yeterli. Modül 9'da eval setup'ın derinine girer.

LLM-as-Judge — Otomatik Kalite Skorlama#

Her test örneği için iki output: baseline (compression öncesi) ve compressed.
LLM bir judge olarak hangisi iyi karar versin:
def llm_judge(query: str, output_a: str, output_b: str, criteria: dict): """A ve B output'larını karşılaştır.""" prompt = f""" İki AI cevabını kıyasla. Kullanıcı sorusuna hangisi daha iyi cevap veriyor? Kriterler: - Doğruluk: bilgi doğru mu? - Tamlık: tüm soruyu cevaplıyor mu? - Akıcılık: Türkçe doğal mı? - Empati: kullanıcıya uygun ton mu? Soru: {query} Cevap A: {output_a} Cevap B: {output_b} Sadece şunlardan birini yaz: "A daha iyi", "B daha iyi", "Eşit" """ response = openai.chat.completions.create( model="gpt-5", # judge daha güçlü model olsun messages=[{"role": "user", "content": prompt}], max_tokens=10, ) return response.choices[0].message.content.strip()

Doğru tasarım kuralları#

  1. Judge model güçlü olsun (GPT-5, Opus 4.7) — judge'in kendisi hata yapmasın
  2. Output sırası random — A ya da B önce gelmesi sonucu değiştirmesin (position bias)
  3. Kriterler explicit — judge "bilmiyorum" demesin

Pair Test — Tam Pipeline#

import random from collections import Counter def pair_test(test_set, baseline_pipeline, compressed_pipeline): """Baseline vs compressed pipeline'ı 100 örnekte karşılaştır.""" results = [] for example in test_set: query = example["input"] baseline_out = baseline_pipeline(query) compressed_out = compressed_pipeline(query) # Position randomization if random.random() > 0.5: verdict = llm_judge(query, baseline_out, compressed_out, {}) mapping = {"A daha iyi": "baseline", "B daha iyi": "compressed", "Eşit": "tie"} else: verdict = llm_judge(query, compressed_out, baseline_out, {}) mapping = {"A daha iyi": "compressed", "B daha iyi": "baseline", "Eşit": "tie"} results.append(mapping.get(verdict, "tie")) return Counter(results) # Çalıştır result = pair_test(golden_set, baseline_rag, compressed_rag) print(result) # Counter({'baseline': 18, 'compressed': 23, 'tie': 59})

Karar#

Total: 100 Baseline daha iyi: 18 (%18) Compressed daha iyi: 23 (%23) Eşit: 59 (%59) Compressed kazandı (23 > 18) + büyük kısım eşit. Verdict: Ship the compression ✅

Stricter eşik#

Eğer "compressed kazandı + eşit > %80" rule koyarsan:
  • Bu örnek: 23 + 59 = 82, ship
  • Aksi takdirde compression çok agresif

Regression Detection — Production'da#

Compression ship ettin. Aylar sonra production'da gözle görünmeyen quality regression olabilir mi? Evet:
  • Data distribution değişti (yeni kullanıcı segmentleri)
  • LLM model upgrade (provider snapshot)
  • Bağlı RAG retrieval sistemi değişti
Bunu sürekli izle.

Daily eval cron#

def daily_quality_check(): """Her gece 100 random production isteğinde compression eval.""" today_traces = get_traces_for_today(sample_size=100) quality_scores = [] for trace in today_traces: # Hipotetik: aynı sorguyu baseline ile de çalıştır (limited) baseline_out = call_baseline(trace["input"]) compressed_out = trace["output"] score = llm_judge_single( query=trace["input"], output=compressed_out, reference=baseline_out, ) quality_scores.append(score) avg = np.mean(quality_scores) # Alert if drop historical_avg = get_historical_avg(days=30) if avg < historical_avg - 0.05: # 5 puan drop send_alert(f"Quality regression detected: {avg:.2f} vs {historical_avg:.2f}") log_metric("compression_quality_score", avg)

Evaluation Rubric — Multi-Dimensional Scoring#

Sadece "A iyi/B iyi" yetmeyebilir. Multi-axis scoring:
RUBRIC = { "accuracy": "0-5 — Bilgi doğru mu?", "completeness": "0-5 — Tüm soruyu cevaplıyor mu?", "fluency": "0-5 — Türkçe akıcı mı?", "empathy": "0-5 — Empatik ton var mı?", "safety": "0-5 — Zararlı içerik yok mu?", } def rubric_judge(query: str, output: str) -> dict: prompt = f"""Aşağıdaki cevabı 5 kriterde 0-5 skala ile değerlendir: Soru: {query} Cevap: {output} Format (JSON): {{ "accuracy": <0-5>, "completeness": <0-5>, "fluency": <0-5>, "empathy": <0-5>, "safety": <0-5>, "notes": "..." }} """ response = openai.chat.completions.create( model="gpt-5", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, ) return json.loads(response.choices[0].message.content) # Her test örneğine 5 boyutlu skor results_per_dim = {dim: [] for dim in RUBRIC.keys()} for ex in test_set: score = rubric_judge(ex["input"], compressed_pipeline(ex["input"])) for dim in RUBRIC: results_per_dim[dim].append(score[dim]) # Compute mean per dimension for dim, scores in results_per_dim.items(): print(f"{dim}: {np.mean(scores):.2f}")

Tipik rapor#

accuracy: 4.6 vs baseline 4.7 (-0.1) ✅ completeness: 4.3 vs baseline 4.5 (-0.2) ⚠️ küçük fluency: 4.7 vs baseline 4.7 (0.0) ✅ empathy: 4.5 vs baseline 4.4 (+0.1) ✅ safety: 5.0 vs baseline 5.0 (0.0) ✅
Compression genel olarak ok, ama "completeness" biraz düşmüş — daha az agresif compress et veya RAG retrieval'i artır.

A/B Rollout Stratejisi#

Eval geçti. Production'a nasıl çıkarırsın? Aşamalı.

Hafta 1 — %5 trafiğine ver#

  • Aktif kullanıcıların %5'i compressed pipeline'a yönlendirildi
  • Metric'leri izle: CSAT, conversion, complaint rate
  • Aktif gözlem, rollback hazır

Hafta 2 — %20#

  • Eğer hafta 1 metric'ler stabil ise %20'ye çıkar
  • Bir hafta daha izle

Hafta 3 — %50#

  • Half-and-half
  • Daha fazla istatistiksel anlamlılık

Hafta 4 — %100#

  • Full rollout

Rollback playbook#

Trigger: CSAT %5 düşüş, complaint rate 2× artış, ya da critical bug raporu Action: Feature flag'i toggle, %100 baseline'a geri al Time: <5 dakika Investigation: Logs'tan failure case'leri çek, compression algorithm fix et, eval set'e ekle, retest
🎉 Modül 6 Tamamlandı
Artık prompt'larını %80-90 sıkıştırabilir ve bilimsel olarak kalite kaybı olmadığını doğrulayabilirsin. Eğer Modül 5'in manuel optimizasyonu + Modül 6'nın otomatik compression kombosu uygularsan, toplam %90+ token tasarrufu, kalite parity ile.
▶️ Modül 7'ye geçiyoruz
Modül 7: Prompt Caching — 2026'nın Tek En Büyük Tasarruf Kaldıracı. Anthropic %90 indirim, OpenAI %50 indirim, Gemini %75 indirim. Cache-friendly mimari, breakpoint'ler, TTL kararları. Bu, sıralama olmayan birinci sıradaki teknik.

Frequently Asked Questions

Yes, a known issue. Mitigation: (1) Judge model != tested model (e.g., compressed Haiku, judge Opus), (2) Position randomization, (3) Human annotator 5% spot-check. Module 9 details eval.

Yorumlar & Soru-Cevap

(0)
Yorum yazmak için giriş yap.
Yorumlar yükleniyor...

Related Content