Okullar için Robotik ve Mühendislik · anaokulundan liseye

4. ünite / 10 · 4 saat

Yapılandırılmış çıktı: JSON şeması ve onarım döngüsü

Modelden programın okuyabileceği veri almak: JSON Schema, doğrulama, hata yolları ve modele geri dönen onarım mesajı.

Bu ünitenin sonunda

  • Bir JSON şemasında tür, zorunlu alan, enum ve sınır kurallarını yazmak
  • Model çıktısından JSON'u güvenle çıkarmak
  • Doğrulama hatalarını yollarıyla raporlamak
  • Sınırlı sayıda denemeli bir onarım döngüsü tasarlamak

Ders notları

Bir modelin cevabını bir program okuyacaksa serbest metin yetmez. "Öğrenci numarası, deney adı, puan" gibi alanları her seferinde aynı biçimde almak için çıktıyı bir JSON şeması ile tanımlarız.

Şemanın kuralları

  • type: string, integer, number, boolean, array, object.
  • required ve additionalProperties: false: hangi alanların şart olduğu ve fazladan alanın kabul edilmeyeceği.
  • enum, minimum, maximum, pattern, minItems: değerin izin verilen aralığı.

Üç savunma hattı

Birincisi, API'nin yapılandırılmış çıktı özelliğidir: Anthropic API'de output_config ile bir şema verildiğinde cevap o şemaya uyacak biçimde üretilir ve SDK'nın parse yardımcısı sonucu doğrudan bir nesneye çevirir. İkincisi, kendi doğrulayıcındır: ağdan, önbellekten ya da eski bir sürümden gelen veriye yine de güvenme, uygulamanın sınırında doğrula. Üçüncüsü, onarım döngüsüdür: doğrulama başarısızsa hataları yollarıyla birlikte modele geri gönder ve yalnız o alanları düzeltmesini iste.

üret → çıkar → doğrula → (hata varsa) onarım mesajı → en çok N deneme

Metin çevresinde JSON

Şemasız istendiğinde model JSON'u "Tabii, işte özet:" gibi bir cümlenin ve kod bloğunun içine koyabilir. Çıkarıcı önce tüm metni, sonra kod bloğunu, sonra ilk süslü parantezle son süslü parantez arasını dener. Bu bir yamadır; asıl çözüm şemalı çıktı ve açık biçim talimatıdır.

Onarım döngüsü sınırsız olmamalıdır: iki üç denemeden sonra hâlâ geçersizse isteği hatalı say, kaydet ve kullanıcıya anlaşılır bir mesaj göster.

Simülasyon

Öğretim modeli: bu sayfadaki simülasyonlar gerçek bir dil modeli değildir. Küçük, deterministik, tarayıcıda çalışan modellerdir; kavramı göstermek için yazıldılar. Site hiçbir dış LLM servisine istek göndermez.

Yapılandırılmış çıktı: JSON şema doğrulayıcı

Solda bir JSON şeması, sağda bir modelin döndürmüş olabileceği çıktı. Hazır örnekleri dene: geçerli, eksik alan, yanlış tür, JSON'un çevresinde fazladan metin, izin verilmeyen değer. Doğrulayıcı hataları yollarıyla gösterir ve onarım döngüsünde modele geri gönderilecek mesajı hazırlar.

Kendin dene

Şema doğrulayıcıda altı örneği sırayla dene ve her birinde hangi kuralın bozulduğunu yaz. "Eksik alan" örneğini elle düzelt: puan alanını ekle ve 101 yap, sonra 100 yap. "Bozuk JSON" örneğinde onarım mesajının şema hatası mesajından nasıl farklı olduğunu karşılaştır.

Kod

Bunları kendi bilgisayarında çalıştır. Anahtar ANTHROPIC_API_KEY ortam değişkeninden okunur; koda asla yazma.

Python: JSON şemalı çıktı, doğrulama ve onarım döngüsü
import json
import anthropic
from jsonschema import Draft202012Validator  # pip install jsonschema

client = anthropic.Anthropic()  # anahtar ANTHROPIC_API_KEY ortam değişkeninden

SCHEMA = {
    "type": "object",
    "properties": {
        "ders": {"type": "string"},
        "hafta": {"type": "integer"},
        "tur": {"type": "string", "enum": ["lab", "sinav", "proje"]},
        "son_tarih": {"type": "string"},
    },
    "required": ["ders", "hafta", "tur", "son_tarih"],
    "additionalProperties": False,
}

