מפתחים יכולים כעת לשמור על עלות תיקון JSON לא תקין ממודלי שפה גדולים (LLMs) תחת שליטה על ידי הגבלת ניסיונות התיקון לשניים, כפי שמראה לולאת Python פשוטה. התבנית — יצירה, ניתוח (parse), אימות, ניסיון חוזר, ואז קבלה או כישלון — הופכת "JSON שאולי תקין" לשיעור הצלחה מדיד ומונעת שימוש בלתי מבוקר בטוקנים (tokens).

למה לולאת תיקון היא חשובה

לעיתים קרובות מנחים LLMs "להחזיר JSON", אך הפלט מכיל לעיתים קרובות שגיאות תחביר, מפתחות חסרים או ערכים ששוברים כללי עסקה. מערכת המשך (downstream system) המצפה לפרוטוקול (payload) קשיח תקרוס או תפיק תוצאות שגויות אם יוזן לה פלט כזה. ללא דרך שיטתית לזהות ולתקן את הבעיות הללו, צוותים או שיקבלו שיעור כישלון גבוה, או שיבזבזו כסף על הנחיית המודל שוב ושוב עד שיצליח.

שלוש שכבות האימות

לולאה אמינה מפרידה את האימות ל:

  • תחביר (Syntax) – האם המחרוזת בכלל ניתנת לניתוח (parse) כ-JSON?
  • מבנה (Shape) – האם האובייקט ברמת העל מכיל בדיוק את המפתחות הצפויים?
  • סמנטיקה (Semantic) – האם הערכים מכבדים אילוצי דומיין (למשל, "category" חייב להשתייך לקבוצה מוגדרת מראש)?

על ידי עצירה בשכבה הראשונה שנכשלת, הלולאה יכולה לספק למודל הודעת שגיאה מדויקת, מה שמשפר דרמטית את הסיכויים לתיקון נכון בניסיון הבא.

דוגמת Python מינימלית

הקוד הבא משתמש בספרייה הסטנדרטית בלבד. הוא מגדיר סכימה קטנה (מילון עם מפתחות category ו-summary) ורשימה קבועה של קטגוריות מותרות.

import json

CATEGORIES = {"bug", "feature", "question"}

def validate(raw: str):
    try:
        value = json.loads(raw)
    except json.JSONDecodeError as exc:
        return None, f"syntax: {exc.msg}"

    if not isinstance(value, dict):
        return None, "shape: root must be an object"
    if set(value) != {"category", "summary"}:
        return None, "shape: expected category and summary"
    if value["category"] not in CATEGORIES:
        return None, "semantic: invalid category"
    if not isinstance(value["summary"], str) or not value["summary"].strip():
        return None, "semantic: summary must be text"

    return value, None

לולאת התיקון עצמה מציבה תקרה קשיחה למספר הניסיונות:

MAX_ATTEMPTS = 2
raw = model_response   # initial LLM output

for attempt in range(MAX_ATTEMPTS + 1):
    value, error = validate(raw)
    if error is None:
        break
    if attempt == MAX_ATTEMPTS:
        raise RuntimeError(f"failed after {MAX_ATTEMPTS} retries: {error}")

    # Send the error and schema back to the model for a fix
    raw = ask_model_to_repair(raw, error)

אם ה-JSON עובר אימות במעבר הראשון, הלולאה יוצאת מיד. אחרת, היא מנסה שוב, ומזינה למודל payload תמציתי: הפלט המקורי, מחרוזת השגיאה המדויקת והסכימה הצפויה. לאחר שני ניסיונות כושלים, התהליך נפסק עם חריגה (exception) ברורה.

שני כללים לתיקונים חסכוניים

  1. שמרו על הנחיות (prompts) תיקון תמציתיות – כללו רק את ה-JSON הגולמי, הודעת השגיאה והסכימה. הוספת היסטוריית צ'אט ארוכה מנפחת את השימוש בטוקנים ועלולה לבלבל את המודל, מה שמעלה את העלות לכל ניסיון חוזר מבלי לשפר את הדיוק.

  2. פרידו בין אימות לבדיקת עובדות – ה-parser יכול לזהות בעיות מבניות, אך הוא אינו יכול לאמת אם הצהרת "summary" היא נכונה. בדיקת עובדות שייכת לשלב מאוחר יותר; ניסיון "לתקן" טענה שקרית רק גורם לשקר להיראות נקי יותר.

מדידת הצלחה

רישום (logging) של סוג השגיאה בכל ניסיון (תחביר, מבנה, סמנטיקה) והאם הלולאה הצליחה מספק מדד קונקרטי: היחס של תגובות LLM שהופכות לשימושיות במסגרת מספר הניסיונות המוגבל. צוותים יכולים לעקוב אחר כך לאורך זמן, להשוות סגנונות הנחיה (prompt styles), או להתנסות בהגדרות סכימה שונות.

חסרונות פוטנציאליים

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

מה כדאי לעקוב אחריו בהמשך

  • הנדסת פרומפטים (Prompt engineering) לצורך תיקון – ליטוש פורמט הודעת השגיאה יכול להפחית את מספר הניסיונות החוזרים הנדרשים.
  • parsers חלופיים – חלק מהספריות מספקות ניתוח (parsing) סלחני שיכול לתקן אוטומטית בעיות קטנות; השוואת העלות שלהן מול לולאה מוגבלת היא כדאית.
  • עדכוני מודלים – גרסאות LLM חדשות יותר עשויות להפיק JSON נקי יותר "מהקופסה", מה שעשוי לאפשר להוריד עוד יותר את מגבלת הניסיונות החוזרים.

לולאת תיקון JSON מוגבלת מעניקה למפתחים כלי פרקטי להפוך פלט LLM מעורפל לנתונים אמינים מבלי שהעלויות יצאו משליטה. על ידי התייחסות לאימות כשלב מרכזי (first-class step) והגבלת ניסיונות חוזרים, צוותים יכולים לשמור על תקציבים ועל מערכות המשך מרוצים.