3 puan yazan GN⁺ 2024-08-30 | 1 yorum | WhatsApp'ta paylaş
  • Bir geliştirici, web’de gördüğü ASCII art bileşeninin nasıl uygulandığını anlamak için küçültülmüş JavaScript’i ChatGPT’ye verdi ve araç, karmaşık akışı okunabilir bir yapıya dönüştürdü
  • Asıl kod, React bileşeninin pencere boyutuna göre sütun ve satırları hesaplayıp setInterval ile 60fps hızında metin ızgarasını güncellemesi üzerine kuruluydu
  • ChatGPT, karakter kümesi seçimini, koordinat ve zaman tabanlı karakter hesaplamasını ve div.textContent güncelleme akışını açıkladıktan sonra bunu eşdeğer TypeScript/React kodu olarak yeniden yazdı
  • İlk başta ░▒▓█ gibi blok karakterler eksik olduğu için uygulamanın farklı olduğu düşünüldü, ancak orijinal betik yeniden incelendiğinde bunun bir kopyala-yapıştır kodlama sorunu olduğu anlaşıldı
  • Doğru karakter kümesiyle güncellendiğinde çıktı, orijinal bileşenle aynı hale geldi ve bunun, küçültülmüş kodu anlama ve yeniden uygulama için ChatGPT’nin pratik biçimde kullanılabileceğini gösterdi

Küçültülmüş JavaScript’te ASCII art uygulamasını bulmak

  • reactive.network hackathon sayfasındaki ASCII art bloğunun nasıl uygulandığını görmek için kaynak kod incelendi
  • İlgili kod küçültülmüş olduğu için insanın doğrudan okuması zordu; normalde ya elle çözmek ya da orijinali geri yüklemek için .map dosyası aramak gerekirdi
  • Bu kez küçültülmüş kodun tamamı ChatGPT’ye yapıştırıldı ve kodun ne yaptığını açıklaması istendi

Küçültülmüş kodun ortaya çıkardığı yapı

  • Kod, JavaScript ve React kullanarak dinamik metin içeriği üreten bir yapıdaydı
  • Başlıca unsurlar şunlardı
    • Math.floor, Math.abs, Math.min gibi matematik fonksiyonları kısa takma adlarla kullanılıyordu
    • "reactive.network REACTIVE.NETWORK" ile özel ve blok karakterlerden oluşan bir karakter kümesi bulunuyordu
    • Kullanılacak karakter kümesi, Date.now() % 3 sonucuna göre seçiliyordu
    • Seçilen karakter kümesinin uzunluğuna göre her koordinat için gösterilecek karakterin indeksi hesaplanıyordu
  • Temel fonksiyon olan eT, konum koordinatlarını ve zaman değerini alıp gösterilecek tek bir karakter döndürüyordu
    • Zaman değeri t.time * 8e-5 ile dönüştürülüyordu
    • Koordinatlar, sütun ve satırlardan küçük olan değer ile ekran oranı kullanılarak düzeltiliyordu
    • Karakter indeksi, Math.cos(position.x * position.x - position.y * position.y) hesabının sonucu ile zaman değeri birleştirilerek belirleniyordu

React bileşeninin render yöntemi

  • Bileşen, metnin yerleştirileceği div için useRef, pencerenin height ve width değerlerini tutmak için useState kullanıyordu
  • İlk useEffect, başlangıç boyutunu window.innerHeight ve window.innerWidth ile ayarlıyor, resize olayı oluştuğunda boyutları güncelliyordu
  • İkinci useEffect, ekran boyutuna göre ASCII ızgarasının boyutunu hesaplıyordu
    • cols, Math.floor(width / 12) * 1.6
    • rows, Math.floor(height / 12)
    • aspect, cols / rows
  • setInterval, 1_000 / 60 aralığında çalışarak 60fps için metni yeniden oluşturuyordu
  • Her karede tüm satır ve sütunlar dolaşılıp hesaplanan karakterler birleştiriliyor, ardından son metin element.textContent içine yazılıyordu

