ਡਿਵੈਲਪਰ ਹੁਣ ਰਿਪੇਅਰ ਕੋਸ਼ਿਸ਼ਾਂ ਨੂੰ ਦੋ 'ਤੇ ਸੀਮਤ ਕਰਕੇ, ਲਾਰਜ ਲੈਂਗੂਏਜ ਮਾਡਲਾਂ (LLMs) ਤੋਂ ਗਲਤ (malformed) JSON ਨੂੰ ਠੀਕ ਕਰਨ ਦੀ ਲਾਗਤ ਨੂੰ ਕੰਟਰੋਲ ਵਿੱਚ ਰੱਖ ਸਕਦੇ ਹਨ, ਇੱਕ ਸਧਾਰਨ Python ਲੂਪ ਇਹ ਦਿਖਾਉਂਦਾ ਹੈ। ਇਹ ਪੈਟਰਨ—ਜਨਰੇਟ ਕਰਨਾ, ਪਾਰਸ ਕਰਨਾ, ਵੈਲੀਡੇਟ ਕਰਨਾ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨਾ, ਫਿਰ ਸਵੀਕਾਰ ਕਰਨਾ ਜਾਂ ਫੇਲ ਹੋਣਾ—"ਸ਼ਾਇਦ-ਵੈਲਡ JSON" ਨੂੰ ਇੱਕ ਮਾਪਣਯੋਗ ਸਫਲਤਾ ਦਰ ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ ਅਤੇ ਟੋਕਨ ਦੀ ਬੇਲੋਗਤ ਵਰਤੋਂ ਨੂੰ ਰੋਕਦਾ ਹੈ।

ਰਿਪੇਅਰ ਲੂਪ ਕਿਉਂ ਮਹੱਤਵਪੂਰਨ ਹੈ

LLMs ਨੂੰ ਅਕਸਰ "JSON ਰਿਟਰਨ ਕਰੋ" ਦੇ ਨਿਰਦੇਸ਼ ਦਿੱਤੇ ਜਾਂਦੇ ਹਨ, ਫਿਰ ਵੀ ਆਉਟਪੁੱਟ ਵਿੱਚ ਅਕਸਰ ਸਿੰਟੈਕਸ ਗਲਤੀਆਂ, ਗੁੰਮ ਹੋਈਆਂ ਕੀਜ਼ (keys), ਜਾਂ ਅਜਿਹੀਆਂ ਵੈਲਯੂਜ਼ ਹੁੰਦੀਆਂ ਹਨ ਜੋ ਬਿਜ਼ਨਸ ਨਿਯਮਾਂ ਨੂੰ ਤੋੜਦੀਆਂ ਹਨ। ਇੱਕ ਡਾਊਨਸਟ੍ਰੀਮ ਸਿਸਟਮ ਜੋ ਸਖ਼ਤ ਪੇਲੋਡ (payload) ਦੀ ਉਮੀਦ ਕਰਦਾ ਹੈ, ਜੇਕਰ ਅਜਿਹਾ ਆਉਟਪੁੱਟ ਮਿਲੇ ਤਾਂ ਕ੍ਰੈਸ਼ ਹੋ ਜਾਵੇਗਾ ਜਾਂ ਗਲਤ ਨਤੀਜੇ ਦੇਵੇਗਾ। ਇਹਨਾਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਫੜਨ ਅਤੇ ਸੁਧਾਰਨ ਦੇ ਯੋਜਨਾਬੱਧ ਤਰੀਕੇ ਤੋਂ ਬਿਨਾਂ, ਟੀਮਾਂ ਜਾਂ ਤਾਂ ਉੱਚ ਅਸਫਲਤਾ ਦਰ ਨੂੰ ਸਵੀਕਾਰ ਕਰਦੀਆਂ ਹਨ ਜਾਂ ਮਾਡਲ ਨੂੰ ਉਦੋਂ ਤੱਕ ਵਾਰ-ਵਾਰ ਪ੍ਰੋਂਪਟ ਕਰਕੇ ਪੈਸੇ ਬਰਬਾਦ ਕਰਦੀਆਂ ਹਨ ਜਦੋਂ ਤੱਕ ਇਹ ਸਹੀ ਨਹੀਂ ਹੋ ਜਾਂਦਾ।

