Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
AI Arayüzü Neden Farklı? Streaming, Belirsizlik ve Angular + ASP.NET Core Mimarisi
AI arayüzünü klasik CRUD ekranından ayıran şey cevabın parça parça, her seferinde farklı ve yarıda kesilebilir gelmesi: aynı soru iki denemede iki farklı kitap, 6 ve 13 saniyelik ilk token süresi ve 2,5 kat farklı token tüketimiyle cevaplandı. Bu yazıda Angular, ASP.NET Core ve model arasındaki mimariyi, API key'in neden bundle'a girmemesi gerektiğini ve /chat/sse'nin event sözlüğünü kuruyoruz.
Angular'da Streaming Chat: fetch ile SSE Okumak, resource stream ve Signal'larla Token Token Render
EventSource POST gövdesi gönderemediği için LLM akışını Angular'da fetch, ReadableStream ve TextDecoderStream ile okuyup event'leri signal'lara yazıyoruz. Bu yazıda chunk sınırında bölünen UTF-8 karakterini, AbortController ile sunucuya kadar giden Durdur butonunu, requestAnimationFrame ile yarıya inen DOM yazımını, @for track hatasının her güncellemede element'i yeniden oluşturmasını ve resource stream'in akış sürerken bile resolved görünmesini ölçüyoruz.
AI Chat State'i ve Hata Yönetimi: State Machine, Yarım Cevap, Timeout, 429 ve Yeniden Üretmek
Bir AI chat'ini güvenilir yapan şey açık bir state machine ve hata türlerini ayırmak: 400 ProblemDetails, Retry-After'lı 429, ilk token timeout'u, akış ortasında error event'i ve kopan bağlantı. Bu yazıda yarım cevabı silmeden işaretliyor, abort'u hatadan ayırıyor, API süreci ölünce dev proxy'nin akışı 90 saniye açık tuttuğunu ve ping tabanlı sessizlik zamanlayıcısının bunu 15 saniyede yakaladığını gösteriyor, yeniden üretmeyi sunucudaki ConversationId geçmişiyle bağlıyoruz.
LLM Çıktısını Güvenle Göstermek: Streaming Markdown, Sanitization, Kod Blokları ve Kaynak Gösterimi
LLM çıktısı güvenilmeyen bir girdi olduğu için Angular'da marked, DOMPurify ve Angular sanitizer'ından oluşan üç katmanlı bir pipeline'la, görselsiz ve link allowlist'iyle render edilir. Bu yazıda tamamlanan blokları dondurarak script süresini üçte bire indiriyor, boş satıra güvenen kuralın listeyi ikiye böldüğünü ve autolink'in yarım URL'i tıklanabilir yaptığını gösteriyor, kod bloklarını component'le ve [n] atıflarını kaynak listesiyle doğrulayarak render ediyoruz.
Tool Çağrıları, Onay Akışı ve Generative UI: Asistanın Component Seçmesine İzin Vermek
Asistanın tool çağrılarını kullanıcıya göstermek, hassas işlemi süreli ve tek kullanımlık bir onay kartına bağlamak ve modelin metin yerine izinli bir component seçmesine izin vermek, Angular'da tiplenmiş SSE event'leri ve doğrulayan bir component registry ile yapılır. Bu yazıda küçük modelin kart göstermeden 'gösterdim' dediğini, bir hata metninin props olarak arayüze geldiğini ve istemci doğrulamasının bunu durdurduğunu gösteriyor, Hashbrown'ı ve postinstall telemetrisini inceliyoruz.
Standart Protokollerle Bağlanmak: AG-UI, AI SDK UI ve Kendi SSE Sözleşmemiz Arasında Seçim
Kendi SSE sözleşmen, AG-UI ve AI SDK UI arasındaki seçim; backend'in, istemci sayısının ve ödemeye razı olduğun bundle ile kablo maliyetinin sonucudur. Bu yazıda aynı asistanı üç protokolle Angular'a bağlıyor, AG-UI'ın varsayılan ayarlarla modelin düşünme metnini 368 KB'lık bir akışla tarayıcıya taşıdığını, iki protokol library'sinin sayfaya 500-680 kB eklediğini ve abort'un RUN_ERROR olarak geldiğini ölçüyoruz.
AI UX ve Erişilebilirlik: Bekleme Hissi, aria-live, Klavye, Geri Bildirim ve Şeffaflık
Streaming bir AI cevabı ekran okuyucuya parça parça değil, tur bitince tek bir LiveAnnouncer duyurusuyla verilmeli; odak input'ta kalmalı, bekleme süresi ve AI etiketi görünmeli. Bu yazıda aria-live'ın üç cümlede 70 değişiklik ürettiğini, Send/Stop değişiminin odağı body'ye düşürdüğünü ve axe-core'un bunu görmediğini ölçüyor, kontrastı düzeltiyor ve beğen/beğenme geri bildirimini backend'e bağlıyoruz.
Streaming AI Arayüzünü Test Etmek: Sahte Stream'ler, Vitest Fake Timer'ları, MSW ve Playwright
Streaming bir AI arayüzü, modeli devreden çıkaran sahte AsyncGenerator'lar, fake timer'lar, MSW ile ReadableStream gövdeli cevaplar ve page.route kullanan Playwright testleriyle deterministik test edilir. Bu yazıda test ortamında instanceof DOMException'ın iptali hata sandırdığını, MSW sse() handler'ının fetch akışına uymadığını ve ping'siz sahte akışta 30 sn timeout yerine 15 sn sessizliğin dolduğunu gösteriyor, 18 testin 2 saniyenin altında bittiğini ölçüyoruz.
Tarayıcıda AI ve Angular 22'nin Deneysel AI Araçları: Built-in AI API'leri ve WebMCP
Chrome'un built-in AI API'leri ve Angular 22'nin deneysel WebMCP fonksiyonları, yalnız özellik kontrolü, süre sınırı ve her zaman çalışan bir sunucu yoluyla kullanılmalı. Bu yazıda Chromium 158'in dört ayarında Summarizer'ın downloadable, unavailable ya da cevapsız döndüğünü, yorum özetini önce cihazda sonra sunucuda ürettiğimizi, WebMCP tool'unda await sonrası inject()'in NG0203 verdiğini ve Angular'ın desteklenmeyen tarayıcıda sessiz kaldığını gösteriyoruz.