← Notlara dön

Tek Bir LLM Skoru İki Farklı Sorunu Gizliyordu

RAG pipeline'ını tek bir şey olarak değerlendirmeyi bıraktım, retrieval ve generation hakkında ayrı sorular sormaya başladım.

“Pipeline iyi mi?”

CairnOps’u kurarken bu soruyu sormaya devam ediyordum ve hiç yardımcı olmuyordu.

Bir RAG sistemi en az iki çok farklı şekilde başarısız olabilir:

  1. retriever yanlış materyali getirir;
  2. model doğru materyali alır ve yine de zayıf bir cevap üretir.

Tüm pipeline için tek bir skor bu ayrımı gizler.

Evaluation’ı, sistemi böldüğüm gibi böldüm

CairnOps için sonunda Ragas’ı çoğunlukla retrieval odaklı evaluation’da, DeepEval’i ise generation odaklı evaluation’da kullandım.

Bu ayrım bir proje tercihiydi, kütüphanelerden birinin dayattığı bir gereklilik değil.

Bir evaluation çalıştırmasının sonucunun bana nerede debug yapacağımı söylemesini istedim.

Örneğin, source coverage’ın iyi olduğu ama fact coverage’ın zayıf olduğu durumlar oldu.

Bu, “quality: 0.71”den çok daha faydalı bir sinyal.

Bana retriever’ın muhtemelen beklediğim dokümanları bulduğunu, ama cevabın beklenen bilginin yeterince fazlasını taşımadığını söylüyor.

Bu ayrım olmadan, bir generation sorunu için retrieval parametrelerini ayarlamaya vakit harcardım.

Benchmark’ım bilerek küçük

Devasa bir sentetik dataset kurmadım.

Knowledge base’ten alınan sekiz vaka ile başladım:

Rota
- Aladağlar
- Kaçkar
- Erciyes
- Uludağ

Ekipman
- Kramponi seçimi
- Emniyet kemeri uyumu

Güvenlik
- Yükseklik hastalığı
- Çığ farkındalığı

Her vakanın net beklentileri var:

BenchmarkCase(
    user_input=...,
    ground_truth=...,
    expected_risk_level=...,
    expected_facts=[...],
    expected_sources=[...],
)

expected_sources özellikle faydalı çıktı.

Bir cevap, retriever’ın kullanmasını beklemediğim bir kaynağa dayanırken bile makul görünebilir. Kaynak setini ayrıca kontrol etmek, sadece son metni yargılamak yerine retrieval drift’ini yakalamamın bir yolu.

Bilerek sıkıcı metrikler kullanıyorum

Her metriğin başka bir LLM’e ihtiyacı yok.

Tam olarak tanımlayabildiğim şeyler için deterministik kontroller tutuyorum:

fact_coverage
source_coverage
risk_match

Hızlılar, tekrarlanabilirler ve ucuzlar.

Sonra gerçekten semantik değerlendirme gerektiren sorular için LLM-as-a-judge metriklerini kullanıyorum, answer relevance ve faithfulness gibi.

Bu iki yaklaşımı birbirine rakip olarak görmüyorum.

Bir şeyi deterministik olarak test edebiliyorsam, bunu tercih ederim. Özellik doğası gereği semantikse, bir judge model faydalı hale gelir.

Ayrıca evaluation kütüphanesinin provider’ımı seçmesine izin vermeyi bıraktım

Bir noktada judge model’i bir string olarak yapılandırdım ve kütüphanenin varsayılan model çözümlemesi üzerinden beklenmedik bir OpenAI-key gereksinimiyle karşılaştım.

Varsayılan yol Groq kurulumumu kabul edene kadar environment variable’ları büküp bunu aşabilirdim.

Bunun yerine judge model’i kendim sarmaladım.

Bu, model çağrısını açık hale getirdi ve DeepEval’i provider seçimi yerine evaluation’a odaklı tuttu.

Küçük bir tasarım tercihi, ama projenin geri kalanının nasıl davranmasını istediğimle uyumlu: kütüphaneler, onları neden dahil ettiysem o kısma sahip olabilir; provider routing benim kontrolümde kalır.

Evaluation suite’im, CairnOps’un “iyi” olduğunu kanıtlayacak kadar büyük değil.

Zaten onu bunun için kullanmıyorum.

Onu regression’ları görünür kılmak ve hangi katmanın önce dikkatimi hak ettiğini söylemesi için kullanıyorum.