Basit bir Python döngüsü, geliştiricilerin onarım denemelerini iki ile sınırlayarak büyük dil modellerinden (LLM'ler) gelen hatalı biçimlendirilmiş JSON'ları düzeltme maliyetini artık kontrol altında tutabileceğini gösteriyor. Oluştur, ayrıştır, doğrula, tekrar dene, ardından kabul et veya başarısız ol şeklindeki bu desen, "belki geçerli JSON" durumunu ölçülebilir bir başarı oranına dönüştürür ve kontrolsüz token kullanımını önler.

Bir onarım döngüsü neden önemlidir?

LLM'lere genellikle "JSON döndür" talimatı verilir, ancak çıktı sıklıkla sözdizimi hataları, eksik anahtarlar veya iş kurallarını bozan değerler içerir. Katı bir veri yükü (payload) bekleyen bir alt sistem, bu tür bir çıktı aldığında çökecek veya yanlış sonuçlar üretecektir. Bu sorunları yakalamak ve düzeltmek için sistematik bir yol olmadığında, ekipler ya yüksek bir hata oranını kabul eder ya da model doğru sonucu verene kadar onu tekrar tekrar istemleyerek (prompting) para kaybeder.

Üç doğrulama katmanı

Güvenilir bir döngü, doğrulamayı şu şekilde ayırır:

  • Sözdizimi (Syntax) – dize (string) bir JSON olarak ayrıştırılabiliyor mu?
  • Yapı (Shape) – en üst düzey nesne tam olarak beklenen anahtarları içeriyor mu?
  • Anlamsal (Semantic) – değerler alan kısıtlamalarına uyuyor mu (örneğin, bir "kategori" önceden tanımlanmış bir kümeye ait olmalıdır)?

Döngü, başarısız olan ilk katmanda durarak modele kesin bir hata mesajı verebilir; bu da bir sonraki denemede doğru düzeltme yapma şansını önemli ölçüde artırır.

Minimal Python örneği

Aşağıdaki kod yalnızca standart kütüphaneyi kullanır. Küçük bir şema (category ve summary anahtarlarına sahip bir sözlük) ve izin verilen kategorilerin sabit bir listesini tanımlar.

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

Onarım döngüsünün kendisi denemeler için kesin bir üst sınır getirir:

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)

Eğer JSON ilk geçişte doğrulamayı geçerse, döngü hemen sonlanır. Aksi takdirde, modele özlü bir veri yükü (orijinal çıktı, tam hata dizesi ve beklenen şema) besleyerek tekrar dener. İki başarısız denemeden sonra süreç net bir hata mesajıyla (exception) durdurulur.

Maliyet etkin onarımlar için iki kural

  1. Onarım istemlerini (prompt) kısa tutun – Sadece ham JSON'u, hata mesajını ve şemayı dahil edin. Uzun bir sohbet geçmişi eklemek token kullanımını artırır ve modeli şaşırtarak doğruluğu artırmadan deneme başına maliyeti yükseltebilir.

  2. Doğrulamayı bilgi kontrolünden (fact-checking) ayırın – Ayrıştırıcı yapısal sorunları tespit edebilir ancak bir "özet" ifadesinin doğru olup olmadığını doğrulayamaz. Bilgi kontrolü daha sonraki bir aşamaya aittir; yanlış bir iddiayı "onarmaya" çalışmak sadece yalanın daha temiz görünmesini sağlar.

Başarıyı ölçmek

Her denemenin hata türünü (sözdizimi, yapı, anlamsal) ve döngünün başarılı olup olmadığını kaydetmek somut bir metrik sağlar: sınırlandırılmış denemeler dahilinde kullanılabilir hale gelen LLM yanıtlarının oranı. Ekipler bunu zaman içinde takip edebilir, istem stillerini karşılaştırabilir veya farklı şema tanımlarıyla deneyler yapabilir.

Potansiyel dezavantajlar

Döngüyü sınırlandırmak, limit aşıldıktan sonra bazı hatalı biçimlendirilmiş çıktıların atılacağı anlamına gelir; bu da modelin ham kalitesi düşükse genel hata oranını artırabilir. Her yanıtın kritik olduğu ortamlarda geliştiriciler, fazladan token maliyeti pahasına daha yüksek bir deneme sınırı tercih edebilirler. Ödünleşim (trade-off) açıktır: daha yüksek kapsama için daha fazla maliyet veya öngörülebilir bir sınırla daha sıkı bütçeler.

Bundan sonra nelere dikkat edilmeli?

  • Onarım için istem mühendisliği – Hata mesajı formatını iyileştirmek, gereken deneme sayısını azaltabilir.
  • Alternatif ayrıştırıcılar – Bazı kütüphaneler, küçük sorunları otomatik olarak düzeltebilen toleranslı ayrıştırma sağlar; bunların maliyetini sınırlandırılmış bir döngü ile karşılaştırmak değerlidir.
  • Model güncellemeleri – Yeni LLM sürümleri doğrudan daha temiz JSON üretebilir ve bu da potansiyel olarak deneme sınırının daha da düşürülmesine olanak tanır.

Sınırlandırılmış bir JSON onarım döngüsü, geliştiricilere belirsiz LLM çıktılarını maliyetleri kontrolden çıkarmadan güvenilir verilere dönüştürmek için pratik bir araç sunar. Doğrulamayı birinci sınıf bir adım olarak ele alarak ve denemeleri sınırlayarak, ekipler hem bütçeleri hem de alt sistemleri memnun tutabilirler.