ਤਿੰਨ ਵੈਲੀਡੇਸ਼ਨ ਲੇਅਰਾਂ

ਇੱਕ ਭਰੋਸੇਯੋਗ ਲੂਪ ਵੈਲੀਡੇਸ਼ਨ ਨੂੰ ਇਹਨਾਂ ਵਿੱਚ ਵੰਡਦਾ ਹੈ:

  • Syntax – ਕੀ ਸਟ੍ਰਿੰਗ ਅਸਲ ਵਿੱਚ JSON ਵਜੋਂ ਪਾਰਸ ਹੁੰਦੀ ਹੈ?
  • Shape – ਕੀ ਟਾਪ-ਲੈਵਲ ਆਬਜੈਕਟ ਵਿੱਚ ਬਿਲਕੁਲ ਉਮੀਦ ਕੀਤੀਆਂ ਕੀਜ਼ ਹਨ?
  • Semantic – ਕੀ ਵੈਲਯੂਜ਼ ਡੋਮੇਨ ਦੀਆਂ ਸੀਮਾਵਾਂ ਦਾ ਪਾਲਣ ਕਰਦੀਆਂ ਹਨ (ਉਦਾਹਰਨ ਲਈ, ਇੱਕ “category” ਇੱਕ ਪਹਿਲਾਂ ਤੋਂ ਨਿਰਧਾਰਤ ਸੈੱਟ ਨਾਲ ਸਬੰਧਤ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ)?

ਪਹਿਲੀ ਅਸਫਲ ਲੇਅਰ 'ਤੇ ਰੁਕ ਕੇ, ਲੂਪ ਮਾਡਲ ਨੂੰ ਇੱਕ ਸਹੀ ਗਲਤੀ ਸੁਨੇਹਾ (error message) ਦੇ ਸਕਦਾ ਹੈ, ਜੋ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ 'ਤੇ ਸਹੀ ਸੁਧਾਰ ਦੀ ਸੰਭਾਵਨਾ ਨੂੰ ਬਹੁਤ ਵਧਾ ਦਿੰਦਾ ਹੈ।

ਮਿਨੀਮਲ 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 ਪਹਿਲੀ ਵਾਰ ਵਿੱਚ ਹੀ ਵੈਲੀਡੇਸ਼ਨ ਪਾਸ ਕਰ ਲੈਂਦਾ ਹੈ, ਤਾਂ ਲੂਪ ਤੁਰੰਤ ਬਾਹਰ ਨਿਕਲ ਜਾਂਦਾ ਹੈ। ਨਹੀਂ ਤਾਂ ਇਹ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ, ਮਾਡਲ ਨੂੰ ਇੱਕ ਸੰਖੇਪ ਪੇਲੋਡ ਦਿੰਦਾ ਹੈ: ਅਸਲ ਆਉਟਪੁੱਟ, ਸਹੀ ਗਲਤੀ ਸਟ੍ਰਿੰਗ, ਅਤੇ ਉਮੀਦ ਕੀਤਾ ਸਕੀਮਾ। ਦੋ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ ਪ੍ਰਕਿਰਿਆ ਇੱਕ ਸਪਸ਼ਟ ਐਕਸੈਪਸ਼ਨ (exception) ਦੇ ਨਾਲ ਰੁਕ ਜਾਂਦੀ ਹੈ।

