Anthropic yakın zamanda Claude'da yeni bir üretken UI etkileşimi başlattı. Bu özellik, sohbet akışı içinde kavramları ve bilgileri görsel olarak sunmanıza yardımcı olarak, düz metinden çok daha kolay anlaşılmasını sağlıyor. !Image Ben de benzer çözümlere bakıyordum ve Claude kendi çözümünü yayınlayınca, işimi hızlandırmam gerektiğini hissettim. Aynı zamanda, referans olması açısından onların yaklaşımını tersine mühendislikle çözebilirdim. İki gün boyunca Codex ve Claude'u yoğun bir şekilde yönlendirdikten sonra, gerçekten başardım! !https://pbs.twimg.com/amplify_video_thumb/2033112086713364480/img/EUmHCjsTK7tfnToZ.jpg Bu özellik, yapay zekanın doğrudan sohbet içinde, akış çıktısıyla etkileşimli grafikler çizmesine ve oluştururken işlemesine olanak tanıyor. Daha önce, yapay zekadan bir web sayfası yazmasını istediğinizde, tüm kodun oluşturulup işlenmesini beklemeniz gerekiyordu ve bu çok uzun sürüyordu. Artık durum farklı. Grafiklerin tuval üzerinde adım adım çizildiğini, SVG düğümlerinin birbiri ardına belirdiğini izleyebiliyorsunuz. Oluşturma sürecinin kendisi büyüleyici ve tamamlandıktan hemen sonra etkileşime geçilebiliyor. Aracım Code Pilot ile doğrudan deneyimleyin: https://github.com/op7418/CodePilot Bu yazıda, kullanımını, özel uygulama sürecini ve bazı önlemleri tanıtacağım. ## Eğlenceli kullanım alanları neler? Veri Analizi: Sonunda sayılar anlam kazanıyor Örneğin, "ABD-İran çatışmasının günlük maliyet tahmini" için bir grafik çizmesini isteyin. Eskiden yapay zeka size sayısal ilişkileri görmenin zor olduğu bir metin duvarı verirdi. Şimdi ise doğrudan bir grafik oluşturuyor ve her bir bölümün miktarını net bir şekilde gösteriyor. Metin ve grafikler birlikte çıktılanıyor, gereken yerde açıklıyor, gereken yerde çiziyor. !Image Küçük Araçlar: Etkileşimli bir hesap makinesi veya benzeri bir şey oluşturun Bileşik faiz hesaplayıcısı yapmasını isteyin. Başlangıç tutarını veya yatırım yılını değiştirmek için kaydırıcıları sürükleyin, alttaki grafikler ve sayılar gerçek zamanlı olarak güncellensin. Bu statik bir görüntü değil; gerçekten etkileşimli bir araç. Kredi hesaplamaları, birim dönüşümleri ve benzeri şeylerin hepsi yapılabiliyor. !Image Mimari Diyagramlar: Bir programcının favorisi Bir projenin mimarisini çizmesini veya bir uygulama planını görselleştirmesini isteyebilirsiniz. Örneğin, burada API'den JWT kimlik doğrulamasına kadar olan tam akışı çizmesini istedim. Özellik karşılaştırmaları, akış şemaları ve hiyerarşik yapıların hepsi grafikseldir ve mimariyi metin açıklamalarını okumaktan çok daha hızlı anlamanızı sağlar. !Image Çevrimiçi Verileri Analiz Edin Bir başka oynama şekli de ona bir GitHub deposu bağlantısı atmak; verileri tarayıp görsel bir analiz yapacaktır. Örneğin, analiz için kendi proje adresimi, CodePilot'u gönderdim. Yıldızlar, çatallar, teknoloji yığını, mimari tasarım ve temel modüllerin hepsi grafiklere döküldü. Projenin tam resmini bir bakışta görebiliyorsunuz, bu uzun bir metni okumaktan çok daha iyi. !Image Etkileşimli ve Derinlemesine Açıklamalar En güçlü yanı, modelle sıkı entegrasyonudur; sadece tek seferlik bir çıktı değildir. Oluşturulan diyagramlarla etkileşime geçebilir ve daha ayrıntılı açıklamalar isteyebilirsiniz. Örneğin, burada musonlar ve okyanus akıntıları arasındaki ilişkiyi açıklamasını istedim. !Image Daha fazlasını öğrenmek istersek, okyanus akıntısı mekanizması için butona tıklayabiliriz. Bu, mevcut modele otomatik olarak bir komut göndererek okyanus akıntısı mekanizmasının bir diyagramını oluşturmaya devam edecektir. !Image Elbette, yaygın fizik ve matematik formüllerini görselleştirmek gibi daha karmaşık etkileşimler gerçekleştirebiliriz. Bu, öğrenciler için çok faydalıdır; her parametre kaydırıcılar ve girişlerle kontrol edilebilir ve animasyon anında değişir. !Image Çin Modelleri için Destek CodePilot'ta uygulandıktan sonra, sadece Claude için değil. Kimi K2.5, Minimax M2.5 ve Anthropic'in yerel modellerinin hepsi bunu iyi çalıştırıyor. Bence K2.5'in çizdiği grafikler Sonnet 3.5'ten bile daha güzel görünüyor ve mimari analizi çok detaylı. Bu özelliği kullanacaksanız, önce K2.5'i denemenizi tavsiye ederim. Tamam, model gösterimleri için bu kadar. Nasıl uygulandığı umurunuzda değilse, CodePilot'u kurup eğlenmeye başlayabilirsiniz. ## Nasıl uygulandı? !Image Claude bunu nasıl yapıyor Claude.ai resmi olarak tool_use mekanizmasını kullanır. Model, yapılandırılmış widget içeriği çıktılamak için özel bir araç çağırır ve ön uç, işlemek için araç çağrısının giriş parametrelerini ayrıştırır. Bu çözüm, Claude.ai'in kendi mimarisi altında iyi çalışır. Ancak CodePilot için üç nedenden dolayı çalışmaz: Birincisi, SDK sınırlamaları. CodePilot, Claude Agent SDK'sının claude_code ön ayar modunu kullanır ve bu, özel araçlar kaydetmeye izin vermez. SDK bir metin delta akışı sunar, bu nedenle araç düzeyinde genişletilemez. İkincisi, akış deneyimi. tool_use'un sonuçlarının işlenmeden önce input_json_delta'nın bitmesini beklemesi gerekir ve artımlı HTML oluşturmayı desteklemez. Kod çitlerinde HTML, metin akışıyla birlikte gelir ve oluşturma sırasında işlemeye olanak tanır. Üçüncüsü, işleme izolasyonu. Claude.ai, izolasyon için Shadow DOM kullanır. Biz bir sandbox iframe seçtik. Iframe izolasyonu daha kapsamlıdır—tamamen bağımsız bir JS yürütme ortamı, CSP kaynak yüklemeyi hassas bir şekilde kontrol eder ve stil sızıntısı veya betik kaçışı olmaz. Biz nasıl yaptık Tetikleyici: Kod Çitleri Model, işlemeyi tetiklemek için özel bir Markdown kod çiti çıktılar: ``show-widget {"title":"training_flow","widget_code":"<svg width=\"100%\" viewBox=\"0 0 680 400\">...</svg>"} ` Bu format, CodePilot'un mevcut kod çiti modlarını (image-gen-request, batch-plan, vb.) yeniden kullanır ve ön uç ayrıştırıcı zinciri bunu doğal olarak destekler.  **İşleme: Sandbox Iframe** Her widget, sandbox="allow-scripts" ile bir iframe'de işlenir. Iframe'in srcdoc'u dikkatlice oluşturulmuş bir alıcı sayfasıdır. CSP politikası yalnızca 4 CDN alan adından harici betiklere izin verir ve connect-src 'none' tüm ağ isteklerini yasaklar. İçerik güncellemeleri postMessage aracılığıyla alınır. Akış önizleme aşamasında, betikler çalıştırılmadan widget:update gönderilir. Son işleme, betikleri çalıştıran widget:finalize gönderir. Bir ResizeObserver, içerik yüksekliğindeki değişiklikleri izler ve bunları postMessage aracılığıyla üst sayfaya bildirir. Tüm <a> tıklamaları durdurulur ve yeni bir pencerede açılmak üzere üst sayfaya yönlendirilir. Tema senkronizasyonu, koyu/açık modlar arasında gerçek zamanlı geçiş yapmak için üst sayfadaki sınıf değişikliklerini izlemeye dayanır.  **CSS Değişken Köprüsü** Widget'ın uygulamayla görsel olarak uyumlu hale gelmesinin anahtarı budur. CodePilot, OKLCH renk uzayında CSS değişkenleri kullanır. Anthropic'in widget tasarım yönergeleri, --color-background-primary gibi standart değişken adları kullanır. Köprüleme katmanı, CodePilot'un değişken değerlerini başlatma sırasında iframe'in :root'una enjekte eder. Yönergelere göre model tarafından yazılan CSS, doğrudan geçerli temanın renklerini kullanabilir. Karanlık moda geçerken, üst sayfa sınıf değişikliğini algılar, değişken değerlerini yeniden hesaplar ve bunları iframe'e iletir.  **Akış İşleme** Tüm uygulamanın en karmaşık kısmı budur. Model, token token üretir. Herhangi bir anda, alınan widget kodu eksik bir JSON, eksik bir HTML veya eksik bir <script> etiketi olabilir. İşleme akışı aşağıdaki gibidir: Regex, "kapatılmamış" ve "kapatılmış" durumları arasında ayrım yapmak için `show-widget ile eşleşir. "widget_code":" sonrasındaki içeriği manuel olarak bulun ve karakter karakter kaçışını kaldırın. JSON henüz bitmediği için JSON.parse kullanılamaz. Kapatılmamış bir <script> etiketi algılandığında, JavaScript kodunun görünür metin olarak görüntülenmesini önlemek için <script'ten önce kesin. 120 ms'lik bir debounce, iframe'in çok sık güncellenmesini önler. Akış içeriği tüm betikleri ve olay işleyicilerini kaldırır; önizleme aşamasında etkileşim gerekmez.  **Deneyimi Cilalamak: Fark edilmemesi gereken detaylar** Kod veya uygulama perspektifinden bakıldığında, o kadar karmaşık değil; karmaşıklık deneyimi cilalamakta yatıyor. Deneyimi etkileyebilecek çok fazla yer var ve kullanıcıların bu detayları ve oluşturma sürecini fark etmemesi gerekiyor. Bu, her aşamayı farklı şekilde ele almayı gerektirir: 1. Akış gibi görünmeyen detaylar 2. Görünmemesi gereken içerik  **Metin Kaybolması** Model önce bir giriş metni çıktılar ("Görsel olarak açıklayayım..."), ardından widget çitini başlatır. Çit görünür görünmez, önceki metin aniden kaybolur ve yalnızca widget işlemeyi bitirdikten sonra geri döner. Bunun nedeni, parseAllShowWidgets()'ın düz metin için boş bir dizi döndürmesidir. Çit yeni göründüğünde ancak kapatılmadığında, çitten önceki metin bu fonksiyona iletilir ve kaybolur. Düzeltme: Çitten önceki metin tamamlanmış bir widget çiti içermediğinde, ayrıştırma fonksiyonunu atlayarak doğrudan <MessageResponse> olarak işleyin. **Yükseklik Sıçramaları** Widget işlemeyi bitirdiği anda, tüm sohbet alanı titrer. Iframe'in başlangıç yüksekliği 0 pikseldir. İçerik ilk kez gerçek yüksekliğini bildirdiğinde, 400 piksel+ olabilir ve bir CSS geçişi bu değişimin 300 ms içinde gerçekleşmesine neden olarak gözle görülür bir sıçramaya yol açar. Düzeltme: İlk yükseklik bildirimi sırasında CSS geçişlerini geçici olarak devre dışı bırakarak yüksekliğin anında yerine oturmasını sağlayın. Sonraki yükseklik ayarlamaları yumuşak geçişler kullanır. **Sonlandırma Titremesi** Widget akış önizlemesinden son işlemeye geçtiğinde, içerik yanıp söner. Alıcı iframe, sonlandırma sırasında tüm DOM'u root.innerHTML = html ile değiştirir. Yeni ve eski içerik aynı olsa bile (salt SVG widget), tarayıcı bir kare yeniden boyama tetikler. Düzeltme: Sonlandırma sırasında, önce yeni HTML'yi geçici bir kapsayıcıya ayrıştırın ve script öğelerini ayırın. Görsel HTML'yi (scriptler olmadan) geçerli DOM ile karşılaştırın—eğer aynılarsa, innerHTML değişimini atlayın ve yalnızca yürütme için scriptleri ekleyin. Salt SVG widget'lar, sıfır yeniden boyama sonlandırması elde eder. **Kaydırma Sıçraması** Sohbet otomatik olarak en alta kayar, ardından aniden birkaç yüz piksel geriye sıçrar ve tekrar geri sıçrar. Akış sona erdiğinde, StreamingMessage bileşeni demonte olur ve MessageItem bileşeni monte olur. Bunlar tamamen farklı iki React bileşenidir ve dahili WidgetRenderer yok edilir ve yeniden oluşturulur. Yeni örneğin iframe yüksekliği 0'dan başlar, bu da içerik alanı yüksekliğinin keskin bir şekilde düşmesine neden olur ve bu da use-stick-to-bottom içinde bir kaydırma ayarlamasını tetikler. Düzeltme: Modül düzeyinde yükseklik önbelleğe alma. Bir widget yüksekliğini bildirdiğinde, widgetCode'un ilk 200 karakteri anahtar olarak kullanılarak bir önbelleğe yazılır. Yeni WidgetRenderer örneği, useState başlatma sırasında yüksekliği önbellekten okur, böylece iframe doğru yükseklikte işlemeye başlar ve 0→gerçek geçişini ortadan kaldırır. **Script Kodu Sızıntısı** Chart.js içeren bir widget yüklendiğinde, altta büyük bir JavaScript kodu bloğu görüntülenir. Model tarafından çıktılanan <script> etiketleri karakter karakter gelir. Açılış etiketi geldiğinde ancak kapanış etiketi gelmediğinde, sanitizeForStreaming açılış etiketini kaldırır, ancak içindeki JavaScript kodu, görünür içerik olarak işlenen çıplak bir metin düğümü haline gelir. Düzeltme: StreamingMessage içinde kısmi kodu çıkardıktan sonra, son <script'in eşleşen bir </script>'i olup olmadığını kontrol edin. Yoksa, <script konumunda kesin. Widget yönergeleri, scriptlerin sona gittiğini belirtir, bu nedenle kesme görsel içeriği etkilemez. Kesme sırasında bir parıltı maskesi gösterilir ve durum çubuğunda "Görselleştirmeye etkileşimli animasyonlar ekleniyor" yazısı görüntülenir. **Iframe Hazır Yarış Durumu** Nadir durumlarda, widget hiç işlenmez ve 0 piksel yükseklikte kalır. WidgetRenderer, useEffect aracılığıyla bir mesaj olay dinleyicisi kaydeder. Ancak, iframe'in alıcı betiği yüklenir yüklenmez widget:ready gönderir. Iframe, React efektinin yürütülmesinden daha hızlı yüklenirse, widget:ready dinleyici kaydedilmeden önce gönderilir ve iframeReady asla true olmaz. Düzeltme: Yedek olarak iframe öğesine bir onLoad geri çağrısı ekleyin. onLoad tetiklendiğinde, alıcı betiğinin yürütmeyi bitirmiş olması gerekir ve güvenilir bir hazır olma sinyali sağlar. **React Bileşen Ağacı Kararlılığı** Widget, çit kapandığı anda yanıp söner. İki sorun üst üste biner: akış kısmi widget'ının React anahtarı yoktur ve kapandıktan sonra key="w-0" alır. Anahtar değişikliği yeniden bağlanmaya neden olur. Ayrıca, parıltı kaplaması bir sarma <div> ile uygulanmıştı, bu da bileşen ağacı yapısını değiştirdi ve başka bir yeniden bağlanmaya neden oldu. Düzeltme: Kısmi widget'a (w-N, burada N, son segments dizisinde beklenen konumdur) kararlı bir anahtar atayın ve kapatıldıktan sonraki anahtarla tutarlı olun. Parıltı kaplamasını WidgetRenderer'ın içine taşıyın ve bir showOverlay prop'u aracılığıyla kontrol edin. Bileşen ağacı, WidgetRenderer key="w-N"> olarak kalır. ## **Son Düşünceler** Tüm üretken UI sistemi için zor olan kısım, "bir HTML parçasını iframe'de çalıştırmak" değil. Bu basit. Gerçek karmaşıklık, bu iframe'i akış, bileşen yaşam döngüsü geçişleri ve tema değişiklikleri gibi durum geçişleri sırasında görsel olarak kararlı tutmakta yatıyor. Her "yanıp sönme", "sıçrama" veya "kaybolma", React'in mutabakatını, tarayıcının işleme hattını ve postMessage`'ın zamanlamasını anlamayı gerektirir. Nihai etki, kullanıcıların grafikleri ve diyagramları modelin yanıtlarına doğal bir şekilde serpiştirilmiş görmeleridir, sanki her zaman orada olmaları gerekiyormuş gibi. Bugünlük bu kadar. Bunu faydalı bulduysanız, lütfen beğenin veya ihtiyacı olabilecek arkadaşlarınızla paylaşın.
Claude'un Yeni Yayınladığı Üretken Arayüz Etkileşimini Kopyaladım!
- Görüntülenme
- 265K
- Beğeni
- 446
- Yeniden gönderi
- 63
- Yorumlar
- 34
- Yer işaretleri
- 815
TL;DR
Bu makale, Code Pilot içinde Claude'un üretken arayüzünün kopyalanmasını detaylandırmaktadır. Sandbox iframe oluşturma, akış tabanlı JSON ayrıştırma ve sorunsuz, titremesiz bir deneyim sağlamak için yapılan kullanıcı deneyimi iyileştirmeleri gibi teknik zorlukları ele almaktadır.
TÜRKÇE çevirisini okuyorsunuz