TypeScript ile daha okunabilir kod olarak yeniden yazma

  • Geliştirici daha sonra eşdeğer kodun TypeScript ile, insanların daha rahat okuyabileceği biçimde yazılmasını istedi
  • ChatGPT’nin ürettiği kod, küçültülmüş kodun işlevlerini şu adlarla açığa çıkardı
    • selectedCharacterSet
    • characterSetLength
    • calculateCharacter
    • Size türü
    • AsciiArtGenerator React bileşeni
  • Anlaşılması zor değişken adları, uygulamanın amacını açık eden adlarla değiştirildi
    • calculateCharacter, koordinatları, sütun ve satırları, ekran oranını ve zaman değerini alarak gösterilecek karakteri hesaplıyordu
    • textRef, gerçek metnin yer alacağı div öğesini gösteriyordu
    • size ve setSize, pencere boyutu durumunu ifade ediyordu
  • Yeniden yazılan kod, orijinal küçültülmüş koda göre çok daha kolay okunuyordu ve bileşenin nasıl uygulandığını öğrenmek için yeterli düzeydeydi

Karakter eksikliği yanılgısı ve kodlama sorunu

  • İlk karşılaştırmada LLM’nin bazı uygulama ayrıntılarını kaçırmış olabileceği düşünüldü
  • Özellikle orijinal bileşende görülen ░▒▓█ gibi karakterlerin ChatGPT çıktısında eksik olduğu sanıldı
  • Daha sonra HN forumundaki bir kullanıcı bunun bir kopyala-yapıştır sorunu olabileceğini belirtti ve ek inceleme sonucunda orijinal kodda ChatGPT’ye yapıştırılan karakterlerden farklı karakterler bulunduğu ortaya çıktı
  • Betik doğrudan indirildiğinde doğru karakterler elde edildi ve sorunun nedeninin kodlama farkı olduğu doğrulandı
  • Karakter kümesi düzeltildikten sonra çıktı, orijinal bileşenle aynı hale geldi

1 yorum

 
GN⁺ 2024-08-30
Hacker News yorumları
  • HumanifyJS’i yapan kişiyim; bu amaç için ayrıca LLM tabanlı bir araç geliştirdim
    LLM’i AST düzeyinde kullanarak, obfuscation kaldırıldıktan sonra bile kodun çalışmaya devam etmesini garanti ediyor: https://github.com/jehna/humanify

    • İsimleri sıfırdan yeniden verme özelliğini eklemek zor olur mu merak ediyorum
      Normal kodda kullanıcının anlamlı isimlerinin tamamını sildikten sonra, algoritmaya ve kalan isimlere, örneğin yerleşik isimlere dayanarak yeni isimler seçen bir özellikten bahsediyorum
      Refactoring yaparken bunu bazen LLM ile elle yapıyorum; parallel_line_opposite_direction yerine antiparallel_line gibi daha standart bir terim bulmak ya da find_animal_instance_in_animals yerine find_instance_in_list gibi daha genellenebilir bir isim keşfetmek için faydalı oluyor
    • Daha fazla araç AST tabanlı yapılmalı; harika iş
      Açıkçası hâlâ AST düzeyinde sürüm kontrolü bekliyorum
    • LLM’e hangi soruları sorduğunu merak ediyorum
      Tüm fonksiyonu verip “Nelerin adı değiştirilmeli?” diye her şey değişene kadar tekrar tekrar sorduğun bir yöntem mi, yoksa tamamını tek seferde yaptırıp çıktıyı parse ederek AST’nin hâlâ eşleştiğini doğruladığın bir yöntem mi merak ediyorum
    • Devasa dosyalarda da çalışıp çalışmadığını merak ediyorum
      Yaklaşık 50 bin satırdan bahsediyorum
      Düzenleme: Şu anda yalnızca 1,2 bin satırlık bir JS dosyasını openai modunda çalıştırıyorum; 20 dakika geçmesine rağmen sadece %70’i bitti. Teorik olarak 50 bin satırlık dosyada çalışsa bile denememek daha iyi olur gibi
  • JS sıkıştırması epey mekanik ve basit, bu yüzden geri alma işi de görece kolay olmalı
    Elbette genel olarak bir insanın elle yapması için yeterince sıkıcıdır, ama dönüşümün kendisi oldukça sınırlı olduğu için obfuscate edilmiş tanımlayıcıları takip eden notlar olduğu sürece okumak mümkün
    Daha genel minification kaldırma ya da obfuscation kaldırma hâlâ açık bir problem gibi görünüyor. Eskiden özellikle obfuscate edilmiş birkaç program yazmıştım; deneyimime göre ChatGPT bunları yüzeysel düzeyde bile anlayamadı
    Örneğin C ile yazılmış 160 baytlık bir Brainfuck yorumlayıcısı gist’inde, GPT-4 ile kodu açıklamaya çalışan bir yorum vardı [1]; o “netleştirilmiş sürüm” özgün koda hiç benzemiyordu
    [1] https://gist.github.com/lifthrasiir/596667#gistcomment-47512...

    • Bir işlemin basit olması, onun ters işleminin de basit olması gerektiği anlamına gelmez
      Örnek olarak çarpma/asal çarpanlara ayırma, türev/integral, geçmişi hatırlama/geleceği tahmin etme verilebilir
      Kod obfuscation’ını kaldırmak kesinlikle bu zor ters problemlerden biri ve hatalar, kullanılmayan ya da alakasız rutinler, tesadüfen doğru sonuç veren yanlış implementasyonlar yüzünden kolayca daha da zorlaşabilir
      Bu anlamda ChatGPT obfuscation kaldırmada iyi sonuç veriyorsa bu sevindirici bir şey; önceden bunun böyle olmasını beklememiz gerektiği söylenemez. ChatGPT’nin sınırlarını daha zor bir problemle görmüş olman iyi, ama bulduğunun yalnızca bir üst sınır olduğunu düşünüyorum. Orijinal metindeki örneği önemsiz görmüyorum
    • let userSignedInTimestamp = new Date() ifadesini let x = new Date() yapmak önemsizdir; ama tersine gitmek için x’in hangi bağlamda kullanıldığını görmek üzere çevredeki kodu okuyup anlamak gerekme olasılığı yüksek
      Üstelik kodun geri kalanı da sıkıştırılmış olduğundan daha zor; her şeyi doğru yapsan bile sonuçta bu kayıplı bir dönüşüm ve değişken adı, kodda açıkça belirtilmeyen özellikler taşıyor olabilir
    • Renkli bir fotoğrafı siyah beyaza çevirmek oldukça basittir, ama özgün renklerine geri döndürmek kolay değildir
      Bunun nedeni süreçte verinin kaybolmuş olmasıdır
      Sıkıştırma da aynı şekilde çalışır. Kodu anlamak için gereken bilginin büyük kısmı kaybolur ve bu bilgiyi geri kazanmak çok zor olabilir
    • Açıklayıcı değişken adı timeFactor’ı çok daha kısa i ile değiştirmek mekanik ve basit olabilir, ama bu süreç yıkıcıdır ve geri çevirmek görece kolay değildir
      Kodun gerçekte ne yaptığını oldukça incelikli biçimde anlamadan imkânsızdır. LLM’in burada yaptığı şey tam da bu kısım ve şaşırtıcı olmasa da güzel bir iş. Bu kadar anında küçümseyen tavır pek hoş değil
    • Claude 3.5 Sonnet ile ilk rastgele denemeyi yaptım: https://claude.site/artifacts/246c1b1a-3088-447a-a526-b1e716...
      PC başında olmadığım için test edemedim
  • Başlıkta şirket adı olan OpenAI yerine ChatGPT ya da model adı olan GPT-4 kullanılmalı değil mi?

    • OpenAI’ın genel bir teknik terim olan GPT’yi markaya dönüştürdüğünü düşününce, OpenAI’ı ürün adı gibi kullanmakta bir miktar ironik adalet var
  • LLM’ler metin dönüşümünde mükemmeldir
    Bence temel güçlü yönleri bu, ama yeterince kullanılmıyor.

    • Bu yalnızca temel güçlü yönleri değil; transformer’ların yapmak üzere tasarlandığı iş de tam olarak bu ve tartışmalı biçimde, yapabildikleri tek şeyin bu olduğu da söylenebilir.
      Akıl yürütme ya da bilgiyi koruma gibi diğer yetenekler, amaçlanan anlamı “anlamadan” metni yeniden üretmedeki bu insanüstü yeteneğin yan etkilerinden ibarettir.
    • Özellikle sıranın çok değişmediği ve öğeler arası ilişkileri derinlemesine dikkate almanın gerekmediği, neredeyse doğrusal dönüşümlerde güçlüdürler.
      Örneğin liste sıralayamazlar ama dil çevirisi yapabilirler. Çünkü neredeyse doğru sıralanmış bir liste yanlıştır, ama neredeyse doğru bir çeviriyi çoğu zaman kabul ederiz.
    • Uygun araçlar eklendiğinde, bir codebase’i başka dillere ve framework’lere neredeyse tek tuşla taşıyabilmeleri gerekir.
      Bir ekip Python kodunun büyük bir parçasını Elixir’e dönüştürmeye değip değmeyeceğini düşünüyorsa artık yalnızca tahmin yürütmek zorunda değil.
      Kısa süre önce bir Python script’ini JavaScript’e çevirmeyi denedim; kusursuzdu ve biraz guardrail ile ölçeği büyütülebilir gibi görünüyor.
    • İş dünyasındaki başlıca kullanım alanı zaten bu değil mi?
      Biz çoğunlukla başka biçimlerden yapılandırılmış veri çıkarmak için kullanıyoruz.
    • Sorun şu ki, halüsinasyon riskini dert etmek zorunda olmadığınız ya da zaten kullanışlı biçimde veriniz olmasa bile çıktıyı doğrulayabildiğiniz durumlar olmalı.
      Üstelik bunu awk, Python, Perl vb. ile daha hızlı halledecek bilgi ya da beceriden de yoksun olmanız gerekir.
  • Sıkıştırmayı obfuscation aracı olarak kullanan geliştiricilerin bir kısmı kesinlikle kızacak gibi görünüyor.
    Eski ColdFusion sürümlerinde bir kod “şifreleme” aracı olduğu zamanı hatırlatıyor. Algoritma çok zayıftı; birinin bir çözme aracı yazması uzun sürmedi.
    Yine de bazıları bu aracın güvenli olduğuna inanıyor ve kaynak kodu açmadan kod satarken kullanıyordu; bu yüzden hoşlanmamışlardı. Açık kaynağın ezici biçimde varsayılan seçenek hâline gelmesinden önceki, 90’ların sonu/2000’lerin başı döneminden bahsediyorum.

    • Yakında bu tür kullanımlar ve bir silahlanma yarışı ortaya çıkacak gibi.
      Web sitesi, kısmen obfuscate edilmiş istemci tarafı koda dayanan yarışmalar sunar; zeki katılımcılar da artık kazanma şanslarını artırmak için bunu ChatGPT’ye koyabilir.
      Daha yeni başlıyoruz.
  • Bu, insandan üstün entelektüel performans örneği.
    Bunu inkâr etmek mümkün değil. Bu iş entelektüel bir iş ve basit ezberle ilgisi yok. Web’de LLM’lerin öğrenebileceği kadar çok sıkıştırılmış kod/sıkıştırması açılmış kod çifti de yok.
    LLM, sıkıştırmasını açtığı şeyi anlıyor ve bu belirli konuda genel olarak insandan üstün.

    • Bu sadece metin dönüşümü.
      Web’de çok fazla sıkıştırılmış kod ve sıkıştırılmamış kod çifti olmadığından emin olabilir miyiz? Mevcut JS’ten kolayca üretip eğitim seti olarak kullanılabilir; ayrıca zaten eğitimde kullanılmış muazzam miktarda sıkıştırılmamış JS de var.
    • Yapay zeka konusunda iyimserim ama bunun söylediğin olgunun bir örneği olduğundan emin değilim.
      İnsanların sıkıştırılmış kodu anlamakta zorlanmasının nedeni opak değişken adları, garip döngüler, minimize edilmiş boşluklar vb. şeylerdir. Bilgisayarlar bunlarda zorlanmaz; zaten sıkıştırmayı yapmamızın nedeni de bu. Attention yapısının bu tür işlerde iyi olması gerekir.
      Sıkıştırılmış/sıkıştırılmamış kodun da çok fazla olduğunu düşünüyorum. Source map dosyalarının amacı tam olarak bu. OpenAI’ın web tarama ve yazılım geliştirmeye yaptığı yatırımı düşününce, eğitimde sıkıştırılmış/sıkıştırılmamış verileri kullanmış olmaları şaşırtıcı olmaz.
    • Yapay zeka ya da zekâ anlayışı konusunda uzman değilim ama taşınabilir hesap makinesinin aritmetiği gerçekten anladığını ve insandan üstün entelektüel performansa sahip olduğunu da söyleyemez miyiz?
    • İnsanların sıkıştırmayı açmaya yardımcı araçlar yapmış olmasını neden insan puanına dahil etmiyoruz?
      Bir bilgisayarın 1000 basamaklı sayıları anında çarpması, insanların önce böyle bir araç yapıp çarpmayı başardığı bir örnektir. Orada entelektüel olarak başarılı olan başka ne var? Bilgisayar da kendini kendi yapmadı.
      İnsan zekâsının sınırını kafatasında kesip, o zekânın yaptığı ve kullandığı araçları problem çözme sürecinin adımları saymazsak, insanların uzaya uçacak, ameliyat yapacak ya da yemeklerin çoğunu pişirecek kadar zeki olmadığını da kabul etmemiz gerekir.
    • GPT-4, tüm atalarınızın hayatları boyunca göreceğinden daha fazla kod tüketti ve kod ile sıkıştırılmış sürümü arasındaki içsel örüntüleri anlıyor.
      Değişken adları çıkarılmış kodun soyut biçimini tanıyıp, devasa internette gördüğü benzer örüntülere insanın okuyabileceği değişken adlarını eşlemesi absürt görünmüyor.
  • İlginç ve bayağı iyileşmiş gibi görünüyor.
    Bir yılı biraz aşkın süre önce, hack’lenmiş bir WordPress sitesindeki özel bir eklenti için yardım isteyen bir e-posta almıştım ve kötü amaçlı kod obfuscation’ını çözmek için GPT kullanmayı denemiştim. O zaman kodu adım adım kendim takip etmek çok daha hızlı ilerletmişti.
    Bu yazıyı okuyunca tekrar denedim [0]. Anlaşılır şeyler verdi ama Window nesnesi üzerinden okunamayan bir string’i fiilen eval edecek şekilde obfuscate edilmişti; bu yüzden tek başına yeterli olmadı.
    O dönemde gönderdiğim raporun bir kısmı şöyleydi: Ağır biçimde obfuscate edilmiş JavaScript kodunu inceleyip, sayfa yüklenmesini algılayan, teoride sabit olan bir hesaplama kisvesini çağıran ve ardından sayfayı kötü amaçlı bir siteye yönlendiren mantığı çözebildiğimi anlatıyordu.
    [0] https://chatgpt.com/share/f51fbd50-8df0-49e9-86ef-fc972bca6b...

  • Decompiler LLM üzerinde çalışan var mı?
    Tüm kodları açık kaynak gibi yapabilecek gibi görünüyor
    Bu durumda eğitim verisi oluşturmak kolay. Ücretsiz GitHub kodlarını çeşitli derleyicilerle toplu şekilde derleyip, derlemeyi geri çevirmeyi öğretebilirsiniz. Sentetik eğitim verisinin uygun ve oldukça kolay üretilebilir olduğu bir durum
    Decompiler yalnızca derlemeyi geri çevirmeye eğitilir; yorum ekleme gibi işler için mevcut daha büyük kod LLM’leri kullanılabilir

    • Potansiyel etkisi muazzam
      Açık kaynaklaştırmanın yanı sıra, kapalı kaynak uygulamaları kolayca decompile edip değiştirerek hataları düzeltmeyi ya da özellik eklemeyi hayal edebilirsiniz. Özellikle uzun zaman önce ölmüş programlar için büyük bir özgürleşme alanı olabilir
      Hukuki nedenlerle büyük modellerde bu davranışın engellenmiş bir özellik olma olasılığı yüksek
    • Kaynağa sahip olmak yalnızca ilk adım; o kodu okuma, değiştirme, çalıştırma ve değiştirilmiş sürümü yeniden dağıtma hakkına da ihtiyaç var
      Bu hakları yalnızca kodun yazarı verebilir
    • Katılıyorum. “Yapay zeka kaynak kodu üretir/anlar” söyleminin büyük bir dikkat dağıtma yemi olduğunu düşünüyorum
      Yapay zeka kodu gerçekten iyi anlıyorsa doğrudan binary üretir ya da düzeltir
      Gerçek bir yapay zeka programcı ortaya çıktığında, insanın okuyabileceği kodu umursamayıp her şeyi makine dilinde kodlayacağına inanıyorum. Mevcut bir sistemi bakımını yapma görevi verilirse, yazılım ve donanım yığınının tamamını bir bütün olarak anlayacaktır
      Bu, görüntü üreten diffusion modellerinin gerçek çizim tekniklerini öğrenmeyi umursamamasına benziyor
    • x86’dan C’ye decompile yapan bir LLM var: https://github.com/albertan017/LLM4Decompile
    • Sıkıştırmayı açmak decompile etmek değildir
      Daha çok değişken ve fonksiyon adlarını değiştirmeye ve satır sonları eklemeye benzer
  • Benim LLM’leri sık kullanma biçimime çok benziyor [0]
    Kodu kendi çabamla okumam gerektiğinde, çözümlemenin ilk adımı olarak kullanıyorum
    Spagetti gibi darmadağın kodu verip daha okunur hâle getirmesini istemek ve oradan başlayabilmek inanılmaz özgürleştirici
    Yazarın da fark ettiği gibi LLM bazen ayrıntıları kaçırıyor, ama o kısımları ben kendim yakalayabiliyorum
    Bir diğer kullanım alanı, kodun ne yaptığını anladığım ama neden o şekilde yazıldığını kafamda oturtamadığım durumlar. Özellikle de o kodu yazan kişi artık şirkette değilse. O zaman metodu LLM sohbetine koyup ne yaptığını açıklıyorum, ardından bazı şeylerin neden belirli bir şekilde yapılmış olabileceğini soruyorum
    Her zaman mükemmel değil, ama oldukça sık gerçekten mantıklı gelen, incelemeden de sağlam çıkan ve yeni içgörü sağlayan açıklamalar üretiyor. Bir iki kez, daha sonra başımı ağrıtacak biçimde refactor etmeme de engel oldu
    [0] chatGPT ve son zamanlarda, başta Claude türevleri olmak üzere çeşitli başka modelleri frontend olarak kullanan openwebUI ile farkları görmek için kullanıyorum. Farklı modellerin birbirlerinin yanıtlarını incelemesini sağlayan ilginç kurulumlar da mümkün

  • Açılmış kod sıkıştırılmış kodla eşleşmiyorsa, sondaki “LLM yanıtı bazı uygulama ayrıntılarını kaçırmış gibi görünüyor” kısmında olduğu gibi, kullanışlılığı ciddi ölçüde azalır
    Özellikle de birçok durumda, yazıdaki gibi kodu basitçe çalıştırıp farkı doğrulamak mümkün olmadığı için
    Düzenleme: Aşağıdaki thread’e bakınca bunun bir encoding sorunu olduğu anlaşılıyor. Yine de doğruluk konusunda hâlâ biraz endişeliyim

    • Asıl isim değiştirme için HumanifyJS gibi başka bir araç kullanmak gerekir: https://github.com/jehna/humanify
    • Açılmış kod orijinale oldukça yakın görünüyor
      Bazı durumlarda ChatGPT, açmanın yanı sıra kendi refactoring işlemini de yapmış
      Orijinal kod handleResizeı hemen çağırmıyor, onun içeriğini inline olarak barındırıyor. Muhtemelen minifier gerçek bir inline etme yapmıştı. Buradaki tek gerçek fark if (typeof window < "u") koşulunun eksik olması
    • O kısım, ChatGPT’nin ürettiği sürümde orijinal örnekte kullanılan bazı karakterlerin eksik olduğu anlamına geliyor
      Özellikle blok karakterlerden bahsediyorum; HN Unicode karakterleri yapıştırmaya izin vermiyor gibi. Orijinal sürümde görünüyorlar ama ChatGPT’nin ürettiği sürümde görünmüyorlar
      Yine de gerekli bağlamın tamamını eklememiş olmam da gayet mümkün
      Birkaç karakter eksik diye çıktının tamamını küçümsemek fazla titiz bir kusur arama gibi. Bunun dışında bana göre çıktı aynı
    • Üstelik JavaScript’ten TypeScript’e yeniden gerçekleştirmesini de istemiştim
      Yalnızca değişken ve metot adlarını değiştirmesini söyleseydim, muhtemelen orijinale daha yakın olurdu