Sekiz ay boyunca bir GitHub Actions merge kuyruğunun içinde bulunmak, size özellik karşılaştırma matrislerinin asla öğretemeyeceği bir şey öğretir. Bir framework elli metrik, harika paneller ve saygın araştırma laboratuvarlarından alıntılar sunabilir. Eğer aynı kod üzerinde bir "vibe check" puanı 0,72'den 0,68'e düştüğü için dağıtımınızı engelliyorsa, bu araç işe yaramaz olmaktan daha kötüdür. Teslimat hızınız (shipping velocity) için aktif bir tehdit haline gelir.
Bu, çoğu LLM değerlendirme derlemesinin gözden kaçırdığı filtredir. Onlar yetenekleri sayarlar. Bir merge kuyruğunda önemli olan tek soruyu nadiren sorarlar: Bu kontrol, her çalıştığında tam olarak aynı şekilde mi geçiyor ve kalıyor?
Bunu, rahatsız edici işleri yaparak öğrendim. Altı açık kaynaklı LLM değerlendirme framework'ünü gerçek bir CI boru hattına (pipeline) bağladım. Sekiz ay boyunca canlı üretim pull request'leri üzerinde çalıştılar. İkisi bekçi (gatekeeper) olarak kalma hakkını kazandı. Diğerleri ise tavsiye niteliğinde panellere düşürüldü, gece işlerine (nightly jobs) taşındı veya tamamen kaldırıldı. Ders sert ve pahalıydı: Ana dalı (main branch) korurken deterministik yapı, olasılıksal kaliteden daha üstündür.
Bir Merge Kapısının Gerçek Görevi
Bir CI kapısı bir araştırma ortamı değildir. O bir fedai (bouncer)dir. Tüm amacı belirli bir değişikliğe bakmak ve evet veya hayır cevabını vermektir. Evet, bu PR ana dala katılabilir. Hayır, katılamaz. Bu cevabın saniyeler içinde gelmesi, kuruşlar seviyesinde maliyetinin olması ve asla geriye dönük olarak değişmemesi gerekir. Sakin bir Salı günü ile telaşlı bir Cuma günü aynı commit üzerinde aynı pipeline'ı tekrar çalıştırırsanız, sonuç aynı olmalıdır.
Çoğu LLM değerlendirme framework'ünün tökezlediği nokta burasıdır. Veri bilimciler tarafından veri bilimciler için inşa edilmişlerdir. İçgörü, keşif ve nüanslı puanlama için optimize edilirler. Bir merge kuyruğu ise ikili kararlar, hız ve sıfır kararsızlık (flakiness) için optimize edilir. Bu iki hedef sadece kısmen örtüşür.
LLM-as-Judge Kuyruğu Neden Bozar
Testimde başarısız olan araçlar tek bir tasarım günahında birleşiyordu: Birincil kapı mekanizması olarak LLM-as-judge çağrılarına çok fazla bel bağladılar.
Bir LLM-as-judge istemi (prompt), bir modelden bir çıktıyı bir ile on arasında puanlamasını, iki yanıttan daha iyisini seçmesini veya olgusal doğruluğu derecelendirmesini ister. Bu yaklaşım, kalite trendlerini anlamak için güçlüdür. Ancak engelleyici (blocking) bir CI kontrolü için zehirdir. Aynı girdi, farklı günlerde farklı puanlar üretebilir; çünkü sıcaklık (temperature), model versiyonlama ve istem (prompt) formatlama gibi unsurların tamamı gürültü (noise) yaratır. Bu puan sert bir eşiğe ve sert bir çıkış koduna (exit code) bağlandığında, kuyruğunuz hayaletler yüzünden tıkanır.
Başarısızlıklar hızla zincirleme bir reaksiyon yaratır. Deterministik olmayan bir kontrol, kuyrukta birikmelere yol açar. Mühendisler, sayı uygun bir şekilde gelene kadar tekrar denemeyi öğrenirler; bu da ekibi kırmızı (hatalı) derlemeleri (builds) görmezden gelmeye alıştırır. Her yeniden deneme daha fazla API kredisi tükettiği için token maliyetleri birikir. En kötüsü de sinyal anlamsız hale gelir. Kırmızı bir derleme "bir hata (bug) eklediniz" anlamına gelmelidir. Eğer "hakem model bugün huysuz uyandı" anlamına geliyorsa, güven sarsılır.
Hayatta Kalanlar Neyi Farklı Yapıyor
Promptfoo ve DeepEval hayatta kaldı çünkü deterministik kontrolleri birinci sınıf vatandaşlar, LLM hakem puanlarını ise ikincil ve engelleyici olmayan sinyaller olarak ele alıyorlar. Bir kapının bir görüşü olan kayan noktalı bir sayıya değil, bir çıkış koduna ihtiyacı olduğunu anlıyorlar.
Promptfoo, MIT lisansı altında yayınlanan, komut satırı için oluşturulmuş bir araçtır. Regex eşleşmeleri, JSON şema doğrulaması, içerik kontrolleri ve tam dize karşılaştırmaları gibi iddiaları (assertions) çalıştırır. Bunlar süslü şeyler değil; sadece geliştirilmiş grep ve jq komutlarıdır. CI'da işe yaramalarının nedeni de tam olarak budur. Bir regex ya eşleşir ya da eşleşmez. Bir JSON şeması ya doğrular ya da hata fırlatır. Promptfoo standart Unix çıkış kodlarını döndürür, böylece GitHub Actions bir birleştirmeyi (merge) ne zaman durduracağını doğal olarak anlar. Bir CLI aracı olarak çalıştığı için dilden bağımsızdır (language-agnostic). Çıktıları doğrulamak için sadece bir Node.js servis deposu (repo) içine bir Python ekosistemi kurmanıza gerek kalmaz.
DeepEval, Apache 2.0 lisanslı, Python ekipleri için ideal seçimdir. pytest gibi entegre olur. Testleri tanıdık bir sözdizimiyle (syntax) yazarsınız ve bir hata, test paketini (suite) doğal olarak engeller. DeepEval devasa bir metrik kataloğu sunar, ancak kritik detay onları dikkatli kullanmanız gerektiğidir. Kapılar için deterministik veya sezgisel (heuristic) metriklere güvenin. Eğer G-Eval veya diğer hakem tabanlı puanlayıcıları dahil ediyorsanız, bunları sert doğrulamalar (hard asserts) yerine engelleyici olmayan rapor oluşturucular içine alın. Bu şekilde kullanıldığında DeepEval, size bir araştırma defterinin (notebook) kararsızlığı olmadan bir test framework'ünün ergonomisini sağlar.
Diğer Dördü Nereye Ait
Kapı olarak hayatta kalamayan dört framework hala değerlidir. Sadece araç zincirinizin (toolchain) başka bir yerinde bulunmaları gerekir.
Future AGI (Apache 2.0) ships over fifty metrics and targets teams building custom SDKs. The metrics are thorough. The problem is that the tool expects you to write your own harness to drive it in a CI queue. In a research context, that is a reasonable trade. In a merge queue, every layer of custom wiring is a new source of instability. It is a capable evaluation engine, but not a ready gatekeeper.
RAGAS (Apache 2.0) excels at measuring retrieval-augmented generation quality. Its faithfulness and answer relevance metrics are genuinely useful for understanding how a knowledge base performs over time. Unfortunately, those metrics lean heavily on LLM judges. They are excellent for a nightly quality job that posts trends to Slack. They are poor bouncers for a pull request. Move RAGAS to your scheduled analysis pipeline, not your merge blockers.
Arize Phoenix carries the Elastic License 2.0 and sits at a different intersection entirely. It connects distributed tracing with evaluation, giving you observability into why a model behaved a certain way. You want this when you are debugging a production incident or tracing a hallucination back to a bad retrieval chunk. You do not want a tracing tool deciding whether a junior developer’s feature branch can ship. Its architecture is built for insight, not binary gates.
MLflow Evaluate (Apache 2.0) inherits its pedigree from experiment tracking. It is heavy. Pulling it into a lean CI image adds startup time and dependencies that slow down every single job. If you absolutely must use it inside a pipeline, stick to its heuristic metrics for structural checks. Even then, you are fighting the framework’s fundamental design. MLflow wants to log runs and compare experiments across weeks. A merge queue wants a verdict in under a minute.
Practical Rules for Gating
If you take nothing else from this experiment, take these three rules.
First, gate structure, not vibe. You can enforce that an output is valid JSON. You can enforce that it contains required keys. You can enforce that a classification label belongs to an allowed enum. These checks are fast, cheap, and deterministic. You cannot reliably enforce that a summary is "friendly" or that a rewrite is "creative." Those qualities belong in human review or periodic batch evaluation, not in automated gates.
Second, if a score moves on unchanged input, demote it immediately. Run your evaluation suite twice against the exact same artifact. If any metric flips from pass to fail, it has lost its right to block a merge. Promote it to an advisory dashboard where variance is expected and tolerable.
Third, respect the exit code. A pretty HTML report with a red banner does not stop a merge. A nonzero exit code does. Your evaluation tool must speak the native language of your CI platform. Standard out is for humans. Exit codes are for machines.
The Takeaway
We are still early in figuring out how to test LLM-powered applications. The temptation is to treat evaluation like a human grading rubric: nuanced, contextual, and slightly subjective. That works in a research paper. It collapses in a merge queue.
After eight months of production traffic, my pipeline now runs Promptfoo for structural and schema assertions across services, and DeepEval for Python-side behavioral checks that map cleanly to pass-fail conditions. Everything else reports to nightly dashboards. The queue is stable. The signal is clean. The team trusts a red build again.
You do not need more metrics at your gate. You need fewer metrics that tell the truth every single time.
Based on original testing and write-up shared on Dev.to. For more discussions on building reliable AI systems, join the GyaanSetu community on Telegram.
