שמונה חודשים בתוך תור מיזוג (merge queue) של GitHub Actions מלמדים אותך משהו שמאטריצות השוואת תכונות לעולם לא יוכלו ללמד. פריימוורק יכול לספק חמישים מדדים, דאשבורדים מרהיבים וציטוטים ממעבדות מחקר מכובדות. אם הוא חוסם את הפריסה (deploy) שלך כי ציון "vibe check" נדחף מ-0.72 ל-0.68 מול קוד זהה, הוא גרוע יותר מחסר תועלת. הוא הופך לאיום פעיל על מהירות השחרור (shipping velocity) שלך.

זהו המסנן שרוב סקירות הערכת ה-LLM מפספסות. הן סופרות יכולות. הן כמעט אף פעם לא שואלות את השאלה היחידה שחשובה בתור מיזוג: האם הבדיקה הזו עוברת ונכשלת בדיוק באותו אופן בכל פעם שהיא רצה?

למדתי את זה על ידי ביצוע העבודה הלא נוחה. חיברתי שישה פריימוורקים להערכת LLM בקוד פתוח לתהליך CI אמיתי. הם רצו מול pull requests בייצור (production) במשך שמונה חודשים. שניים זכו בזכות להישאר כשומרי סף (gatekeepers). השאר הועברו לדאשבורדים מייעצים, למשימות ליליות (nightly jobs), או הוסרו לחלוטין. השיעור היה חד ומשמעותי: מבנה דטרמיניסטי מנצח איכות הסתברותית כשאתה שומר על ה-main branch.

התפקיד האמיתי של שומר סף מיזוג (Merge Gate)

שומר סף CI הוא לא סביבת מחקר. הוא מאבטח (bouncer). המטרה כולה שלו היא להסתכל על שינוי ספציפי ולענות כן או לא. כן, ה-PR הזה יכול להצטרף ל-main branch. לא, הוא לא יכול. התשובה הזו צריכה להגיע תוך שניות, לעלות שקלים בודדים, ולעולם לא להשתנות רטרואקטיבית. אם תריץ שוב את אותו pipeline מול אותו commit ביום שלישי שקט וביום שישי לחוץ, התוצאה חייבת להיות זהה.

כאן רוב פריימוורקי הערכת ה-LLM נתקעים. הם נבנו על ידי מדעני נתונים עבור מדעני נתונים. הם עושים אופטימיזציה לתובנות, חקירה ודירוג מורכב (nuanced scoring). תור מיזוג עושה אופטימיזציה להחלטות בינאריות, מהירות ואפס flakiness (חוסר יציבות). שני היעדים הללו חופפים רק חלקית.

למה LLM-as-Judge שובר את התור

הכלים שנכשלו בבדיקה שלי חלקו חטא עיצובי אחד: הם הסתמכו יותר מדי על קריאות LLM-as-judge כמנגנון שומר הסף העיקרי.

פרומפט של LLM-as-judge מבקש ממודל לדרג פלט בסולם של אחת עד עשר, או לבחור את התגובה הטובה יותר מבין שתיים, או לדרג נכונות עובדתית. הגישה הזו חזקה להבנת מגמות איכות. היא רעל עבור בדיקת CI חוסמת. אותו קלט יכול להפיק ציונים שונים בימים שונים מכיוון ש-temperature, גרסאות מודל ופורמט הפרומפט כולם מכניסים רעש. כשציון זה קשור לסף קשיח ולקוד יציאה (exit code) קשיח, התור שלך נחסם בגלל "רוחות רפאים".

הכשלים נערמים במהירות. בדיקה לא-דטרמיניסטית יוצרת עומסים בתור. מהנדסים לומדים לנסות שוב ושוב עד שהמספר יוצא לטובתם, מה שמאלף את הצוות להתעלם מ-builds אדומים. עלויות ה-tokens מצטברות כי כל ניסיון חוזר שורף יותר קרדיטים של API. גרוע מכל, האות (signal) הופך לחסר משמעות. build אדום אמור להביע "הכנסת באג". אם המשמעות היא "מודל השופט התעורר היום ברגישות גבוהה מדי", האמון נשחק.

מה השורדים עושים אחרת

Promptfoo ו-DeepEval שרדו כי הם מתייחסים לבדיקות דטרמיניסטיות כאזרחים מדרגה ראשונה ולציוני LLM judge כאותות משניים שאינם חוסמים. הם מבינים ששומר סף זקוק לקוד יציאה, לא למספר floating-point עם דעה משלו.

Promptfoo, ששוחרר תחת רישיון MIT, בנוי עבור שורת הפקודה (command line). הוא מריץ assertions כמו התאמות regex, אימות JSON schema, בדיקות contains והשוואות מחרוזות מדויקות. אלו אינם דברים מתוחכמים. אלו פקודות grep ו-jq משודרגות. זו בדיוק הסיבה שהם עובדים ב-CI. regex או מתאים או לא. JSON schema או מאמת או זורק שגיאה. Promptfoo מחזיר קודי יציאה סטנדרטיים של Unix, כך ש-GitHub Actions מבינים באופן טבעי מתי להפסיק מיזוג. הוא בלתי תלוי בשפה (language-agnostic) כי הוא פועל ככלי CLI. אין צורך להתקין אקוסיסטם של Python בתוך רפו של שירות Node.js רק כדי לאמת פלטים.

DeepEval, המורשה תחת Apache 2.0, הוא הבחירה עבור צוותי Python. הוא משתלב כמו pytest. אתם כותבים טסטים בתחביר מוכר, וכשל חוסם את ה-suite באופן טבעי. DeepEval מציע קטלוג עצום של מדדים, אך הפרט הקריטי הוא שעליכם להשתמש בהם בזהירות. הישענו על מדדים דטרמיניסטיים או היוריסטיים עבור שומרי סף. אם אתם משתמשים ב-G-Eval או במדרגים אחרים מבוססי שופט, עטפו אותם במחוללי דוחות שאינם חוסמים במקום ב-hard asserts. כשמשתמשים בו כך, DeepEval מעניק לכם את הארגונומיה של פריימוורק בדיקות ללא ה-flakiness של מחברת מחקר (research notebook).

איפה ארבעת האחרים משתלבים

לארבעת הפריימוורקים שלא שרדו כשומרי סף יש עדיין ערך. הם פשוט שייכים למקום אחר בשרשרת הכלים (toolchain) שלכם.

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.