Lapan bulan di dalam barisan penggabungan (merge queue) GitHub Actions mengajar anda sesuatu yang tidak akan pernah diajarkan oleh matriks perbandingan ciri. Sebuah rangka kerja boleh menawarkan lima puluh metrik, papan pemuka yang cantik, dan petikan daripada makmal penyelidikan yang dihormati. Jika ia menyekat penggunaan (deploy) anda kerana skor "vibe check" berubah daripada 0.72 kepada 0.68 terhadap kod yang sama, ia lebih buruk daripada tidak berguna. Ia menjadi ancaman aktif kepada kepantasan penghantaran (shipping velocity) anda.
Itulah penapis yang sering terlepas pandang oleh kebanyakan ringkasan penilaian LLM. Mereka mengira keupayaan. Mereka jarang bertanya satu-satunya soalan yang penting dalam barisan penggabungan: adakah semakan ini lulus dan gagal dengan cara yang sama tepat setiap kali ia dijalankan?
Saya mempelajari perkara ini melalui kerja yang mencabar. Saya menyambungkan enam rangka kerja penilaian LLM sumber terbuka ke dalam saluran paip (pipeline) CI yang sebenar. Ia dijalankan terhadap permintaan tarik (pull request) pengeluaran secara langsung selama lapan bulan. Dua daripadanya layak kekal sebagai penjaga pintu (gatekeepers). Selebihnya diturunkan pangkat kepada papan pemuka penasihat, dipindahkan ke tugasan malam (nightly jobs), atau dibuang sepenuhnya. Pengajarannya sangat pedas dan mahal: struktur deterministik mengatasi kualiti probabilistik apabila anda sedang menjaga cawangan utama (main branch).
Tugas Sebenar Penjaga Penggabungan (Merge Gate)
Penjaga CI bukanlah persekitaran penyelidikan. Ia adalah seorang pengawal pintu (bouncer). Seluruh tujuannya adalah untuk melihat perubahan tertentu dan menjawab ya atau tidak. Ya, PR ini boleh menyertai cawangan utama. Tidak, ia tidak boleh. Jawapan itu perlu sampai dalam masa beberapa saat, menelan kos yang sangat rendah, dan tidak pernah berubah secara retroaktif. Jika anda menjalankan semula saluran paip yang sama terhadap komit yang sama pada hari Selasa yang tenang dan hari Jumaat yang sibuk, hasilnya mestilah serupa.
Di sinilah kebanyakan rangka kerja penilaian LLM tersandung. Ia dibina oleh saintis data untuk saintis data. Ia dioptimumkan untuk wawasan, penerokaan, dan pemarkahan yang bernuansa. Barisan penggabungan pula dioptimumkan untuk keputusan binari, kelajuan, dan sifar ketidaktentuan (flakiness). Kedua-dua matlamat ini hanya bertindih sebahagian sahaja.
Mengapa LLM-as-Judge Merosakkan Barisan Penggabungan
Alatan yang gagal dalam ujian saya berkongsi satu dosa reka bentuk yang sama: mereka terlalu bergantung pada panggilan LLM-as-judge sebagai mekanisme penjaga utama.
Prompt LLM-as-judge meminta model untuk memberi skor pada output pada skala satu hingga sepuluh, atau memilih yang lebih baik antara dua respons, atau menilai ketepatan fakta. Pendekatan ini berkuasa untuk memahami trend kualiti. Namun, ia adalah racun bagi semakan CI yang menyekat (blocking). Input yang sama boleh menghasilkan skor yang berbeza pada hari yang berbeza kerana suhu (temperature), versi model, dan format prompt semuanya memperkenalkan hingar (noise). Apabila skor tersebut terikat pada ambang (threshold) yang tetap dan kod keluar (exit code) yang tetap, barisan penggabungan anda akan tersekat disebabkan oleh "hantu" (ketidaktentuan).
Kegagalan berlaku secara berantai dengan cepat. Semakan nondeterministik mewujudkan kesesakan barisan. Jurutera belajar untuk mencuba semula sehingga nombor tersebut memberikan keputusan yang memihak kepada mereka, yang mana ini melatih pasukan untuk mengabaikan binaan (build) berwarna merah. Kos token meningkat kerana setiap percubaan semula membakar lebih banyak kredit API. Yang paling teruk, isyarat tersebut menjadi tidak bermakna. Binaan merah sepatutnya bermaksud "anda telah memperkenalkan pepijat (bug)." Jika ia bermaksud "model hakim sedang cerewet hari ini," kepercayaan akan terhakis.
Apa yang Dilakukan Secara Berbeza oleh Yang Terselamat
Promptfoo dan DeepEval terselamat kerana mereka menganggap semakan deterministik sebagai keutamaan (first-class citizens) dan skor hakim LLM sebagai isyarat sekunder yang tidak menyekat. Mereka memahami bahawa penjaga pintu memerlukan kod keluar, bukannya nombor titik apung (floating-point number) yang mempunyai pendapat sendiri.
Promptfoo, yang dikeluarkan di bawah lesen MIT, dibina untuk baris arahan (command line). Ia menjalankan pengesahan (assertions) seperti padanan regex, pengesahan skema JSON, semakan kandungan, dan perbandingan rentetan tepat. Ini bukanlah sesuatu yang canggih. Ia hanyalah arahan grep dan jq yang dipertingkatkan. Itulah sebabnya ia berfungsi dalam CI. Regex sama ada sepadan atau tidak. Skema JSON sama ada sah atau ia akan mengeluarkan ralat. Promptfoo mengembalikan kod keluar Unix standard, jadi GitHub Actions memahami secara asli bila perlu menghentikan penggabungan. Ia bersifat agnostik bahasa kerana ia beroperasi sebagai alat CLI. Anda tidak perlu memasang ekosistem Python di dalam repo perkhidmatan Node.js hanya untuk mengesahkan output.
DeepEval, dilesenkan di bawah Apache 2.0, adalah pilihan untuk pasukan Python. Ia berintegrasi seperti pytest. Anda menulis ujian dalam sintaks yang biasa, dan kegagalan akan menyekat suite tersebut secara semula jadi. DeepEval menawarkan katalog metrik yang besar, tetapi butiran kritikalnya ialah anda mesti menggunakannya dengan berhati-hati. Bergantunglah pada metrik deterministik atau heuristik untuk penjaga pintu. Jika anda menggunakan G-Eval atau penyaring berasaskan hakim yang lain, bungkus ia dalam penjana laporan yang tidak menyekat berbanding pengesahan keras (hard asserts). Apabila digunakan dengan cara ini, DeepEval memberikan anda ergonomik rangka kerja ujian tanpa ketidaktentuan buku nota penyelidikan.
Di Mana Kedudukan Empat yang Lain
Empat rangka kerja yang tidak terselamat sebagai penjaga pintu masih mempunyai nilai. Ia hanya perlu diletakkan di tempat lain dalam rantaian alatan (toolchain) anda.
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.
