7. ünite / 10 · 4 saat
Değerlendirme: ölçüt, rubrik, hakem ve uydurma kontrolü
Test kümesi kurmak, tam ve normalize eşleşme, token F1, rubrik, LLM hakem kavramı ve cevabın kaynağa dayanıp dayanmadığını sınamak.
Bu ünitenin sonunda
- Bir uygulama için küçük ama temsil edici bir test kümesi kurmak
- Tam eşleşme, normalize eşleşme ve token F1'i hesaplamak
- Rubrikle çok boyutlu puan vermek ve LLM hakemin sınırlarını açıklamak
- Uydurma sayıları dayanaklılık kontrolüyle yakalamak
Ders notları
"Birkaç soru sordum, iyi görünüyor" bir ölçüm değildir. Bir LLM uygulaması, cevabı bilinen sorulardan oluşan bir test kümesiyle değerlendirilir ve her prompt, model ya da dizin değişikliğinden sonra aynı küme yeniden koşulur.
Ölçütler
- Tam eşleşme: cevap altın cevapla karakter karakter aynı mı? Çok katıdır; "Yüzde 10." ile "yüzde 10" farklı sayılır.
- Normalize eşleşme: büyük-küçük harf (Türkçe I/İ dahil), noktalama ve kaynak etiketi atıldıktan sonra eşleşme.
- Token F1: ortak kelimelerin kesinlik ve duyarlılığının harmonik ortalaması. Kısmi doğruluğu ödüllendirir ama anlamı ölçmez.
- Rubrik: doğruluk, kaynak gösterme, kısalık, dayanaklılık gibi ölçütlere ayrı puan.
LLM hakem
Açık uçlu cevaplarda başka bir modele rubriği, kaynağı ve cevabı verip puanlatmak (LLM-as-judge) ölçeklenebilir bir yoldur. Ama hakem de bir modeldir: uzun cevabı kayırabilir, kendi üslubunu ödüllendirebilir, aynı girdiye farklı puan verebilir. Hakemin kararları insan puanlarıyla küçük bir kümede karşılaştırılmadan ona güvenilmez. Bu sayfada hakem promptu yalnız gösterilir, çalıştırılmaz.
Uydurma kontrolü
Dayanaklılık, cevaptaki iddiaların kaynakta bulunup bulunmadığıdır. Ucuz ve etkili bir kontrol: cevaptaki her sayı kaynak notta geçiyor mu? "AD0 yüksekse 0x69 olur" gerçekte doğru olabilir ama notlarda yoksa kaynaksızdır; RAG uygulamasında kaynaksız iddia hatadır.
Tek bir sayıya bakma: ölçütleri yan yana koy ve hangi ölçütün hangi hatayı yakaladığını incele. Simülasyonda A sistemi kısa ve isabetli, B uzun ve yer yer uyduruyor; tam eşleşme ikisini de cezalandırır, dayanaklılık yalnız B'yi.
Simülasyon
Öğretim modeli: bu sayfadaki simülasyonlar gerçek bir dil modeli değildir. Küçük, deterministik, tarayıcıda çalışan modellerdir; kavramı göstermek için yazıldılar. Site hiçbir dış LLM servisine istek göndermez.
Değerlendirme tezgâhı: ölçütler, rubrik, dayanaklılık
Sekiz soruluk bir test kümesinde iki sistemin cevapları: A kısa ve isabetli, B uzun ve yer yer uyduruyor. Tam eşleşme, normalize eşleşme, token F1, rubrik puanı ve kaynağa dayanaklılık kontrolünü aç kapa; hangi ölçütün hangi hatayı yakaladığını tabloda gör. LLM hakem promptu yalnız gösterilir, çalıştırılmaz.
Kendin dene
Değerlendirme tezgâhında önce yalnız tam eşleşmeyi aç: A ve B neden ikisi de düşük? Normalize eşleşmeyi ekle ve farkı açıkla. Dayanaklılığı aç ve B'nin hangi sayıları uydurduğunu listele. Son olarak 2. sorunun B cevabı için hakem promptunu oku ve hakemin hangi bilgiyle "kaynaksız" diyebileceğini yaz.
Kod
Bunları kendi bilgisayarında çalıştır. Anahtar ANTHROPIC_API_KEY ortam değişkeninden okunur; koda asla yazma.
import re
import unicodedata
from collections import Counter
def normalize(text: str) -> str:
text = text.replace("I", "ı").replace("İ", "i").lower() # Türkçe büyük-küçük harf
text = unicodedata.normalize("NFKC", text)
text = re.sub(r"\[[^\]]*\]|[^\w\s%.,]|(?<!\d)[.,]|[.,](?!\d)", " ", text) # kaynak etiketini ve noktalamayı at, ondalığı koru
return " ".join(text.split())
def exact_match(pred: str, gold: str) -> int:
return int(pred.strip() == gold.strip())
def normalized_match(pred: str, gold: str) -> int:
return int(normalize(pred) == normalize(gold))
def token_f1(pred: str, gold: str) -> float:
p, g = normalize(pred).split(), normalize(gold).split()
common = sum((Counter(p) & Counter(g)).values())
if common == 0:
return 0.0
precision, recall = common / len(p), common / len(g)
return 2 * precision * recall / (precision + recall)
cases = [ # regresyon kümesi: her değişiklikten sonra yeniden koşulur
{"q": "Dönem projesinin not ağırlığı nedir?", "gold": "yüzde 45"},
{"q": "MPU6050 varsayılan I2C adresi?", "gold": "0x68"},
]
for c in cases:
pred = my_app(c["q"]) # değerlendirilen sistem
print(exact_match(pred, c["gold"]), normalized_match(pred, c["gold"]),
round(token_f1(pred, c["gold"]), 2))import json
import anthropic
client = anthropic.Anthropic() # ANTHROPIC_API_KEY ortam değişkeninden
RUBRIC = """Her ölçütü 0 ya da 1 ile puanla:
1. correct: cevap referansla aynı bilgiyi veriyor
2. grounded: her iddia <source> içinde geçiyor
3. cited: cevap kaynak kimliğini gösteriyor
4. concise: gereksiz tekrar ve dolgu yok"""
SCHEMA = {
"type": "object",
"properties": {
"correct": {"type": "integer", "enum": [0, 1]},
"grounded": {"type": "integer", "enum": [0, 1]},
"cited": {"type": "integer", "enum": [0, 1]},
"concise": {"type": "integer", "enum": [0, 1]},
"reason": {"type": "string"},
},
"required": ["correct", "grounded", "cited", "concise", "reason"],
"additionalProperties": False,
}
def judge(question: str, source: str, reference: str, answer: str) -> dict:
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=2000,
system="Sen tarafsız bir değerlendiricisin. Yalnız verilen rubriğe göre puanla.",
messages=[{"role": "user", "content": (
f"{RUBRIC}\n<question>{question}</question>\n<source>{source}</source>\n"
f"<reference>{reference}</reference>\n<answer>{answer}</answer>")}],
output_config={"format": {"type": "json_schema", "schema": SCHEMA}},
)
text = next(b.text for b in response.content if b.type == "text")
return json.loads(text) # hakemi de insan etiketli örneklerle sınaSık yapılan hatalar
- Test kümesini yalnız kolay sorulardan kurmak: "notlarda yok" ve sınır durumları da olmalı.
- Yalnız tam eşleşmeye bakmak: doğru ama farklı yazılmış cevaplar hata sayılır.
- LLM hakemi insanla karşılaştırmadan kullanmak.
- Test kümesini prompt yazarken görüp ona göre ayarlamak: ayrı bir doğrulama kümesi tut.
Yazılım mühendisliği bağlantısı
Değerlendirme kümesi LLM uygulamasının regresyon testidir.
- Kümeyi depoda tut, CI'da her çekme isteğinde koştur ve ölçütleri bir eşikle karşılaştır.
- Her hatayı kümeye yeni bir vaka olarak ekle; aynı hata ikinci kez sessizce dönmesin.
Kendini sına
"Yüzde 10." cevabı, altın cevap "yüzde 10" iken tam eşleşmede ve normalize eşleşmede ne alır?
Kesinlik 0,5 ve duyarlılık 1 ise token F1 kaçtır?
LLM hakemine güvenmeden önce ne yapılmalı?
Dayanaklılık kontrolü hangi hatayı yakalar?
Bu üniteden sonra bitirme projesinde
- Değerlendirme raporu: 25+ soruluk küme, ölçütler ve rubrik CI'da; iki prompt sürümünün karşılaştırması; hata analizi (hangi soru neden yanlış).