· 3 dk okuma
AI üretimlerini iki kez ücretlendirmeden ücretlendirmek
yazan: Furkan Durna · Proje: DRAPAI
#drapai #postgres #architecture
DRAPAI, yapay zekâ destekli bir sanal deneme uygulaması: bir kişinin ve bir kıyafetin fotoğrafını yüklüyorsunuz, uygulama da o kıyafetin o kişi üzerinde nasıl duracağını gösteren bir önizleme üretiyor. Her üretim bir token'a mal oluyor. Bir isteğin izlediği yola bakana kadar bu basit görünüyor:
mobile app → backend → workflow engine → AI model → back to the database
Her ok başarısız olabilir ve bazıları belirsiz şekilde başarısız olur. Bir çağrı timeout'a düşerse, üretim bir dakika sonra yine de tamamlanabilir. Çok erken ücret alırsanız kullanıcılar başarısız işlemler için ödeme yapar. Çok geç ücret alırsanız bir retry bedava bir üretime yol açabilir. Bu yazı, token bakiyesini doğru tutan fikirler hakkında.
Bir job, veritabanı tarafından zorlanan bir durum makinesidir
Her üretim, tek yönde ilerleyen bir job'dır:
pending → processing → succeeded | failed
Bu yolda olmayan her geçişi veritabanının kendisi reddeder ve tamamlanmış bir job asla geri dönemez. Uygulama yalnızca tamamlanmış job'ları kesin kabul eder. Kuralı veritabanına koymak, hiçbir servisin, workflow'un ya da gelecekteki bir bug'ın onu esnetememesi anlamına gelir.
Önce rezerve et, sonra kesinleştir
Token'lar, kullanıcı Generate'e dokunduğunda düşülmez. Bloke edilir:
- Bir job oluşturulduğunda, çağıranın job'ın sahibi olduğu kontrol edildikten sonra onun için bir token rezerve edilir.
- Üretim, sahiplik sunucuda tekrar kontrol edilerek gönderilir.
- Job başarılı olursa bloke kesinleşir. Başarısız olursa bloke serbest bırakılır.
Rezervasyon ve gönderim job başına idempotent'tir; bu yüzden çift dokunma ya da bir ağ retry'ı ekstra bir maliyet doğurmaz.
Timeout, başarısızlık değildir
İlk versiyonlardan biri, timeout'a düşen bir gönderimi başarısız job olarak ele alıyordu. Bu yanlıştı: HTTP çağrısı pes ettikten sonra iş çalışmaya devam edebilir; dolayısıyla bir job'ın parası iade edilip yine de bir görsel üretilebiliyordu.
Artık timeout "başarısız" değil, "bilinmiyor" anlamına geliyor. Zamanlanmış bir reconciliation job'ı, tamamlanmış job'ların blokelerini düzenli aralıklarla kesinleştiriyor ve çok uzun süredir takılı kalan job'ları çözüyor. Neyin "çok uzun" sayılacağı, job'ın nerede takıldığına bağlı: hiç alınmamış bir job, çalıştığı bilinen bir job'dan daha erken çözülüyor; gönderim sonucu bilinmeyen bir job ise iade edilmeden önce en uzun süre bekletiliyor.
Yetkili işlemleri erişimin dışında tutmak
Token hareket ettiren işlemler, normal bir kullanıcının sahip olduğundan daha fazla yetki gerektiriyor. Bu işlemler client'a açık API'nin tamamen dışında tutuluyor ve client'lar onlara yalnızca önce sahipliği kontrol eden ince giriş noktaları üzerinden ulaşabiliyor.
Bunu doğru yapmak birkaç deneme aldı. Kâğıt üzerinde daha sıkı görünen bir değişiklik, giriş noktasının altında ihtiyaç duyduğu yetkiler artık olmadığı için tüm gerçek çağrıları bozdu. Ders şu: yetkileri sıkılaştırdığınızda, yalnızca migration'ın uygulandığını kontrol etmekle yetinmeyin; gerçek bir kullanıcı oturumundan uçtan uca test edin.
Abonelikler bakiyeye ekleme yapmaz, bakiyeyi sıfırlar
Ücretli planlar, App Store ve Google Play üzerinden aylık bir token hakkı veriyor. Her iki mağaza da aynı yenilemeyi birden fazla kez bildirebiliyor. Her bildirimde token eklemek onları çoğaltırdı; bu yüzden her fatura dönemi, bakiyeyi mağazanın kendi transaction ID'sine göre plan miktarına sıfırlıyor. Aynı ID'yi tekrar görmek hiçbir şeyi değiştirmiyor.
Ücretsiz token'lar kötüye kullanımı çeker
Yeni kullanıcılar uygulamayı denemek için birkaç ücretsiz token alıyor. Ücretli bir AI modelinde ücretsiz üretimler, insanları toplu hesap açmaya davet eder; bu yüzden bu hakkın koşulları var: yeni bir hesaba değil kullanıcının kimliğine bağlı, onboarding'in tamamlanmasını gerektiriyor ve kayıtlar rate limit'e tabi. Bir kontrol karar veremediğinde fail closed davranıyor, yani reddediyor.
Bir sonraki projede de koruyacağım şeyler
- Durum kurallarını her çağıranın içine değil, veritabanına koyun.
- Önce bloke edin, sonra kesinleştirin. Asla girişte ücret almayın.
- Timeout'u "bilinmiyor" olarak ele alın ve bilinmeyenleri zamanlanmış bir job'ın çözmesini sağlayın.
- Hak tanımlarını, ödeme sağlayıcısının kontrol ettiği bir ID üzerinden idempotent yapın.