10 puan yazan GN⁺ 2025-06-11 | 2 yorum | WhatsApp'ta paylaş
  • Son dönemde yapay zeka ajanlarının benimsenmesi artarken, Go dili tabanlı hibrit yığınların kullanımı da yükselişte
  • Ajanlar uzun çalışma süresi, yüksek maliyet ve sık görülen giriş/çıkış beklemesi gibi özelliklere sahip
  • Go; hafif goroutine'ler, merkezi iptal mekanizması, kanal tabanlı mesajlaşma gibi yüksek performanslı bir eşzamanlılık modeli sunar
  • Standart kütüphanesi geniştir ve profilleme aracı pprof ile bellek ve thread sızıntılarını izlemek kolaydır
  • Ancak Go'nun makine öğrenimi ekosisteminin zayıf olması, zirve performansının çok etkileyici olmaması ve diğer dillere kıyasla daha sınırlı üçüncü taraf desteği gibi kısıtları da vardır

Ajan nedir?

  • Ajan, tekrar eden bir döngü içinde çalışan ve bir sonraki yürütme adımına kendi başına karar verebilen bir süreçtir
  • Workflow'lardaki gibi önceden tanımlı bir rota yerine, koşullara (ör. “test geçti”) veya azami yineleme sayısına göre sona erip ermeye karar verir
  • Gerçek hizmet ortamlarında ajanlar birkaç saniyeden birkaç saate kadar uzun süre çalışır ve LLM çağrıları, tarayıcı kontrolü gibi işlemler nedeniyle maliyetlidir
  • Kullanıcının girdisini (veya başka bir ajanın girdisini) işlemesi gerektiğinden, giriş/çıkış (I/O) bekleme süresi yüksektir

Go dili neden ajanlar için uygundur?

Yüksek performanslı eşzamanlılık

  • Go'nun goroutine yapısı yalnızca 2KB bellekle binlerce, hatta on binlerce hafif thread'i aynı anda çalıştırabilir
  • Her goroutine çok çekirdeği kullanarak paralel işleme yapar; bu sayede I/O ve bekleme durumundaki ajanlar da rahatça çalıştırılabilir
  • Kanal (Channel) tabanlı iletişim sayesinde bellek paylaşımı yerine mesaj aktarımıyla senkronizasyon sağlanır (Mutex kullanımı en aza iner)
  • Ajanların asenkron biçimde mesaj alışverişi yaparak durum yönetmesi için uygundur

Merkezi iptal mekanizması

  • Go'da context.Context kullanıldığında, çoğu kütüphane ve API iptal sinyalini desteklediği için çalışmayı durdurmak son derece kolaydır
  • Node.js veya Python'da farklı iptal kalıpları bir arada bulunurken, Go tutarlı bir yaklaşımla güvenli iptal ve kaynak geri kazanımı sağlar

Zengin standart kütüphane

  • Go'nun standart kütüphanesi oldukça geniştir; HTTP/web, dosya, ağ I/O'su gibi neredeyse tüm alanları kapsar
  • Tüm I/O işlemleri goroutine içinde bloklayıcı çalışma varsayımıyla ele alındığından, iş mantığı doğrusal (straight-line) biçimde yazılabilir
  • Python'da asyncio, threading, process gibi farklı eşzamanlılık kalıplarının bir arada bulunması karmaşıklık yaratır

Profilleme ve tanılama araçları

  • Go'nun pprof gibi yerleşik araçlarıyla bellek sızıntıları ve goroutine (thread) sızıntıları gerçek zamanlı olarak izlenebilir
  • Uzun süreli ve eşzamanlı çalışan ajanlarda ortaya çıkabilecek sızıntı sorunlarını teşhis etmede güçlüdür

LLM destekli kod yazımına uygunluk

  • Go, basit sözdizimi ve zengin standart kütüphanesi sayesinde LLM'lerin Go'ya özgü stil ile kod yazmasını kolaylaştırır
  • Framework bağımlılığı düşük olduğundan, LLM'nin sürümler veya kalıplar konusunda daha az endişelenmesi gerekir

Go'nun sınırlamaları

  • Üçüncü taraf kütüphane ve ekosistem bakımından Python ve TypeScript'in gerisindedir
  • Makine öğrenimini doğrudan uygulamak için uygun değildir (performans ve destek sınırlıdır)
  • En yüksek performansın gerektiği durumlarda Rust ve C++ daha iyidir
  • Hata yönetimi konusunda esnek davranan geliştiriciler için biraz rahatsız edici olabilir

2 yorum

 
codemasterkimc 2025-06-11

Java'dansa Go, Go'dansa Rust :)

 
GN⁺ 2025-06-11
Hacker News görüşleri
  • Çoğu ajan sisteminde en büyük gecikme unsurunun sonuçta LLM çağrıları olduğu vurgulanıyor. Yazıda anılan avantajların belirli bir dil lehine olmadığı; çoğunlukla uzun bekleme süreleri, pahalı kaynak kullanımı, kullanıcıdan veya başka ajanlardan gelen girdiler ve yüksek I/O bekleme süreleriyle ilgili olduğu söyleniyor. Bu özellikler nedeniyle sunucu çalışma hızı ya da verimliliğinden çok, Python gibi dillerin sunduğu geniş yapay zeka kütüphanesi ekosistemi ve desteğinin daha önemli bir avantaj olduğu savunuluyor. Python’da asyncio ya da çoklu iş parçacığı kütüphanelerini dert etmek gerektiği yönünde eleştiriler olsa da, pratikte ajan geliştirme o kadar zor değil ve birileri zaten ilgili iş akışlarını geliştirmiş olduğundan başlamak kolay deniyor

    • Go ile ajan kurarken eşzamanlılık ve backpressure yönetimi kalıplarının iyi oturmuş olmasının büyük avantaj olduğu deneyimlenmiş. Ajanlar çoğunlukla yavaş dış servislerle yapılan işlemler içeriyor ve bu tür işlerde Go’nun eşzamanlılık kalıpları çok faydalı oluyor. Elbette dil çok da önemli değil; en çok JavaScript kullanılıyor gibi görünüyor. Ancak konu kod üretimiyse Go ile LLM kombinasyonunun iyi bir sinerji yarattığı hissediliyor

    • Go, güçlü eşzamanlılık işleme yeteneği ve kolay dağıtım açısından Python’dan ayrışıyor. Go’da sadece statik binary dağıtmak yeterli olduğundan Python’daki ortam ve bağımlılık sorunlarından kaçınılabiliyor

    • Ajanlar orkestrasyon katmanı rolü oynuyor ve bu iş için özellikle Go, Erlang ve Node’un uygun olduğu düşünülüyor. Çok büyük AI kütüphaneleri şart değil; yoğun I/O içeren işler alan bazlı araç arayüzlerinin arkasında soyutlanıp gereken dilde alt sistemler kurulabilir deniyor

  • Go’nun bu tür iş yüklerinde büyük bir avantajı olmadığı, zamanın çoğunun I/O beklemeye gittiği söyleniyor. Go’nun tip sisteminin kısıtlı olduğu ve modern dillerde yerleşik gelen birçok özelliğin Go’da dolaylı yollarla çözüldüğü belirtiliyor. TypeScript, AI için çok iyi bir glue language ve Python’la birlikte kütüphane desteği çok güçlü. Python yerine TypeScript tercih edilmesinin nedeni olarak çok daha güçlü ve olgun bir tip sistemi gösteriliyor. Python’ın da hızla geliştiği ekleniyor. Node.js ve Python’da uzun süre çalışan işleri durdurmanın çok zor olduğu iddiasının sağlam temeli olmadığı düşünülüyor. Çoğu araç bu özelliği zaten destekliyor ve başlıca diller Python ile JS

    • Gerçekten performans gerekiyorsa V8’den hızlı C++ ya da Rust ile native modül yazmayı tercih ederim. Go’ya kadar gitmeye gerek yok
  • Elixir ve BEAM tabanlı ajan framework’leri denenmiş; BEAM ile SQLite kombinasyonunun şu an için ajanlar açısından en ideal seçenek olduğu düşünülüyor. Ajanlar uygulamayı yeniden dağıtmadan güvenle değiştirilebiliyor ve BEAM’in eşzamanlılığı bu iş için fazlasıyla yeterli. Durum tabanlı ya da geçici ajanları uygulamak da çok kolay. Gelecekte Python, TypeScript ve Rust ile temel ajanlar kurup, dil tercihlerine göre daha karmaşık ajan geliştirmeyi mümkün kılacak MCP sunucuları da yapılması planlanıyor

    • Extism projesi ve Elixir SDK öneriliyor. Bu kombinasyonla çekirdek servis, yönlendirme ve mesaj iletimi Elixir ile kurulup BEAM/OTP avantajlarından yararlanılabiliyor; ayrıca başka dillerde yazılmış küçük ve hafif Wasm modülleri biçimindeki ajanlar da eklenti gibi gömülebiliyor
      Extism
      Elixir SDK

    • BEAM’in yerleşik veri deposu mnesia yerine neden SQLite seçildiği merak ediliyor
      mnesia docs

  • Ajanların zamanının büyük kısmı LLM yanıtını beklemek ve dış servisleri (API, DB) çağırmakla geçiyor. Dil çalışma zamanının performans etkisi gerçekte neredeyse yok. Ajan performansı ve ölçeklenebilirliği için gerçekten önemli bir dil özelliği varsa, bunun JSON serileştirme ve seriden çıkarma performansı olacağı söyleniyor

    • Bu yüzden JSON’u doğal olarak işleyen TypeScript gibi bir dil kullanmanın daha iyi olduğu düşünülüyor. TypeScript’in tip sistemi Go’dan bile çok daha güçlü

    • Deneyime göre LLM çağrıları dışında ajanlardaki en maliyetli kısım asenkron düzenleme (merge, diff, patch) çakışmalarını çözmek. Bu iş düşük seviye kütüphanelere devredilebilse de, serileştirme kadar optimize edilmesi zor bir sorun olarak görülüyor

  • Bu ampcode.com ajan geliştirme rehberi akla geliyor. Python, dinamik dil özellikleri sayesinde dekoratörlerle metotları doğrudan araç çağrısına dönüştürmek, araç fonksiyonlarının tekrarından liste üretmek ya da bunları hızla JSON şemasına çevirmek gibi işlerde doğal bir kullanım sunuyor. Buna karşılık birden fazla dış tetikleyicinin (ör. kullanıcı girişi, Gmail e-postası, Slack mesajı vb.) yeni ajan çalıştırmaları başlattığı yapı, Go’nun channel ve switch/for loop kullanımıyla çok daha sezgisel gelmiş. Python’da ise ayrı ayrı kuyruklar ve thread’ler kurmak gerektiğinden daha karmaşık oluyor

  • Yazının mantığı izlenecekse Elixir ajanlar için ideal denebilir

  • Go’nun sınırlı ve yetersiz tip sistemi neredeyse her uygulama için uygunsuz görülüyor. Hatta Go’nun en büyük dezavantajının dilin kendisi olduğu söyleniyor. Dil dışındaki unsurların Go’yu katlanılabilir kıldığı düşünülüyor

    • Yıllarca Go ile programlama yapmış biri olarak tip sistemi sorunlarının fazla olduğu görüşüne katılınıyor. LLM alanındaki insanların neredeyse yalnızca Python ya da JavaScript kullandığı gözleniyor. Herkesin daha modern dillere geçmesi gerektiği düşünülse de, Go Python/JavaScript’in dağınık import ve paket sorunlarına kıyasla yine de daha iyi bir seçenek olabilir

    • Go tip sisteminin sınırlamalarının ajan geliştirmede tam olarak nasıl engel yarattığını daha somut duymak isteyenler var

    • Aslında Go’ya statik tip sisteminin eklenme nedeni performans hedeflerine ulaşmanın başka yolunu bulamamış olmaları deniyor. Pratikte dilin dinamik tipli bir dil gibi kullanıldığı, bunun da dilin tasarım amacının yanlış anlaşılmasına yol açtığı savunuluyor. Dinamik tipli dillerin genel olarak uygunsuz olduğu söylenebilir ama Python, Erlang, Elixir gibi dillerin aktif biçimde kullanılıyor olması, bu problem alanına dinamik tiplerin daha uygun olabileceğini gösteriyor

    • Birden çok dönüş değerinin bileşik şekilde çalışmaması, hata desteğinin exception’lardan daha iyi olsa da çok ayrıntılı olması, channel’ların hata yapmaya açık olması ve enum tiplerinin hayal kırıklığı yaratması eleştiriliyor. Buna rağmen interface’lerin şaşırtıcı derecede iyi çalıştığı ve paketleme sisteminin oldukça akıcı olduğu söyleniyor. Rust öğrenirken dosya yapısının Go’dan çok daha karmaşık olduğu fark edilmiş. Hatta dilin basit olması sayesinde çeşitli linter ve kod üretim araçları oluşturmak da kolay. Uzun vadeli Go kodu bakımı, Python/JS’ye kıyasla daha az kaygı veriyor

    • Go’ya derlenen bir LISP/Scheme lehçesi iyi şekilde sürdürülse gerçekten harika olurdu

  • Uzun bekleyen ve çalıştırma maliyeti yüksek süreçlerde, süreç ölürse tüm işin kaybolması önemli bir dezavantaj. Bekleme sırasında durumu veritabanına serileştirmek daha güvenli olabilir, ancak bunu kolaylaştıran bir dil olmadığı söyleniyor. Checkpoint tabanlı durum makineleri yazmak kolay değil

    • Checkpoint tabanlı durum makinelerinin Hatchet(hatchet.run) ve Temporal(temporal.io) gibi platformların sunduğu temel özelliklerden biri olduğu açıklanıyor. Bu platformlar iş akışı içindeki fonksiyon yürütme geçmişini saklıyor ve kesinti olduğunda geçmişi otomatik olarak yeniden oynatıyor. Bellek dökümü yerine çıktı bazlı ilerleme geçmişinin çok daha verimli olduğu savunuluyor. (Hatchet kurucusu)

    • goroutine, thread ve uzun çalışan zincirler sonuçta atomik iş birimlerine bölünmek ve durum serileştirmesi yapmak zorunda. Bunun hata sonrası toparlanma, hata takibi, sonuçların yeniden referanslanması ve çok düğümlü dağıtım gibi gereksinimleri karşıladığı söyleniyor. Elixir’deki Oban(github.com/oban-bg/oban) framework’ü bu yaklaşımı kullanıyor; ayrıca asenkron işlerin kalıcı hale getirilmesinin önemini anlatan Oban yazısı da öneriliyor. (Oban yazarı)

    • Golang tabanlı bir ajan kütüphanesi geliştirilirken, yeterli log varsa ajan durumunun her zaman geri yüklenebileceği düşünülmüş. Zaman damgaları ve üst çalıştırma (run) bilgisiyle alt/yan dal çalıştırma ağacı kurulabileceği belirtiliyor. Session yönetimi için map ve DB birlikte kullanılıyor ve gerektiğinde yeniden inşa edilebiliyor. Tek tek nesneleri elde tutmak yerine, stateless nesneler map içinde id ile bulunuyor; önceki action, step ve context ise durum nesnesinde tutuluyor. Ajan/iş akışı tutarlılığı da sonuçların hash ile yönetilmesiyle sağlanıyor. Şimdilik yalnızca temel ajanlar ve araçlar uygulanmış; loglama, geri yükleme ve iptal mantığı ise henüz geliştirilmemiş

    • Temporal’ın uzun süreçlerde checkpoint alma için oldukça faydalı olduğu ve dilden bağımsız çalıştığı söyleniyor

    • İş kuyruğu üzerinde düşünen biri, Postgres içinde basit bir kuyruk kurmayı değerlendirdiğini söylüyor. Avantajlar olarak sunucular arasında iş yükü dağıtımı, süreç sonlandıktan sonra görevlerin kaybolmaması ve daha iyi görünürlük sayılıyor. Ancak bunun kod karmaşıklığını ciddi biçimde artırabileceği, bu yüzden mimariyi basit kurmanın zor olduğu hissediliyor

  • AI mühendislerinin JavaScript kullanmaktan aşırı derecede kaçındığı söyleniyor. TensorFlow for Swift’in iptal edilmesi, AI dillerindeki çeşitliliğin sonu olarak görülüyor

    • JavaScript’ten kaçınmanın sadece AI mühendislerine özgü olmadığı düşünülüyor. 30 yılı aşkın süredir JS yazmış biri olarak buna katılındığı söyleniyor

    • JS’nin dil olarak çok kötü olduğu ve backend’e taşınmasının hata olduğu düşünülüyor. TypeScript’in de alttaki JS sorunlarını çözemediği savunuluyor. JS ya da TS kullanmaktan kaçınıp Go, Rust, Python, Ruby, Elixir, F# gibi alternatiflerin tercih edildiği belirtiliyor

    • JS’nin ajanlar için neden özellikle iyi görüldüğü merak ediliyor

  • ML alanında daha iyi bir eşzamanlılık modeline ihtiyaç olduğu hissediliyor. Go ile ML denendiğinde kütüphane desteğinin yetersizliği ve dış gRPC çağrılarına ya da wrapper’lara bağımlılık nedeniyle bunun pratikte neredeyse imkansız olduğu görülmüş. Python’ın sınırları var ve C++ da aşırı ayrıntılı olduğundan üretkenliği düşürüyor