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.requiredveadditionalProperties: 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.
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.
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."))// 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
"puan": "88" değeri, puan için type: integer olan şemada hangi hatayı verir?
additionalProperties: false ne sağlar?
Onarım döngüsüne neden bir deneme sınırı konur?
API'nin yapılandırılmış çıktı özelliği kullanılıyorsa kendi doğrulayıcın hâlâ gerekli mi?