ਲਾਗਤ-ਪ੍ਰਭਾਵਸ਼ਾਲੀ ਰਿਪੇਅਰ ਲਈ ਦੋ ਨਿਯਮ

  1. ਰਿਪੇਅਰ ਪ੍ਰੋਂਪਟ ਨੂੰ ਸੰਖੇਪ ਰੱਖੋ – ਸਿਰਫ ਰਅਅ (raw) JSON, ਗਲਤੀ ਦਾ ਸੁਨੇਹਾ, ਅਤੇ ਸਕੀਮਾ ਸ਼ਾਮਲ ਕਰੋ। ਲੰਬੀ ਚੈਟ ਹਿਸਟਰੀ ਜੋੜਨ ਨਾਲ ਟੋਕਨ ਦੀ ਵਰਤੋਂ ਵਧ ਜਾਂਦੀ ਹੈ ਅਤੇ ਇਹ ਮਾਡਲ ਨੂੰ ਉਲਝਾ ਸਕਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਸਹੀ ਹੋਣ ਦੀ ਸੰਭਾਵਨਾ ਵਧੇ ਬਿਨਾਂ ਹਰ ਰਿਟਰਾਈ ਦੀ ਲਾਗਤ ਵਧ ਜਾਂਦੀ ਹੈ।

  2. ਵੈਲੀਡੇਸ਼ਨ ਨੂੰ ਫੈਕਟ-ਚੈਕਿੰਗ ਤੋਂ ਵੱਖ ਰੱਖੋ – ਪਾਰਸਰ (parser) ਸੰਰਚਨਾਤਮਕ ਸਮੱਸਿਆਵਾਂ ਦਾ ਪਤਾ ਲਗਾ ਸਕਦਾ ਹੈ, ਪਰ ਇਹ ਪੁਸ਼ਟੀ ਨਹੀਂ ਕਰ ਸਕਦਾ ਕਿ “summary” ਕਥਨ ਸੱਚਾ ਹੈ। ਫੈਕਟ-ਚੈਕਿੰਗ ਬਾਅਦ ਦੇ ਪੜਾਅ ਵਿੱਚ ਆਉਂਦੀ ਹੈ; ਕਿਸੇ ਗਲਤ ਦਾਅਵੇ ਨੂੰ “ਠੀਕ” ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਨਾਲ ਸਿਰਫ ਝੂਠ ਵਧੇਰੇ ਸਾਫ਼ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ।

ਸਫਲਤਾ ਨੂੰ ਮਾਪਣਾ

ਹਰੇਕ ਕੋਸ਼ਿਸ਼ ਦੀ ਗਲਤੀ ਦੀ ਕਿਸਮ (syntax, shape, semantic) ਅਤੇ ਕੀ ਲੂਪ ਸਫਲ ਰਿਹਾ, ਇਸ ਨੂੰ ਲੌਗ ਕਰਨਾ ਇੱਕ ਠੋਸ ਮੈਟ੍ਰਿਕ ਦਿੰਦਾ ਹੈ: ਸੀਮਤ ਰਿਟਰਾਈਜ਼ ਦੇ ਅੰਦਰ ਵਰਤੋਂ ਯੋਗ ਬਣਨ ਵਾਲੇ LLM ਜਵਾਬਾਂ ਦਾ ਅਨੁਪਾਤ। ਟੀਮਾਂ ਸਮੇਂ ਦੇ ਨਾਲ ਇਸ ਨੂੰ ਟ੍ਰੈਕ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਪ੍ਰੋਂਪਟ ਸ਼ੈਲੀਆਂ ਦੀ ਤੁਲਨਾ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਵੱਖ-ਵੱਖ ਸਕੀਮਾ ਪਰਿਭਾਸ਼ਾਵਾਂ ਨਾਲ ਪ੍ਰਯੋਗ ਕਰ ਸਕਦੀਆਂ ਹਨ।

ਸੰਭਾਵੀ ਨੁਕਸਾਨ

ਲੂਪ ਨੂੰ ਸੀਮਤ ਕਰਨ ਦਾ ਮਤਲਬ ਹੈ ਕਿ ਸੀਮਾ ਪੂਰੀ ਹੋਣ ਤੋਂ ਬਾਅਦ ਕੁਝ ਗਲਤ ਆਉਟਪੁੱਟ ਨੂੰ ਰੱਦ ਕਰ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਕੁੱਲ ਅਸਫਲਤਾ ਦਰ ਵਧ ਸਕਦੀ ਹੈ ਜੇਕਰ ਮਾਡਲ ਦੀ ਅਸਲ ਗੁਣਵੱਤਾ ਘੱਟ ਹੈ। ਅਜਿਹੇ ਮਾਹੌਲ ਵਿੱਚ ਜਿੱਥੇ ਹਰ ਜਵਾਬ ਮਹੱਤਵਪੂਰਨ ਹੁੰਦਾ ਹੈ, ਡਿਵੈਲਪਰ ਵਾਧੂ ਟੋਕਨਾਂ ਦੀ ਕੀਮਤ 'ਤੇ ਵਧੇਰੇ ਰਿਟਰਾਈ ਸੀਮਾ ਨੂੰ ਤਰਜੀਹ ਦੇ ਸਕਦੇ ਹਨ। ਇਹ ਸਮਝੌਤਾ ਸਪਸ਼ਟ ਹੈ: ਵਧੇਰੇ ਕਵਰੇਜ ਲਈ ਵਧੇਰੇ ਲਾਗਤ, ਜਾਂ ਇੱਕ ਅਨੁਮਾਨਿਤ ਸੀਮਾ ਦੇ ਨਾਲ ਘੱਟ ਬਜਟ।

ਅੱਗੇ ਕੀ ਦੇਖਣਾ ਹੈ

  • ਰਿਪੇਅਰ ਲਈ ਪ੍ਰੋਂਪਟ ਇੰਜੀਨੀਅਰਿੰਗ – ਗਲਤੀ ਦੇ ਸੁਨੇਹਾ ਫਾਰਮੈਟ ਨੂੰ ਸੁਧਾਰਨ ਨਾਲ ਲੋੜੀਂਦੀਆਂ ਰਿਟਰਾਈਜ਼ ਦੀ ਗਿਣਤੀ ਘਟਾਈ ਜਾ ਸਕਦੀ ਹੈ।
  • ਵਿਕਲਪਿਕ ਪਾਰਸਰ – ਕੁਝ ਲਾਇਬ੍ਰੇਰੀਆਂ ਟੋਲਰੈਂਟ ਪਾਰਸਿੰਗ ਪ੍ਰਦਾਨ ਕਰਦੀਆਂ ਹਨ ਜੋ ਮਾਮੂਲੀ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਆਪਣੇ ਆਪ ਠੀਕ ਕਰ ਸਕਦੀਆਂ ਹਨ; ਇੱਕ ਸੀਮਤ ਲੂਪ ਦੇ ਵਿਰੁੱਧ ਉਹਨਾਂ ਦੀ ਲਾਗਤ ਦੀ ਤੁਲਨਾ ਕਰਨਾ ਫਾਇਦੇਮੰਦ ਹੈ।
  • ਮਾਡਲ ਅੱਪਡੇਟਸ – ਨਵੇਂ LLM ਵਰਜਨ ਸ਼ੁਰੂ ਤੋਂ ਹੀ ਸਾਫ਼ JSON ਪੈਦਾ ਕਰ ਸਕਦੇ ਹਨ, ਜਿਸ ਨਾਲ ਰਿਟਰਾਈ ਸੀਮਾ ਨੂੰ ਹੋਰ ਘਟਾਉਣ ਦੀ ਸੰਭਾਵਨਾ ਬਣਦੀ ਹੈ।

ਇੱਕ ਸੀਮਤ JSON ਰਿਪੇਅਰ ਲੂਪ ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਵਧਦੀ ਲਾਗਤ ਤੋਂ ਬਿਨਾਂ ਅਸਪਸ਼ਟ LLM ਆਉਟਪੁੱਟ ਨੂੰ ਭਰੋਸੇਯੋਗ ਡੇਟਾ ਵਿੱਚ ਬਦਲਣ ਲਈ ਇੱਕ ਵਿਵਹਾਰਕ ਸਾਧਨ ਦਿੰਦਾ ਹੈ। ਵੈਲੀਡੇਸ਼ਨ ਨੂੰ ਇੱਕ ਪ੍ਰਮੁੱਖ ਕਦਮ ਵਜੋਂ ਮੰਨ ਕੇ ਅਤੇ ਰਿਟਰਾਈਜ਼ ਨੂੰ ਸੀਮਤ ਕਰਕੇ, ਟੀਮਾਂ ਬਜਟ ਅਤੇ ਡਾਊਨਸਟ੍ਰੀਮ ਸਿਸਟਮ ਦੋਵਾਂ ਨੂੰ ਖੁਸ਼ ਰੱਖ ਸਕਦੀਆਂ ਹਨ।