API & Backend

LLM Yapılandırılmış Çıktılar: Pydantic v2, JSON Schema ve Instructor ile Sıfır Hatalı Veri Çıkarma

LLM çıktılarının kırılmasını önlemek için Pydantic v2, Instructor ve yerel JSON Schema modları ile %100 tip güvenli veri çıkarma rehberi.

Güncellendi: 9 Eylül 20265 dk
Paylaş:XLinkedIn

Özet & Doğrudan Çözüm (TL;DR)

LLM Structured Outputs; yapay zeka modellerinin serbest metin üretmek yerine katı bir JSON Schema veya Pydantic modeline kesin olarak uymasını sağlayan gramer kısıtlı kod çözme (grammar-constrained decoding) teknolojisidir. Modelin çıktı olasılık dağılımındaki (logits) şema dışı belirteçler matematiksel olarak maskelendiği için bozuk JSON, eksik alanlar veya yanlış veri tipleri %100 oranında engellenir.

Önemli Çıkarımlar:

  • Gramer Kısıtlı Kod Çözme: Model şemaya uymayan geçersiz token'ları fiziksel olarak üretemez; sıfır sözdizim (syntax) hatası.
  • Pydantic v2 Performansı: Rust tabanlı pydantic-core çekirdeği ile mikrosaniye düzeyinde veri doğrulama ve serileştirme.
  • Instructor Kütüphanesi: OpenAI, Anthropic ve Gemini API'lerinde otomatik şema dönüştürme ve doğrulamadan geçmeyen yanıtlarda otomatik retry döngüsü.
  • İç İçe Nesneler & Validatörler: Regex kontrolleri, sayısal aralıklar (gt=0), enum listeleri ve özel iş mantığı kurallarının LLM seviyesinde işletilmesi.

1. Prompt ile JSON İstemek Neden Üretimde Çöker?

Geleneksel yaklaşımlarda sistem promptuna 'Lütfen sadece geçerli bir JSON objesi döndür, markdown tırnağı koyma' yazılır. Ancak bu yöntem üretim ortamında kaçınılmaz olarak çöker.

LLM'ler öngörülemeyen durumlarda JSON öncesine selamlaşma metinleri ekler, nesne sonlarına fazladan virgül bırakır veya sayı beklenen alana metin yazar. Structured Outputs mimarisinde ise çıkarım motoru (inference engine), her token üretim adımında JSON şemasının izin verdiği karakterlerin logit skorlarını 1 yapar, kalan tüm olasılıkları negatif sonsuza çeker. Böylece geçersiz bir karakterin seçilmesi imkansız hale gelir.

2. Pydantic v2 ve Instructor ile Üretim Seviyesinde Uygulama

Aşağıdaki Python betiği, karmaşık bir B2B fatura metninden iç içe kalemleri, vergi tutarlarını ve satıcı bilgilerini tip güvenli olarak çeken eksiksiz bir örnektir:

structured_invoice_parser.py
from typing import List
from pydantic import BaseModel, Field, field_validator
import instructor
from openai import OpenAI

class InvoiceItem(BaseModel):
    description: str = Field(description="Hizmet veya ürün açıklaması")
    unit_price: float = Field(gt=0, description="Birim fiyat (pozitif sayı)")
    quantity: int = Field(gt=0, default=1, description="Adet miktarı")
    total: float = Field(gt=0, description="Kalem toplam tutarı")

class InvoiceExtraction(BaseModel):
    vendor_name: str = Field(min_length=2, description="Faturayı kesen şirket adı")
    tax_id: str = Field(description="Vergi kimlik veya VKN numarası")
    items: List[InvoiceItem]
    grand_total: float = Field(gt=0, description="KDV dahil genel toplam")

    @field_validator("grand_total")
    @classmethod
    def validate_total(cls, v, values):
        items = values.data.get("items", [])
        calculated = sum(item.total for item in items)
        if abs(v - calculated) > 1.0:
            raise ValueError(f"Toplam tutar kalemler toplamıyla uyuşmuyor: {v} != {calculated}")
        return v

client = instructor.from_openai(OpenAI())

raw_ocr_text = """
VERGİ FATURASI: Bulut Bilişim A.Ş. VKN: 1928374650
1. 12 Aylık Dedicated Sunucu Barındırma - 12 x 1500 TL = 18000 TL
2. SSL ve Güvenlik Duvarı Lisansı - 1 x 2000 TL = 2000 TL
TOPLAM: 20000 TL
"""

invoice = client.chat.completions.create(
    model="gpt-4o-mini",
    response_model=InvoiceExtraction,
    max_retries=3,
    messages=[{"role": "user", "content": raw_ocr_text}]
)

print(f"Başarıyla Çıkarıldı: {invoice.vendor_name} | Kalem Sayısı: {len(invoice.items)}")

3. Hata Yönetimi ve Otomatik Kendini İyileştirme (Self-Healing)

Instructor kütüphanesinin en büyük gücü max_retries mekanizmasıdır. Eğer Pydantic validatörü bir veri hatası fırlatırsa (örneğin kalemler toplamı fatura genel toplamına eşit çıkmazsa), hata mesajı otomatik olarak bir sonraki prompta eklenir ve modelden yalnızca hatalı alanı düzelterek yeniden üretmesi istenir. Bu döngü sistemin insan müdahalesine gerek kalmadan %99.9 doğrulukla çalışmasını sağlar.

Sıkça Sorulan Sorular

Structured outputs ilk token süresini (TTFT) yavaşlatır mı?

OpenAI ve Gemini'nin yerel JSON şema motorlarında şemanın gramer tablosu ilk çağrıda derlenir ve belleğe alınır. İlk istekte küçük bir gecikme (100-200ms) yaşansa da sonraki tüm istekler standart hızda çalışır.

LangChain veya LlamaIndex yerine doğrudan Instructor kullanmak neden avantajlıdır?

Instructor, gereksiz karmaşık soyutlamalar yerine doğrudan saf Python ve Pydantic v2 kullanır. Bu sayede hata ayıklaması kolaydır, kütüphane boyutu küçüktür ve performans kaybı yaşanmaz.

Doğrulanmış Kaynaklar ve Dokümantasyon

İlgili Teknik Rehberler

Bu mimariyle bağlantılı diğer üretim odaklı rehber ve vaka analizlerini inceleyin: