· kaynak dev.to (home feed)
TypeScript contract testleri, LLM model dizelerini yükseltirken sessiz kopuşları yakalar
Bir dev.to gönderisi, bir LLM model dizesinin değiştirilmesinin kırıcı bir bağımlılık değişikliği olduğunu savunuyor ve ardından iki model sürümünü mock'layıp davranışlarını karşılaştıran çevrimdışı bir TypeScript test kapısı inşa ediyor.

dev.to'daki bir gönderi görünürde basit bir argüman ileri sürüyor: API çağrınızın içindeki model tanımlayıcısı bir konfigürasyon değil. Canlı bir API sözleşmesinin yarısıdır ve değiştirilmesi, major bir bağımlılığı yükseltmekle aynı şekilde ele alınmalı — değişiklik yayına girmeden önce çalışan bir test paketiyle. Yazar ardından bu paketi tamamen çevrimdışı olarak TypeScript'te kuruyor.
Gönderinin anlattığıyla bir aylık sözleşme değişikliği
Bu eforu gerekçelendirmek için gönderi, Eylül sonundan dört sağlayıcı sürümünü listeliyor; her biri belgelenmiş davranışı değiştirdi:
17 Eylül'de Google, Antigravity Agent 09-2026'yı yayınladı. Gönderiye göre yerleşik araçları PascalCase parametrelere geçti ve write_file(path, content), write_to_file veya replace_file_content ile değiştirildi. Eski antigravity-preview-05-2026, 5 Ekim 2026'da emekliye ayrılıyor.
22 Eylül'de Anthropic, Claude Opus 5.5'i piyasaya sürdü. Alıntılanan sürüm notlarına göre disabled ve enabled türündeki thinking yükleri artık 400 hatası üretiyor; tool_choice türleri any ve tool için de aynısı geçerli.
28 Eylül'de Claude Sonnet 5.5 geldi; sürüm notları mevcut Sonnet 5 kodunun kırılabileceği beş yolu listeliyor: yüksek efor veya altında önden düşünmeyi kapatmak için disabled yerine between_tools geliyor; zorunlu araç kullanımı 400 döndürüyor; thinking blokları artık modele ve konuşmaya bağlı; önceki computer_20251124 bilgisayar kullanımı aracı artık Claude API'de veya Google Cloud'da kabul edilmiyor; danışman aracı, danışman rolünde Claude Opus 4.8, Opus 4.7 ve Sonnet 5'i reddediyor. Ayrı bir "yenilikler" sayfası altıncı bir değişiklik ekliyor: araç çağrıları arasındaki metin artık thinking bloklarının içinde geliyor — hiçbir isteği başarısız kılmayan bir yanıt şekli değişikliği.
29 Eylül'de OpenAI, DevDay'de GPT-6.1 Sol'u yayınladı ve model sayfasına göre none ve minimal akıl yürütme eforları desteklenmiyor.
Gönderinin de belirttiği gibi: üç şirket, tekrar eden tek bir örüntü.
Gürültülü hatalar ile sessiz hatalar
Makalenin öne sürdüğü temel ayrım iki hata modu arasındaki fark. Bir 400 hatası gürültülüdür — hızlıca başarısız olur ve fark edilir. Ancak ilerleme metninin thinking bloklarına taşınması gibi, varsayılan görüntüleme ayarlarında boş görünen bir değişiklik sessizdir. Kullanıcılar bir araç çağrısı tetiklenmeden önce hiçbir şey görmez ve yalnızca durum kodlarını kontrol eden her test geçer. Bu asimetri, yazarın salt assertion tabanlı testlerin değil, model sürümleri arasındaki bir diff'in gerekli sayılmasının nedeni.
Önce nötr tipler, sonra iki mock'lanmış sürüm
Adım adım anlatım bir Node 18+ projesi ve üç dev bağımlılığıyla başlıyor: typescript, tsx ve @types/node. İlk adım, herhangi bir sağlayıcı SDK'sını yansıtmak yerine uygulamanın kendi şeklini tanımlayan nötr istek ve yanıt tipleri tanımlıyor — prompt, token bütçesi, düşünme modu, araç seçimi. Yazarın ilkesi açık: sözleşmeler sağlayıcının ne sunduğunu değil, uygulamanızın neye ihtiyacı olduğunu kodlamalı.
İkinci adım, aynı sağlayıcının iki mock'unu kuruyor: claude-sonnet-5 ve claude-sonnet-5-5. Yeni mock, kapalı düşünme ve zorunlu araç kullanımı için belgelenmiş reddedilmeleri, ayrıca araçlar arası ilerleme notunu bir thinking bloğuna taşıyan şekil değişimini yeniden üretiyor. Hata ifadeleri ve yanıt yükleri uydurmadır ve hiçbir şey ağa dokunmaz ya da API anahtarı gerektirmez. Gönderi alternatif konusunda net: her isteği kabul eden bir mock hiçbir şey kanıtlamaz.
Yedi sözleşme, her biri bir hüküm döndürüyor
Üçüncü adım yedi vaadi düz fonksiyonlar olarak kodluyor: çıktı JSON'unda sayısal bir toplam ve dizgisel bir para birimi var; araç çağrıları iyi biçimli bir girdi ve tool_use durdurma nedeni taşıyor; ilerleme metni bir araç çağrısından önce görünüyor; zorunlu araç kullanımı hâlâ bir çağrı üretiyor; düşünme kapalı hızlı yolu 200 döndürüyor; düşük token bütçesi max_tokens ile duruyor; reddedilen istek, belgelenmiş davranışla uyumlu olarak refusal durdurma nedeniyle 200 döndürüyor. Her kontrol başarıda null, başarısızlıkta insan tarafından okunabilir bir neden döndürüyor — assertion çerçevesi gerekmiyor.
Gönderinin içindekiler tablosunda özetlenen kalan adımlar aynı sözleşmeleri iki mock'lanmış sürüme karşı çalıştırıp sonuçları diff'liyor, sürüm notlarındaki bilinen kırılmalar doğrudan türetilen kontrolleri ekliyor ve her şeyi, bir yükseltmeyi üretime ulaşmadan önce durduran bir kapıda birleştiriyor. Çerçeve şu: bir kontrol sürüm notlarını okur, diğeri iki model sürümünü doğrudan karşılaştırır.
Neden önemli
Çoğu ekip bir model dizesini, bir log seviyesini değiştirir gibi değiştiriyor. Bu gönderi o dizeyi, yükseltmeleri iki şekilde kırılan sürümlü bir bağımlılık olarak yeniden çerçeveliyor: gürültülü biçimde, reddetmelerle; ve sessizce, yeniden şekillenen yanıtlarla. Mock'lanmış sağlayıcılara karşı yapılan contract testler her iki boşluğu da ucuzca kapatıyor — CI'da çalışıyorlar, kimlik bilgisi gerektirmiyorlar ve durum kodu kontrollerinin kaçırdığı şekil kaymasını yakalıyorlar. Yazarın alıntıladığı, üç sağlayıcıya yayılmış dört Eylül sürümü, bunun arada bir tehlike değil, hızlı ilerleyen model API'lerinde yaşamanın normal maliyeti olduğunu düşündürüyor. Üretim LLM entegrasyonlarını sürdüren herkes için gönderi hem argümanı hem de çalışan bir başlangıç noktasını sunuyor.
- #ai
- #typescript
- #testing
- #llm
- #api-design
İlgili yazılar
- Açıklayıcı yazı, 'saniyede milyon token' iddialarının LLM bağlamı ve çıktı hızı için ne anlama geldiğini ayıklıyor
- Timeout bir hata anlamına gelmez: agent yeniden denemeleri neden idempotent işlem ID'lerine ihtiyaç duyar
- MCP, function calling ve ChatGPT eklentileri: agent yığınının katmanları olarak açıklanıyor