def extract(text: str, tries: int = 2) -> dict:
    messages = [{"role": "user", "content": f"Duyurudan ödev kaydını çıkar:\n<duyuru>{text}</duyuru>"}]
    for _ in range(tries):
        response = client.messages.create(
            model="claude-sonnet-5-5", max_tokens=512, messages=messages,
            output_config={"format": {"type": "json_schema", "schema": SCHEMA}},
        )
        raw = next(b.text for b in response.content if b.type == "text")
        data = json.loads(raw)  # şema biçimi garanti eder; iş kurallarını biz denetleriz
        errors = [e.message for e in Draft202012Validator(SCHEMA).iter_errors(data)]
        if not 1 <= data["hafta"] <= 14:
            errors.append("hafta 1 ile 14 arasında olmalı")
        if not errors:
            return data
        # Onarım: hataları modele geri gönder, yeniden iste
        messages += [{"role": "assistant", "content": raw},
                     {"role": "user", "content": "Şu hataları düzelt: " + "; ".join(errors)}]
    raise ValueError("geçerli kayıt alınamadı")

print(extract("Gömülü Sistemler: proje 12. haftanın cuma günü 17.00'de teslim."))
JavaScript: küçük bir JSON şema doğrulayıcı ve JSON ayıklayıcı
// Modelin JSON çevresine yazdığı metni at: ilk { ile son } arasını al
function extractJson(text) {
  const a = text.indexOf('{'), b = text.lastIndexOf('}')
  if (a < 0 || b < a) throw new Error('JSON bulunamadı')
  return JSON.parse(text.slice(a, b + 1))
}

const typeOf = (v) => (Array.isArray(v) ? 'array' : Number.isInteger(v) ? 'integer' : typeof v)

function validate(schema, value, path = '$') {
  const errs = []
  const ok = schema.type === 'number' ? typeof value === 'number' : typeOf(value) === schema.type
  if (schema.type && !ok) return [`${path}: beklenen ${schema.type}, gelen ${typeOf(value)}`]
  if (schema.enum && !schema.enum.includes(value)) errs.push(`${path}: izin verilmeyen değer ${JSON.stringify(value)}`)
  if (schema.type === 'object') {
    for (const k of schema.required ?? []) if (!(k in value)) errs.push(`${path}.${k}: eksik alan`)
    for (const [k, v] of Object.entries(value)) {
      if (schema.properties?.[k]) errs.push(...validate(schema.properties[k], v, `${path}.${k}`))
      else if (schema.additionalProperties === false) errs.push(`${path}.${k}: fazla alan`)
    }
  }
  return errs
}

const schema = { type: 'object', required: ['ders', 'hafta'], additionalProperties: false,
  properties: { ders: { type: 'string' }, hafta: { type: 'integer' }, tur: { type: 'string', enum: ['lab', 'sinav', 'proje'] } } }
const reply = 'Tabii! İşte kayıt: {"ders": "Gömülü", "hafta": "12", "tur": "odev"}'
console.log(validate(schema, extractJson(reply)))

Sık yapılan hatalar

  • Modelin her zaman geçerli JSON döndüreceğini varsaymak ve ayrıştırma hatasını yakalamamak.
  • Sayıyı metin olarak ("88") kabul edip sonra hesapta hata almak.
  • Onarım döngüsüne deneme sınırı koymamak: hata sürerse maliyet büyür.
  • Fazladan alanlara izin verip sonra veritabanına beklenmeyen sütun yazmak.

Yazılım mühendisliği bağlantısı

Şema, model ile uygulaman arasındaki arayüz sözleşmesidir.

  • Şemayı tek bir yerde tanımla (Pydantic, Zod) ve hem API isteğinde hem doğrulamada aynısını kullan.
  • Sözleşme testleri yaz: her örnek çıktı için beklenen hata kodları sabitlensin; şema değişince testler hangi istemcilerin kırılacağını gösterir.

Kendini sına

  1. "puan": "88" değeri, puan için type: integer olan şemada hangi hatayı verir?

  2. additionalProperties: false ne sağlar?

  3. Onarım döngüsüne neden bir deneme sınırı konur?

  4. API'nin yapılandırılmış çıktı özelliği kullanılıyorsa kendi doğrulayıcın hâlâ gerekli mi?

Macademia'da ilgili

Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç