توسعه‌دهندگان اکنون می‌توانند با محدود کردن تلاش‌های اصلاح به دو مورد، هزینه اصلاح JSON نامعتبر تولید شده توسط مدل‌های زبانی بزرگ (LLMs) را تحت کنترل نگه دارند؛ یک حلقه ساده در پایتون این موضوع را نشان می‌دهد. این الگو — تولید، تجزیه (parse)، اعتبارسنجی، تلاش مجدد، و سپس پذیرش یا شکست — «JSON احتمالا معتبر» را به یک نرخ موفقیت قابل اندازه‌گیری تبدیل کرده و از مصرف بی‌رویه توکن‌ها جلوگیری می‌کند.

چرا یک حلقه اصلاح اهمیت دارد

مدل‌های زبانی بزرگ اغلب دستور می‌گیرند که «JSON برگردان»، اما خروجی‌ها مکرراً حاوی خطاهای سینتکس، کلیدهای مفقود یا مقادیری هستند که قوانین کسب‌وکار را نقض می‌کنند. یک سیستم پایین‌دست که انتظار یک پِی‌لود (payload) دقیق را دارد، در صورت دریافت چنین خروجی‌هایی، کرش می‌کند یا نتایج اشتباه تولید می‌کند. بدون یک روش سیستماتیک برای شناسایی و اصلاح این مشکلات، تیم‌ها یا با نرخ شکست بالا مواجه می‌شوند و یا با تکرار مکرر پرامپت‌ها تا رسیدن به نتیجه صحیح، هزینه اضافی متحمل می‌شوند.

سه لایه اعتبارسنجی

یک حلقه قابل اعتماد، اعتبارسنجی را به این بخش‌ها تقسیم می‌کند:

  • Syntax (نحو) – آیا رشته اصلاً به عنوان JSON قابل تجزیه است؟
  • Shape (ساختار) – آیا شیء سطح بالا دقیقاً شامل کلیدهای مورد انتظار است؟
  • Semantic (معنایی) – آیا مقادیر از محدودیت‌های دامنه پیروی می‌کنند (برای مثال، یک "category" باید متعلق به یک مجموعه از پیش تعریف شده باشد)؟

با توقف در اولین لایه شکست‌خورده، حلقه می‌تواند پیام خطای دقیقی به مدل ارائه دهد که شانس اصلاح صحیح در تلاش بعدی را به طرز چشمگیری افزایش می‌دهد.

نمونه پایتون حداقلی

کد زیر تنها از کتابخانه استاندارد استفاده می‌کند. این کد یک شمای (schema) کوچک (یک دیکشنری با کلیدهای 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 در اولین مرحله از اعتبارسنجی عبور کند، حلقه بلافاصله خارج می‌شود. در غیر این صورت، تلاش مجدد انجام شده و یک پِی‌لود مختصر به مدل داده می‌شود: خروجی اصلی، رشته دقیق خطا و شمای مورد انتظار. پس از دو تلاش ناموفق، فرآیند با یک استثنا (exception) واضح متوقف می‌شود.

دو قانون برای اصلاح‌های مقرون‌به‌صرفه

  1. پرامپت‌های اصلاح را مختصر نگه دارید – فقط شامل JSON خام، پیام خطا و شمای مربوطه باشد. اضافه کردن تاریخچه طولانی چت باعث افزایش مصرف توکن می‌شود و می‌تواند مدل را گیج کند و بدون بهبود دقت، هزینه هر تلاش مجدد را بالا ببرد.

  2. اعتبارسنجی را از راستی‌آزمایی جدا کنید – تجزیه‌کننده (parser) می‌تواند مشکلات ساختاری را تشخیص دهد، اما نمی‌تواند تأیید کند که یک بیانیه "summary" درست است یا خیر. راستی‌آزمایی مربوط به مرحله بعدی است؛ تلاش برای «اصلاح» یک ادعای نادرست، صرفاً باعث می‌شود آن دروغ تمیزتر به نظر برسد.

اندازه‌گیری موفقیت

ثبت نوع خطا در هر تلاش (syntax، shape، semantic) و اینکه آیا حلقه موفق بوده است یا خیر، یک معیار ملموس به دست می‌دهد: نسبت پاسخ‌های LLM که در محدوده تلاش‌های تعیین‌شده، قابل استفاده می‌شوند. تیم‌ها می‌توانند این مورد را در طول زمان ردیابی کنند، سبک‌های پرامپت را با هم مقایسه کنند یا با تعاریف مختلف شمای آزمایش کنند.

معایب احتمالی

محدود کردن حلقه به این معناست که برخی از خروجی‌های نامعتبر پس از رسیدن به حد مجاز دور ریخته می‌شوند، که اگر کیفیت خام مدل پایین باشد، ممکن است نرخ شکست کلی را افزایش دهد. در محیط‌هایی که هر پاسخ حیاتی است، توسعه‌دهندگان ممکن است سقف تلاش مجدد بالاتری را به قیمت مصرف توکن‌های اضافی ترجیح دهند. این یک معامله (trade-off) صریح است: هزینه بیشتر برای پوشش بالاتر، یا بودجه‌های محدودتر با یک سقف قابل پیش‌بینی.

آنچه باید در ادامه زیر نظر داشت

  • مهندسی پرامپت برای اصلاح – اصلاح قالب پیام خطا می‌تواند تعداد تلاش‌های مجدد مورد نیاز را کاهش دهد.
  • تجزیه‌کننده‌های جایگزین – برخی کتابخانه‌ها تجزیه منعطفی را ارائه می‌دهند که می‌تواند مشکلات جزئی را خودکار اصلاح کند؛ مقایسه هزینه آن‌ها در مقابل یک حلقه محدود شده ارزشمند است.
  • به‌روزرسانی‌های مدل – نسخه‌های جدیدتر LLM ممکن است JSON تمیزتری را به صورت پیش‌فرض تولید کنند که پتانسیل کاهش بیشتر حد تلاش مجدد را فراهم می‌کند.

یک حلقه محدود شده‌ی اصلاح JSON، ابزاری کاربردی در اختیار توسعه‌دهندگان قرار می‌دهد تا خروجی‌های مبهم LLM را بدون افزایش تصاعدی هزینه‌ها، به داده‌های قابل اعتماد تبدیل کنند. با در نظر گرفتن اعتبارسنجی به عنوان یک مرحله اصلی و محدود کردن تلاش‌های مجدد، تیم‌ها می‌توانند هم بودجه‌ها و هم سیستم‌های پایین‌دست را راضی نگه دارند.