Kategori arşivi: Yapay Zeka

Yapay Zeka İle Sohbet

Yapay zeka ile çalışırken dikkat edilmesi gereken en önemli hususlardan birisi, onun birçok söylem ve eyleminin altında varsayımların yatmasıdır.

İsteklerinizi yeterince keskin ifade etmezseniz, size kanatları olan ama uçamayan bir uçak teslim edebilir. 

Uçak örneğinden devam edelim.

Varsayımları ortadan kaldırmak için sadece “bir uçak yap” demek yetmez. “Bu uçak tamamlandığında uçabilmelidir” demeniz gerekir.

İşte varsayımlara karşı kullanabileceğiniz en güçlü panzehirlerden ikisi:

Onay/kabul kriterleri ve ınvariantlar.

Bu ikili ile gereksinimleri teknik anlamda formalize etmek mümkün hale gelir.

Bunun üç önemli sonucu vardır:

– Ajanlara ne yapmaları gerektiğini net olarak söylersiniz.

– Ajanların hareket alanına net sınırlar çizersiniz.

– İşin ne zaman gerçekten tamamlandığını objektif olarak ölçebilirsiniz.

Üçüncü madde özellikle önemli.

Çünkü “kod yazıldı”, “özellik implemente edildi” ya da “uygulama çalışıyor” birer tamamlanma kriteri değildir.

Uçağın kanatlarının olması, motorunun çalışması ve pistte ilerleyebilmesi de yeterli değildir. Uçak uçmuyorsa, uçak tamamlanmamıştır.

Kabul kriterleri bize neyin gerçekleşmesi gerektiğini, ınvariantlar ise ne olursa olsun hangi kuralların ihlal edilemeyeceğini söyler.

Böylece yapay zekaya sadece ne üretmesi gerektiğini değil, ürettiği şeyin hangi koşullarda doğru kabul edileceğini de tarif etmiş oluruz.

Yapay zeka çağında gereksinim yazmak artık yalnızca ne istediğimizi anlatmak değildir. Doğru olanın sınırlarını tarif etmektir.

Aksi taktirde yapay zeka ile sadece sohbet etmiş olursunuz.

Yazılımcılar ve Zihinsel Modellerle Olan Sınavları

Gelelim yazılım mühendislerinin her daim sınavı olmuş şu zihinsel model oluşturma işine.

Zihinsel modelin sadece kod bağlamında oluşabileceğine, koddan kopmakla birlikte bunun artık mümkün olmadığına dair garip bir inanış var.

Yapay zekaya her şeyi devir ve delege ettiğimizde, yapılan iş hakkında zihinsel model oluşturmanın artık bir illüzyon olduğunu söylemlerini duymaya başladım.

Genelde bu söylemlerin arkasında çok uzun yıllar kod yazmış ve bu işi kutsallaştırmış yazılımcıların olduğunu düşünüyorum. Artık kod yazmadığımıza göre onların en güçlü dayanakları ve parladıkları alan ortadan kalkmış durumda: kod yazma yetisi.

Neden yapay zekanın, kod yazmasak bile eskisine kıyasla daha zengin zihinsel modeller oluşturmamıza katkı sağladığını açıklayayım.

Öncelikle üzerinde çalıştığımız bir işin gerçek bir zihinsel modeli ile kodun zihinsel modelini birbirinden ayırmamız gerekiyor. İkisi aynı şey değil. Kodun ne yaptığını bilmek, onun çalışma şeklini içselleştirmek, nasıl eklemeler yapabileceğini bilmek koda bağımlı olan zihin modelidir. Bu yüzden kod okumuyorsak, artık zihinsel model oluşturamayız demek yanlıştır. Sadece kod için gerekli zihinsel modeli oluşturamayabiliriz kaldı ki açıp kodu okumadan ve nasıl bir yapıda olduğunu anlamaktan bizi kimse alıkoymuyor. İsteyen kod tabanlı zihinsel modeli hemen oluşturabiilr.

Kod sistemin kendisi değil; sistemin belirli bir teknolojiyle yapılmış temsilidir. Hatta yapay zeka öncesinde çoğu zaman zihinsel modelimizi kod üzerinden kurmak zorundaydık, çünkü sisteme açılan ana pencere koddu.

Örneğin bir e-ticaret sistemini anlamak için OrderService sınıfındaki 600 satır kodu zihninizde tutmanız gerekmez. Öyle bir sınıftaki ıf, for, interface, repository, DTO ve SQL sorguları oluşturmamız gereken zihinsel modelin belirli bir teknoloji kullanılarak hayata geçirilmiş halidir. 

Ama bundan daha önemli bir üst zihinsel model vardır, o da bu sınıfın aslında işletme mantığı ve gereksinimler çerçevesinden baktığımızda ne yapması gerektiğidir, örneğin sipariş hangi durumlara sahip, stok ne zaman rezerve edilir, sistem ınvariantları nelerdir vb.

Biz yıllarca ikisini birbirine karıştırdık. Çünkü başka çaremiz yoktu.

Bir sistemin nasıl çalıştığını anlamak istiyorsanız kodu açmanız gerekiyordu. Metotları takip ediyor, sınıflar arasında geziyor, debugger çalıştırıyor, SQL sorgularına bakıyor ve bütün bunlardan kafanızın içinde sistemin nasıl çalıştığına dair bir model oluşturmaya çalışıyordunuz.

Yani kod zihinsel model değildi. Kod, zihinsel modele ulaşmak için kullandığımız araçtı.

Şimdi o araç değişiyor.

Yapay zeka bana 50.000 satırlık kod tabanını satır satır okutmak yerine şunu anlatabilir:

“Bir sipariş oluşturulduğunda sistemde tam olarak neler oluyor?”

Eskiden zihinsel modeli koddan çıkarmaya çalışıyorduk.

Şimdi yapay zeka kodu okuyup bize sistemin modelini çıkarabiliyor.

Aradaki fark muazzam.

Üstelik burada çok önemli başka bir avantaj ortaya çıkıyor.

İnsan kod okurken lokal düşünmeye çok yatkındır.

Bir sınıfı açar. Bir metoda girer. Oradan başka bir metoda geçer. Repository’ye iner. Bir event bulur. Başka servise gider. Bir süre sonra ağacın dalları arasında dolaşmaya başlar.

Yapay zeka ise doğru kullanıldığında bunun tersini yapabilir.

On binlerce satırı tarayıp bize yukarıdan bakabileceğimiz bir harita çıkarabilir.

Yani zihinsel modelimiz küçülmez.

Soyutlama seviyesi yükselir.

Kod detaylarıını değil zihnimde sistemin davranışını tutmak isterim. Özellikle sistemin sahip olduğu invariantlara bakarak bir satır kod okumadan sistem hakkında mükemmel bir zihinsel model oluşturabilirim.

Zaten kod okuyarak oluşturduğumuz zihinsel model çoğu zaman sandığımız kadar iyi değildi. Çünkü insanın okuyabileceği kod miktarı sınırlı. Genelde zihnimizde oluşturabildiğimiz model sistemin sadece küçük bir kısmıydı, çünkü büyük resmi görmek her zaman ya mümkün degildi ya da yazılımcının entellektüel kapasitesi yeterli değildi.

Yapay zeka burada ilk defa bize çok daha geniş bir perspektif sunuyor. Koca bir sistemi birkaç prompt ile analiz ettirip, anında bir zihin modeli yaratabilirim. Bir insanın haftalar boyunca farklı kaynaklardan toplamaya çalışacağı bağlamı, aynı problem üzerinde bir araya getirebilirim.

Bu durumda zihinsel model nasıl fakirleşmiş oluyor?

Tam tersi söz konusu.

Kod seviyesindeki zihinsel modelden sistem seviyesindeki zihinsel modele geçiyoruz.

Eskiden iyi yazılımcıyı diğerlerinden ayıran şeylerden biri kodu okuyabilme ve kod üzerinden sistemin zihinsel modelini oluşturabilme yeteneğiydi. Şimdi başka bir yetenek öne çıkıyor:

Sisteme doğru soruları sorabilmek.

Koddan uzaklaşıyoruz ama sistemden uzaklaşmıyoruz.

Aksine:

Koddan uzaklaştıkça sisteme yaklaşma imkanımız doğuyor.

Davranış Mimarlığı

Umarım tasarım prensiplerini hatırlıyorsunuzdur, hatta onları kullanmaya gayret ediyorsunuzdur.

Detaylar için bu konuda yazdığım makalelere bakabilirsiniz:

Tasarım prensipleri kod seviyesinde, yapıları doğru şekilde oturtmak için kullandığımız mekanizmalardı. Örneğin SRP ile tek sorumluluğu olan sınıflar ya da metotlar tasarladık, OCP ile modüler yapılar inşa ettik, DIP ile bağımlılıkların tanımlı soyut yapılar üzerinden koda enjekte edilmesini sağladık vs. Sadece SRP”ye dayanan mikroservis mimarileri bile oluşturuldu.

Peki bu yapılara ihtiyacımız kaldı mı?

Teknik olarak SOLID & Co artık bizim derdimiz değil. Yapay zeka araçlarına SOLID uyumlu kod yaz dememiz yeterli oluyor.

Bizim kod tabanlı teknik tasarım prensiplerinden uygulama tasarım prensiplerine geçiş yapmamız gerekiyor.

Bunlardan aklıma gelenlerden bazıları şöyle:

– IDD — Invariant Driven Development

– SDD — Spec Driven Development

– DNRC — Do Not Reuse Code

– BDD — Behavior Driven Design

– AFD — Agent Friendly Design

– HIL — Human in the Loop

Bunların ortak bir özelliği var:

Hiçbiri yapay zekaya kodun nasıl yazılması gerektiğini anlatmıyor. Bunun yerine ortaya çıkacak sistemin nasıl olması gerektiğini tanımlıyorlar.

SOLID bize kodu nasıl şekillendireceğimizi öğretti. Yeni nesil prensipler ise yapay zekanın üreteceği sistemlerin davranış alanını şekillendirecek.

Yazılımcının işi de tam olarak buraya doğru kayıyor: Kodun mimarlığından, davranışın mimarlığına.

Reuse Olmuştur, Yaşasın Reuse

Şirket içi süreçleri yönetmek için altı değişik uygulama tasarladım. Birkaç tanesi de pipelilne’da.

Çoğunda takvim, talep yönetimi (ticket) ve WhatsApp vari chat özelliği var.

Ama bu ortak özelliklerin hiçbirisini modül olarak tasarlamadım. Yani yıllardır bize öğretilen: “Bir kere yaz, her yerde kullan.” felsefesini terk ettim.

Neden?

Yazılımda tekrar kullanım önemli değil miydi? Bizlerden yazılımcı olarak sürekli tekrar kullanım, yani reusability kurallarına uymamız beklenmedi mi?

Evet.

Ama bunun çok önemli bir ekonomik sebebi vardı: Maliyetten tasarruf etmek.

Aynı şeyi beş defa geliştirmek yerine bir defa geliştirip beş yerde kullanmak çok daha ucuzdu.

Artık bu denklemin maliyet tarafı radikal bir şekilde değişti.

Ben örneğin WhatsApp vari chat özelliğini bir kere inşa ettirdikten sonra, diğer projelerde bunu modül olarak kullanmıyorum. Referans olarak kullanıyorum.

Ajana:

“Buradaki chat mekanizmasına bak. Aynısını bu uygulamanın ihtiyaçlarına göre yeniden oluştur.”

diyorum.

Bu kadar!

30 değişik uygulamada 30 değişik chat implementasyonu olmuş, umurumda değil.

Çünkü her uygulamanın kendine has ihtiyaçları var.

Birinde dosya paylaşımı gerekiyor, diğerinde ticket ile ilişkilendirme, diğerinde departman bazlı odalar, diğerinde müşteri ile birebir iletişim.

Eskiden bunların hepsini karşılayabilecek ortak bir chat modülü tasarlamaya çalışırdık. Sonra konfigürasyonlar başlardı. Interface’ler. Adapter’lar. Extension point’ler. Feature flag’ler. Ve bir süre sonra herkesin ihtiyacını karşılamaya çalışan devasa bir ortak modülümüz olurdu. Çünkü yeniden yazmak pahalıydı.

Şimdi ise çoğu durumda tam tersi geçerli:

Mevcut ortak modülü yeni ihtiyaca adapte etmek, özelliği referans implementasyondan yeniden ürettirmekten daha pahalı hale gelebilir.

Burada çok önemli bir paradigma değişikliği var:

Kodun kendisini tekrar kullanmak yerine, artık fikri, davranışı, invariantları ve referans implementasyonu tekrar kullanabiliriz.

Yani reuse ortadan kalkmıyor. Reuse’un cehresi değişiyor.

Eskiden code reuse vardı.

Şimdi giderek knowledge reuse (bilginin tekrar kullanımı) ve intent reuse (niyetin tekrar kullanımı) on plana çıkıyor.

Aynı kodu 30 yerde kullanmak zorunda değilim.

Aynı niyetten 30 farklı ve kendi bağlamına uygun implementasyon ürettirebilirim.

Bu yüzden yazılım mühendisliğinin temel yapı taşlarından biri olarak kabul ettiğimiz “mümkün olduğunca tekrar kullan” felsefesinin de sorgulanma zamanı geldi.

Çünkü yapay zeka çağında kıt olan şey artık kod üretme kapasitesi değil. Kıt olan şey doğru davranışı, doğru sınırları ve doğru invariantları tanımlayabilme kapasitesi.

Invariant Driven Development

Yapay zeka ile sağlıklı ve istediğimiz yapıda uygulamalar geliştirebilmek için kullanabileceğimiz iki yöntemden bahsetmek istiyorum:

1.) Spec Driven Development

2.) Invariant Driven Development

Bir sonraki yazımda Spec Driven Development nedir ve nasıl yapılır konusuna değineceğim.

Bu yazının konusu ise IDD: Invariant Driven Development.

Testlerden başlayalım. Özellikle de birim (unit) testlerinden.

Klasik birim testlerinde test edilen birimin dış dünya ile olan ilişkileri çoğu zaman mocklanır. Test sonunda da bu mockların beklediğimiz şekilde kullanılıp kullanılmadığı verify edilir.

Sorun tam olarak burada başlar.

Bu noktadan itibaren testi sistemin davranışına değil, implementasyona bağlamış oluyoruz.

Örneğin bir para transferini test ettiğimizi düşünelim. transfer() metodunun çağrıldığını, ardından müşteri nesnesindeki değişikliklerin kalıcı hale gelmesi için customer.save() metodunun çalıştığını ve sonrasında gerekli diğer metotların belirli bir sırada çağrıldığını kontrol ediyoruz.

Peki burada gerçekte neyi test ediyoruz?

Para transferinin doğru yapılıp yapılmadığını mı?

Yoksa bizim o para transferini bugün nasıl implemente ettiğimizi mi?

Çoğu zaman ikincisini.

Bu tür testler işletme mantığından ziyade implementasyon detaylarını garanti altına alırlar. Bunun doğal sonucu olarak implementasyon değiştiğinde test de kırılır.

Halbuki sistemin davranışı değişmemiş olabilir.

Yapay zeka çağında bunun başka bir maliyeti daha var.

Bu testler yapay zekanın kodu özgürce refactor etmesini zorlaştırırlar. Ajan yaptığı her yapısal değişiklikte yüzlerce testin neden kırıldığını anlamak, mevcut mock yapılarını okumak ve yeni implementasyona adapte etmek zorunda kalır. Bu da gereksiz token, zaman ve context harcaması anlamına gelir.

Bizim istediğimiz şey başka.

Yapay zekaya:

“Bu kodu böyle yaz.”

demek yerine:

“Bu sistem hiçbir koşul altında şu kuralları ihlal edemez.”

demek istiyoruz.

Implementasyon alanını mümkün olduğunca yapay zekaya bırakırken, sistemin davranış sınırlarını kendimiz belirlemek istiyoruz.

İşte burada Invariant Driven Development (IDD) devreye giriyor.

Invariant nedir?

Invariant, sistem hangi işlemden veya kod yolundan geçerse geçsin doğru kalması gereken bir koşuldur.

Örneğin:

Bir sipariş için yapılan toplam iade tutarı, siparişin ödenmiş tutarından büyük olamaz.

Bu bir implementasyon detayı değildir.

Bu kuralın uygulanabilmesi için sistemin hangi sınıfı, hangi metodu, hangi repository’yi veya hangi algoritmayı kullandığı bizi ilgilendirmez.

Yapay zeka ister RefundService oluştursun, ister bunu aggregate içerisinde çözsün, ister mevcut yapıyı tamamen refactor etsin.

Tek bir şartımız var:

Bu invariant hiçbir zaman ihlal edilemez.

Başka örnekler verelim:

– Stok miktarı izin verilen durumlar dışında negatif olamaz.

– Tamamlanmış bir ödeme ikinci kez tamamlanamaz.

– İptal edilmiş bir sipariş tekrar teslim edilmiş duruma geçirilemez.

– Bir ödeme için yapılan toplam refund, tahsil edilen tutarı aşamaz.

– Aynı ödeme işlemi aynı idempotency key ile ikinci kez gerçekleştirilemez.

– Bir kullanıcının erişim yetkisi olmayan işletmenin verisine ulaşması mümkün değildir.

Bunların hiçbirisi bize kodun nasıl yazılması gerektiğini söylemiyor. Bize sistemin hangi sınırlar içerisinde davranması gerektiğini söylüyor.

Aradaki fark çok önemli.

Peki invariantları nasıl bulacağız?

IDD yapabilmek için öncelikle sistemimizde geçerli olan invariantları keşfetmemiz gerekiyor.

Bunun için uygulamayı geliştirmeye başlamadan önce yapay zeka ile kapsamlı analiz seansları yapılması gerektiğini düşünüyorum.

Birinci adımda uygulamanın DDD (Domain Driven Design) ile ana omurgası oluşturulur. Domain nedir? Aggregate’ler nelerdir? Entity’ler nelerdir? Value Object’ler nelerdir? Aggregate sınırları nerede başlar, nerede biter?

İkinci adımda bu domain içerisinde her zaman doğru kalması gereken kurallar araştırılır.

Burada yapay zekaya doğrudan şu soruyu bile sorabiliriz:

“Bu domain içerisinde ihlal edilmesi mümkün olmaması gereken tüm invariantları ve bunların edge-case varyantlarını çıkart.”

İşte o noktada invariantlar kendilerini göstermeye başlarlar.

Üçüncü adımda bunları örneğin bir INVARIANTS.md dosyasına kaydederiz.

Invariantlar mümkün olduğunca doğal dilde, açık, yoruma kapalı ve test edilebilir şekilde tanımlanmalıdır.

Örneğin:

INV-PAYMENT-001

Bir payment için başarılı refund işlemlerinin toplam tutarı, ödeme ile alinmis tutarını hiçbir zaman aşamaz.

Ardından bunun varyantlarını tanımlarız:

– Partial refund yapılabilir.

– Birden fazla partial refund yapılabilir.

– Son partial refund kalan tutar kadar olabilir.

– Başarısız refund toplam tutara dahil edilmez.

– Concurrency durumunda iki refund işlemi aynı anda bu invariantı ihlal edemez.

– Retry işlemi ikinci bir refund oluşturmamalıdır.

Böylece tek bir cümleden bütün bir davranış alanı ortaya çıkmaya başlar.

Ve burada çok önemli bir paradigma değişikliği gerçekleşiyor:

Test artık başlangıç noktası değil, invariantın türevidir.

Biz yüzlerce test tarif etmiyoruz. Biz sistemin değişmezlerini tarif ediyoruz. Hangi testlerin gerekli olduğunu, bu invariantların hangi seviyede test edilmesi gerektiğini ve hangi edge-case’lerin oluşturulması gerektiğini yapay zeka çıkartabilir.

Böylece insanın görevi test kodu yazmak ya da yapay zekaya hangi metodun kaç kere çağrılması gerektiğini anlatmak olmaktan çıkar.

İnsanın görevi şudur:

Sistemin hangi koşullar altında dahi bozulmaması gerektiğini tanımlamak.

Yapay zekanın görevi ise bu sınırlar içerisinde istediği implementasyonu oluşturmak, gerektiğinde refactor etmek ve invariantların hala geçerli olduğunu sürekli olarak ispatlamaktır.

IDD’nin benim için en önemli tarafı da tam olarak burada. Implementasyonu serbest bırakıyoruz, davranışı değil.

Müfredat Değişmek Zorunda

Yapay zeka gerçekleri tam anlamıyla kabul gördüğünde, yazılımcıların eğitim ve gelişimleri de radikal bir şekilde değişikliğe uğrayacak.

Ağırlık artık teknik yetkinlikte olmayacak.

Bir programlama dilini ne kadar iyi bildiğiniz, bir framework’ün API’lerine ne kadar hakim olduğunuz ya da ne kadar hızlı kod yazabildiğiniz giderek önemini kaybedecek.

Bunların yerine başka yetkinlikler ön plana çıkacak:

– Bir sistem nasıl tasarlanır?

– Sistemin nasıl davranması gerektiği nasıl tarif edilir?

– Sistemin sahip olması gereken invariantlar nelerdir?

– Doğru kabul kriterleri nasıl oluşturulur?

– Bir problemin sınırları nasıl çizilir?

– Bir iş, yapay zeka ajanlarının üzerinde bağımsız çalışabileceği parçalara nasıl ayrılır?

– Ajanların birbirlerinin ayaklarına basmadan çalışabilecekleri bir ortam nasıl oluşturulur?

– Ürettikleri sonuçların doğru olup olmadığı, tek tek kod satırlarını okumadan nasıl anlaşılır?

Bugün bu teknik donanıma sahip yazılımcı bulmanız imkansız.

Aslında yazılımcının eğitiminde ağırlık “nasıl yapılır?” sorusundan “ne yapılmalı, nasıl davranmalı ve doğru olduğunu nasıl anlarız?” sorularına kayacak.

Bu çok önemli bir paradigma değişikliği.

Çünkü bugüne kadar yazılım eğitimlerinin büyük bölümü implementasyon yeteneği kazandırmaya yönelikti.

Programlama dili öğrettik. Framework öğrettik. Design pattern öğrettik. API öğrettik. Syntax öğrettik.

Yeni dönemde ise sistem düşüncesi, mimari, modelleme, domain bilgisi, problem çözme, invariant tanımlama, onay/kabul kriteri oluşturma, doğrulama ve ajan orkestrasyonu çok daha merkezi hale gelecek.

Kod yazmayı öğrenmek yerine sistem kurmayı öğrenmek gerekecek.

Çünkü kod artık ürün değil. Kod, tarif ettiğimiz sistem davranışının yapay zeka tarafından üretilen implementasyon detaylarından sadece biri.

Bu yüzden geleceğin iyi yazılımcısını diğerlerinden ayıracak olan şey daha fazla kod bilmesi değil, daha iyi düşünebilmesi olacak.

Birkaç sene içinde üniversite müfderatlarının bu konulara eğilecek şekilde adapte edilmesi gerekiyor. Aksi taktirde 10-15 sene içinde gerçek anlamda bir yazılımcı krizi yaşayabiliriz.

Devri Biten Şeyler

Nerede durduğumuzu daha iyi anlamak için nelerin bittiğini ve devrinin kapandığını özetleyelim.

1.) Kod yazmak

Bunda hemfikir olduğumuzu düşünüyorum. Tartışmaya açık olmayan bir konu.

2.) Kod okumak

Hala itirazlar gelmiyor değil, kod okumanın gereksiz olduğunu söylediğimizde.

Neden kod okumanın gereksiz olduğunu gösteren birkaç güçlü argüman var.

Birincisi, yapay zeka çok iyi kod yazıyor.

İkincisi, yapay zeka çok fazla kod yazıyor.

Üçüncüsü, yazılımcının o kadar kodu okuyacak vakti yok.

Dördüncüsü, yapay zeka yazdığı kodun sağlamasını testlerle sürekli yapıyor.

Burada önemli olan kodu okumak değil, kodu anlamak.

3.) Test yazmak

Test yazmak da artık insan tarafından yapılması anlamlı ve gerekli olan bir aktivite değil.

Ben sistemin nasıl davranması gerektiğini onay/kabul kriterleriyle, sistem için geçerli kuralları ise invariantlarla tanımlıyorum. Yapay zeka tüm testleri bu ikisine göre şekillendirebiliyor.

On binlerce, sadece implementasyonu test eden test yerine, sistemsel kuralların bozulup bozulmadığını söyleyen testler oluşuyor. Böylece testler implementasyonun bekçisi olmaktan çıkıp, sistem davranışının bekçisi hâline geliyor.

4.) Teknolojiyi takip etmek

Yıllarını Java ve onun teknik altyapısıyla geçirmiş birisi olarak beni artık ne Java’nın yeni sürümleri, ne GC, ne JVM ne de yeni dil özellikleri ilgilendiriyor.

Aynı şekilde yeni çatılar ve kullandığım çatıların yeni sürümleri de beni ilgilendirmiyor. Eskiden bir Spring major update için günlerce uğraşırken, hatta bu yer yer teknik nedenlerden dolayı mümkün bile değilken, şimdilerde yapay zekaya:

“Upgrade to X.” demem yetiyor.

Teknolojinin nasıl kullanılacağını bilmek yerine, artık teknolojiden ne istediğimi bilmem gerekiyor. Bu çok büyük bir zihinsel değişim.

5.) Teknik kitap okumak

Teknik kitap okumuyorum.

Bir önceki yazımda belirttiğim gibi yapay zeka ile olan günlük interaksiyonum bana her gün 200 sayfalık bir kitap okumak gibi geliyor.

6.) Teknik dokümantasyon okumak

7.) Stack Overflow’da çözüm aramak

8.) Debugging

Breakpoint koymak, uygulamayı adım adım çalıştırmak, değişkenlerin içine bakmak… Bunlar da giderek insan aktivitesi olmaktan çıkıyor.

Çünkü yapay zeka yalnızca hatayı görmekle kalmıyor; logları, stack trace’i, kodu, testleri ve git geçmişini birlikte analiz ederek hatanın kaynağını bulabiliyor.

9.) Manuel refactoring

10.) Boilerplate yazılım mimarisi üretmek

11.) Klasik code review

Bütün bunları alt alta koyduğumuzda ilginç bir tablo ortaya çıkıyor.

Bahsettiğim hiçbir konu ortadan kalkmadı. Hatta tam tersine bunların hepsi eskisinden çok daha fazla yapılıyor.

Ortadan kalkan, bunları insanın bizzat yapmak zorunda olması.

Yazılımcının işi yukarı doğru taşınıyor. 

Yazılım geliştirme bitmiyor. Yazılımcının yazılım geliştirme biçimi bitiyor.

Ve geriye çok daha zor bir iş kalıyor:

Doğru sistemi tarif edebilmek.

Artik Kitap Okumuyorum

Her gün bir kitap okuyorum gibi.

Eskiden kod yazarken çoğu şeyi zihnimden geliyordu. Arada takıldığım yerlerde stackoverflow gibi yerlerde çözümler arardım ya da çalışma arkadaşlarıma danışırdım. Boş vakitlerimde de beni ilgilendiren yazılım konularında kitaplar okurdum.

Şimdi durum değişti.

Çözmem gereken teknik problemler %90 oranında azaldı. Stackoverflow gibi sitelere gitmeyeli 5 sene olmuştur. Artık teknik kitaplar da okumuyorum.

Bunun yerine hergün 200 sayfalık kitap okur gibiyim.

Özellikle Codex + Gpt ile analiz yaptırdığımda ya da bir problem üzerine çalıştığımda interaksiyon gereği yapay zekanın benim için oluşturduğu sayfalar dolusu yazıyı okumam gerekiyor. Ufak bir soru “bu neden böyle oldu” demek bile 10-20 sayfalık ekran çıktısına neden olabilir.

Sağlıklı karar verebilmek için hepsini okumam gerekiyor. Bazı yerlerde ne söyleyeceğini tahmin ettiğim için okumadan “devam et” diyebiliyorum. Böylece her gün neredeyse bir kitap kadar bilgiyi okumuş oluyorum.

Kitap okurken insanın nasıl kelime hazinesi gelişiyor ve kitap okuma genel olarak iyi bir alışkanlık ise, yapay zeka ile interaksiyonlardan doğan metinleri de okumak benim için faydalı. Genel olarak yapay zekanın teknik problemleri çözme şeklini gözlemleyebiliyorum. Biz yazılımcılardan çok farklı değiller. Lakin deterministik kalıplarda bunu yapıyor olmaları bazen “anladım, böyle de yapılabiliyormuş” dedirtmiyor değil.

Ben çok şey öğreniyorum.

Yazılım zaten ömür boyu öğrenmeyi gerektiren bir uğraş.

Yapay zekâ bunu ortadan kaldırmadı.

Tam tersine, öğrenmeyi yaptığımız işin içine gömdü ve çok daha verimli bir seviyeye taşıdı.

Testlere Gerek Kaldı mı?

Kod yazma ve okuma devri bitti dedik.

Peki testler ne olacak?

İyi niyet taşıyarak ajanların her kod parçası için test yazmaya başlamaları çok büyük problemlerin habercisi olabilir.

Bunlar:

– CI/CD süreçlerinin uzaması.

– Ajanların kapsama alanı geniş (code coverage) testleri her defasında okumalarının gereksiz token harcamalarını tetiklemesi.

– Testlerin mevcut implementasyona çok sıkı bağlanarak refactoring’i zorlaştırması.

– Ajanın kodu değiştirdikten sonra asıl problemi çözmek yerine yüzlerce kırılan testi tamir etmekle uğraşması.

Çözüm ne olabilir?

Sadece E2E testleri yeterli mi? Birim testlerini silebilir miyiz?

Sadece E2E testleri uçtan uca senaryoları test ederler. Bu testlerin kırılmaları problemin nerede olduğunu doğrudan göstermez. Bu yüzden ince ayar yapabilen birim testlerine de ihtiyacımız vardır.

Her ikisine de ihtiyacımız var, ama testin sağladığı değer ile maliyeti — özellikle CI süresi ve token tüketimi — arasında bir denge kurulması gerekiyor.

“Ne kadar çok testimiz var?” ya da “Code coverage ne kadar yüksek?” yerine şu soruyu sormamız gerekiyor:

Bu test hangi sistem gerçeğini koruyor?

Burada “invariant” kavramı devreye giriyor.

Invariant, sistem içerisinde hangi değişiklik yapılırsa yapılsın doğru kalması gereken bir kuraldır.

Örneğin bir ödeme sisteminde:

Yapılan iadelerin toplamı, müşteriden tahsil edilen miktardan hiçbir zaman fazla olamaz.

Bu bir invariant’tır.

Ajan bütün sistemi refactor edebilir.

Ama sonunda bu kural hala geçerli olmak zorundadır.

İşte testin görevi burada değişiyor.

Test artık ajana:

“PaymentRepository.save() metodunu çağırmadın.”

demek yerine:

“PAYMENT-001 invariant’ını ihlal ettin. 100 TL tahsil edildi ama sistem 120 TL iade yapılmasına izin verdi.”

demelidir.

İki hata mesajı arasında çok büyük bir fark var.

Birincisi implementasyonu koruyor.

İkincisi sistemin doğrusunu koruyor.

Bu bakış açısıyla testler, mevcut kodu donduran mekanizmalar olmaktan çıkıp ajanlara sınırları gösteren sensörlere dönüşüyorlar.

Ajan istediği kadar refactoring yapabilir, sınıfları bölebilir, birleştirebilir, mimariyi değiştirebilir.

Ama invariant’ları ihlal edemez.

Böylece yapay zeka ajanına iki şeyi aynı anda vermiş oluyoruz:

Özgürlük ve sınır.

Özgürlük implementasyonda.

Sınır ise sistemin değişmez doğrularında.

Bu yüzden gelecekte önemli olanın %90 ya da %100 code coverage olacağını düşünmüyorum.

Daha önemli bir soru var:

İşletmemiz ve uygulamamız için kritik olan gerçeklerin yüzde kaçını invariant olarak tanımladık ve bunların yüzde kaçını otomatik olarak doğrulayabiliyoruz?

Belki de yeni metriğimiz “Code Coverage” değil, “Invariant Coverage” olmalı.

Amaç, mümkün olan en düşük maliyetle ajana mümkün olan en yüksek kalitede geri bildirim vermektir.

Bizim yazılımcı olarak görevimiz ajanları doğru yönlendirebilmek. Bunun için kodun nasıl yazılması gerektiğine dair fikir beyanı yani sıra ınvariantlar kullanarak sistem spesifikasyonunu iyi tanımlamamız gerekiyor.

Yapay Zeka ve Refactoring

Ben yazılımcıların severek ne test yazdıklarını ne de refactoring yaptıklarını gördüm.

Halbuki her ikisi de sağlıklı ve uzun ömürlü bir uygulama oluşturmak için elzem.

Testler olmadığı için kimse refactoring yapmaya cesaret edemiyor. Ya “bana ne” diyor ya da bunun için gerekli zamanı bulamıyor.

Yapay zeka ile yazılım geliştirme döngüsü ise test etme ve refaçtoring üzerine kurulu.

Ufak bir değişiklik istiyorsunuz. Mevcut yapıyı adapte ediyor, gerekiyorsa refactoring yapıyor ve yaptığı değişikliği testlerle garanti altına alıyor.

Şimdiye kadar GPT ya da Opus’un test yazmadan veya yaptığı değişikliği dokümante etmeden ciddi bir değişiklik yaptığını pek görmedim.

Aslında olan şu:

Bir uygulamayı yeni gereksinimlere adapta edebilmek için refactoring yapmak zorundasınız, yani continuous refactoring effort gerekli. Bunun için testlere ihtiyacınız var. Yapay zeka bir uygulamayı sürekli adapte etmek için gerekli en önemli yöntemin refactoring olduğunu biliyor sadece buna odaklanarak uygulamayı sürekli yoğuruyor.

Yazılımın ana prensibi aslında uygulamayı yeni müşteri gereksinimleri ile yoğurabilmek. Bu konuda yazılımcılar yıllarca ne yazık ki başarılı olamadılar. Bunun nasıl efektif yapıldığını artık yapay zekayı takip ederek, görebilirler.

Ajan Skill’leri Değişen Kültür

Agent skill’leri hakkında konuşalım.

Ben Claude Code bünyesinde hiçbir SKILL dosyası kullanmıyorum.

Açıkçası kullanmayı da tavsiye ve tasvip etmiyorum.

Neden?

Bu, sizin çocuğunuzu başka birisinin terbiye etmesi gibi bir şey.

Yapılacak işin tüm kurallarını bir skill set tanımlıyor. Siz ajana bir iş veriyorsunuz, skill ise ona bu işi nasıl yapması gerektiğini söylüyor.

Ama benim tam olarak devretmek istemediğim şey de bu: nasıl çalışması gerektiği. Çünkü bir ajanin nasıl çalışacağı benim yazılım geliştirme anlayışımın bir parçası.

– Gereksinimleri nasıl analiz edecek?

– Hangi soruları soracak?

– Ne zaman implementasyona başlayacak?

– Neyi kontrol edecek?

– Neyi test edecek?

– Bir işi ne zaman tamamlanmış kabul edecek?

Bunların hepsi benim çalışma metodolojimin parçaları.

Başkasının hazırladığı bir skill’i kullandığım anda sadece bir aracı kullanmış olmuyorum. O kişinin çalışma biçimini, varsayımlarını ve tercihlerini de sistemime dahil etmiş oluyorum.

Ben ajanların yeteneklerini standartlaştırmak istemiyorum.

Ben onların davranışlarını kendi çalışma sistemim içinde şekillendirmek istiyorum.

Bu yüzden hazır skill’ler yerine kendi loop’larımı, kurallarımı, review mekanizmalarımı ve onay/kabul kriterlerimi oluşturuyorum.

Ajan benim yerime kod yazabilir. Ama nasıl yazılım geliştireceğimize karar veren taraf ajanın skill dosyası olmamalı.

Yapay zeka araçları ile çalışmak gerçekten disiplin gerektiren bir şey. Gelişi güzel skill yükleyerek, işin daha da kolaylaşacağını düşünmek doğru değil. Çoğu zaman tam tersi oluşabilmekte, çünkü skiller gidişatı yönetme kabiliyetinizi sabote ediyor olabilirler.

Skill aslında bilgi değil, kodlanmış bir çalışma kültürüdür. Kendi kültürünüzü mü oluşturacaksınız yoksa başkalarının kültürünümü adapte etmeye çalışacaksınız?

Yazılım Üretim Hattı

Fikirden canlı ürüne nasıl geliyoruz, 10 adımda anlatalım (uçtan uca üretim modeli)

1. Güzel bir fikir buluyoruz. Başka kimsede bu fikrin olmaması lazım ;-)

2. Sonra Gpt ile geniş kapsamlı, saatler süren analiz seansları yapıyoruz.

3. Daha önce bolca bahsettiğim gibi loop engineering yapabilmek için gerekli iş paketlerini Gpt’ye hazırlattırıyoruz.

4. Akabinde loop.sh ile döngüyü başlatıyoruz ve bilgisayarın ekranını kapatıyoruz.

5. 24 ya da 48 saat sonra durum nedir diye Gpt’ye soruyoruz. Benim projelerim genelde gün ortasında başlıyor ve ertesi sabah kalktığımda ürün çalışır halde bekliyor oluyor.

6. Ürünü lokalde test ediyoruz. Eksiklerini tamamlattırıyoruz, hataları düzelttiriyoruz. Ben bu safhaya software factory’den çıkan uygulama için finetuning ismini veriyorum.

7. Daha sonra ilk deployment için sunucu hazırlıkları başlıyor. Bu işi yine Gpt üstleniyor. Gpt daha önce kurulmuş olan uygulamaları referans niteliğinde kullanarak yeni uygulamayı sunucularda high avaılable ve loadbalancer arkasında yer alacak şekilde birden fazla sunucuda kurma hazırlıklarını tamamlıyor. Çok daha önce tamamen dışarıya kapatılmış ve hardening yapılmış sunuculardan oluşan bir cluster sistemini Gpt ile zaten kurmuştuk.

8. Her projede ship.sh isminde bir script var. Bu bir wrapper script ve önce release.sh ile sürüm oluşturuluyor. Eğer bir flutter projesi ise android, ios, macos, windows, llinux, web sürümleri oluşturuluyor. Her sürüm öncesinde mevcut tüm testler koşturuluyor. Eğer bir backend projesi ise sürüm jar dosyası olarak çıkıyor. Sürüm artifact repositöry’ye yüklendikten sonra deploy.sh ile doğrudan sunuculara aktarılıyor. Yükleme öncesinde precheck ile sunucular check ediliyor. Deployment hatalı olursa, rollback yapılarak, eski sürüm aktifleştiriliyor.

9. Bir uydu uygulamamız olan kokpit ile hangi sunucuda hangi uygulamanın hangi sürümünün deploy edildiğini görebiliyoruz. deploy.sh son adımda kokpit için gerekli yüklemeleri yapıyor.

10. Bu noktadan itibaren fikir artık canlı canlı canlıda çalışır durumda. Fikir artık fikir değildir. Analiz edilmiş, geliştirilmiş, test edilmiş, sürümlenmiş, birden fazla sunucuya deploy edilmiş, gerektiğinde rollback edilebilir ve Kokpit üzerinden izlenebilir canlı bir üründür.

Fikirden canlı ürüne giden yol artık aylarla değil, günlerle; bazen saatlerle ölçülüyor.

Fikirden uygulama üreten ve canlıya alan üretim hattına hoşgeldiniz.

Yoruldum

Ben eskiden kod yazarken bu kadar zihinsel yorulmuyordum.

Spesifik bir şeye odaklanıp, saatlerce onunla uğraşabiliyordum.

Şimdi durum değişti.

Kod yazmıyorum. Kodu yazdırıyorum. Kodu da artık okumuyorum.

Ama eski çalışma sistemime göre bir değişim söz konusu.

Artık herşeyi en ince detayına kadar anlayıp, yapay zeka ajanlarını yönlendirmem ve yönetmem gerekiyor. Paralelde 2-3 değişik proje ve onlarca ajanla çalışıyorum ve bu detaycı çalışma tarzı zihinsel olarak beni yoruyor. Yorucu olan context switching + sürekli karar verme birleşimi.

Şikayet etmiyorum. Bu şekilde çalışmak ve aylar sonra ortaya çıkabilecek ürünleri birkaç gün içinde canlıya almak kadar eğlenceli bir şey yok.

Sadece zihinsel çalışma tarzım bile değişikliğe uğramış. Yeni farkına varıyorum.

Eskiden bilgisayarın işlemcisi gibiydim. Şimdi bilgisayarların schedüler’i gibi çalışıyorum.

Yapay zeka must have diyorsak, bu çalışma tarzının ne yazık ki bir alternativi yok.

Token ve Üretim Kapasitesi İlişkisi

Oh, oh!

Gpt haftalık limitim full, üzerinde birde bedava fulleme kredisi vermişler. Etti mi %200.

Claude codex de aynı şekilde full. Orada da bir resetleme kredisi var.

Toplamda %400 yapay zeka sermayem var.

Şimdi bu %400’ün yani yapay zeka sermayesinin ne anlama geldiğini somut bir örnek ile açıklayayım. Ben burada harcayabileceğim token görmüyorum. Ben burada üretim kapasitesi görüyorum.

Ben bununla şimdi 3 tane uygulama çıkartırım. Her birinin kendi desktop, mobil ve web arayüzü ve spring backend’ı var.

Sadece bir tanesi için 3 kişilik bir ekip bir ay çalışırdı.

Nereden nereye geldiğimizin küçük ama ifade gücü çok yüksek bir örneği.

Burada değişen şey sadece yazılım geliştirme hızımız değil aslında.

Eskiden yazılım üretme kapasitesini insan sayısı ve zaman ile ölçüyorduk. Üç yazılımcı, bir ay, bir uygulama gibi.

Şimdi bunun yanına yeni bir üretim faktörü eklendi: yapay zeka sermayesi.

Ben artık elimdeki GPT ve Claude limitlerine baktığımda sadece token ya da kullanım hakkı görmüyorum. Doğrudan üretim kapasitesi görüyorum.

Belki de yazılım dünyasında yaşanan asıl dönüşüm bu.

Yapay zeka sadece yazılımcının daha hızlı kod yazmasını sağlamadı. Bir kişinin ulaşabileceği üretim kapasitesini değiştirdi.

Yapay Zeka İle TDD

Daha önce TDD (Test Driven Development) yaptınız mı?

TDD’de çalışma mekanizması kabaca şöyle işler:

Önce bir test yazarsınız. Test çalışmaz, çünkü henüz kodda karşılığı yoktur. Sonra testi çalışır hale getirene kadar implementasyonu yaparsınız. Ardından yeni bir test yazarsınız. O da çalışmaz. Onu çalışır hale getirecek kodu yazarsınız. Böylece sürekli çalışmayan testler yeni kodu doğurur.

Testler kodun arkasından değil, kod testlerin arkasından gelir.

Malum, artık kod yazmıyoruz :)

O zaman TDD de yapamayız mı?

Tam tersine.

Yapay zeka ajanlarına TDD yaptırabiliriz.

Reçetesi şöyle:

Bir projeye başlamadan önce aklınıza gelen tüm onay/kabul kriterlerini bir dosyada tanımlayın.

Örneğin:

Given: Kullanıcı login olmak için kullanıcı adı ve şifresini girer.

When: Login tuşuna basar.

And: Girdiği şifre hatalıdır.

Then: Giriş engellenir ve kullanıcıya hata mesajı gösterilir.

Bu şekilde aklınıza gelen tüm kabul kriterlerini tanımlayın. Ardından yapay zeka ajanına şunu söyleyin:

Her kabul kriteri için bir E2E testi oluştur. Örneğin Cypress ile.

Ajan muhtemelen size: “Fakat bu testler mevcut implementasyonda çalışmayacak.” diyecektir.

Cevabınız:

“Zaten istediğim bu. Testleri oluştur. Sonra bütün testler yeşil olana kadar implementasyonu geliştir.”

İşte bu noktadan itibaren çalışma şekli değişiyor.

Artık yapay zekaya: “Şu özelliği geliştir.” demiyorsunuz.

Ona çalışması gereken testleri veriyorsunuz.

Ajanin görevi ise sistemi bu testleri geçecek hale getirmek oluyor.

→Test (red)

→ Implementasyon

→ Test (green)

→ Yeni test (red)

→ Yeni implementasyon

→ Test (green)

Yani TDD ortadan kalkmadı. Sadece artık testi geçecek kodu biz yazmıyoruz. TDD yapan bir yapay zeka ajanımız var.

Yapay Zeka Daha İyi Kod Yazıyor

Yazılımcıların yapay zeka araçlarının yaptığı işlere karşı tereddüt etmesinin bence temel bir sebebi var:

Yazılımcılar, yazılımın ne kadar kırılgan olduğunu biliyorlar.

Mutlaka düşünülmemiş bir edge case vardır. Mutlaka hesaba katılmamış bir yan etki vardır. Bir yeri düzeltirsin, başka bir yer bozulur. Hop, sistem yamulur. :)

Zaten yazılımcılar yıllardır tam da bu nedenle regresyonu önleyecek mekanizmalar geliştiriyorlar: testler, type safety, static analiz, code review, CI/CD, monitoring vs.

Kendi yazdıkları kodun ne kadar kırılgan olabileceğini bildikleri için, doğal olarak yapay zekanın yazdığı koda da aynı şüpheyle yaklaşıyorlar.

Fakat burada önemli bir fark var.

Yapay zeka sadece kod üreten bir araç değil. Elindeki kod tabanını, gereksinimleri, testleri, logları ve runtime davranışını birlikte analiz edebildiğinde, bir insanın tek tek zihninde tutmakta zorlanacağı kadar fazla ilişkiyi aynı anda değerlendirebiliyor.

Benim bugüne kadarki tecrübem şu:

Yapay zeka şaşırtıcı derecede sağlam ve nokta atışı çözümler üretebiliyor.

Bana göre yapay zeka, doğru mühendislik mekanizmalarıyla çevrelendiğinde, insanlardan çok daha iyi kod yazabiliyor.

Runtime’da Kendini Tamir Eden Uygulamalar

Kendi kendini tamir (hot refactoring) eden uygulamalar devrinden bahsetmiştim.

Bunu kendi projelerimde nasıl uygulayacağımın reçetesini veriyorum.

– OpenAI’in max 20 aboneliğini kullan

– Sunuculara Codex CLI kur

– Git üzerinden projeleri klonla, yerlerini Codex ile paylaş

– Uygulamaların runtime çalışma ayarlarını Codex ile paylaş

– Çalışan uygulamalar için eşdeğer bir staging alanı oluştur

– Her işlem öncesinde prod DB backup oluştur ve staging alanında restore et

– Log, metric, health check ve gerektiğinde thread/heap dump gibi runtime verilerine Codex’in erişebilmesini sağla

– Uygulamanın sağlıklı çalışıp çalışmadığını belirleyen kuralları net olarak tanımla

– Bir hata oluştuğunda önce runtime verileri üzerinden root cause analizi yaptır

– Tespit edilen problem için kod değişikliğini staging üzerinde yaptır

– Unit, integration ve özellikle E2E testlerini otomatik çalıştır

– Staging üzerinde canlıya mümkün olduğunca yakın koşullarda yeni sürümü ayağa kaldır

– Aynı hatanın tekrar oluşmadığını ve mevcut fonksiyonların bozulmadığını doğrulat

– Tüm kontroller başarılıysa yeni sürümü oluştur

– Rolling deployment ile canlıya al

– Deployment sonrasında log, metric ve health check’leri tekrar kontrol ettir

– Bir regresyon tespit edilirse otomatik rollback yap

– Yapılan değişikliği, sebebini ve doğrulama sonuçlarını kayıt altına al

Böylece döngü şu hale geliyor:

Detect → Diagnose → Fix → Test → Deploy → Observe → Rollback

Buradaki kritik nokta Codex’in canlıda kafasına göre kod değiştirmesi değil.

Production problemi ortaya çıkarıyor. Yapay zeka problemi analiz ediyor. Düzeltmeyi staging üzerinde gerçekleştiriyor ve doğruluyor. Başarılı olan değişiklik kontrollü şekilde production’a taşınıyor.

Yani aslında uygulama kendi kodunu canlıda canlı canlı değiştirmiyor.

Canlıdan gelen geri bildirim, uygulamanın kendi yeni sürümünü üretmesini tetikliyor.

Benim “hot refactoring” dediğim şey tam olarak bu.

Bir sonraki aşama ise daha ilginç:

İnsan müdahalesini bu döngüden adım adım çıkarmak.

O zaman elimizde sadece kendi kendini tamir eden değil, kendi kendini işleten bir yazılım sistemi kalıyor.

Tek Kişilik Dev Yazılım Kadroları Dönemi

Tek kişilik dev kadrolarla yazılım geliştirmek için gerekli son eşiğin de aşıldığını düşünüyorum.

Bu son eşik neydi?

Sürümleme, deployment ve canlı işletim.

Kod yazmayı zaten yapay zekaya devretmeye başladık. Test, analiz ve refactoring süreçlerinde de aynı dönüşüm yaşanıyor.

Şimdi buna deployment ve production operasyonları da ekleniyor.

Bunların tamamını yapay zekayı yazılım geliştirme sürecine entegre ederek birkaç sesli komutla yönetmek mümkün hale geliyor.

Artık tek bir senior software engineer;

– gereksinimleri tanımlayabilir,

– uygulamayı geliştirebilir,

– test ettirebilir,

– sürümleyebilir,

– canlıya alabilir,

– canlidaki hataları analiz edip giderebilir,

– uygulamayı yeni gereksinimlere adapte edebilir

ve bu döngüyü istediği kadar tekrarlayabilir.

Yani eskiden farklı uzmanlıklara ve kalabalık ekiplere dağıtılmış olan yazılım yaşam döngüsünün tamamı, giderek tek kişinin yönettiği yapay zeka destekli bir mühendislik sistemine dönüşüyor.

Tek kişilik dev yazılım kadroları dönemi başlıyor.

Hot Refactoring

Ok, kritik bir eşiğe geldik.

Ben uygulamaların canlıya alınması ve orada işletilmesi konusunda da yapay zekayı öncelikli araç olarak kullanıyorum.

Neler yaptırıyorum?

– Sunucularda yeni bir servis için gerekli altyapı kurulumu (nginx, service start/stop scriptleri, veri tabanı oluşumu vb)

– Bir ürünün doğrudan HA konfigürasyonda rollilng deployment

– Hata olması durumunda hatanın analizi ve çözümü

– Monitoring işlemleri

Bir sonraki adımda runtime refactoring.

Runtime refactoring nedir?

Uygulamanın canlı canlı, bulunan bir hata sonrasında refactor ve hemen yeni sürümü ile replace edilmesi. Buna hot refactoring bile diyebiliriz.

Yani runtime’da kendi kendini tamir eden uygulamalar devrine geçiyoruz ;-)

Döngü şu şekilde olacak:

Observe → Diagnose → Modify → Verify → Deploy → Observe

Bu modelde yapay zeka sadece kod yazan ajan olmaktan çıkıyor. Production lifecycle’ın tamamını yöneten bir engineering agent haline geliyor.

Kendi kendini tamir eden uygumalar…

Şimdiye kadar bu self healing mekanizmaları container seviyesinde yapılabiliyordu, yani restart container ile servis yeniden çalışır hale geliyordu.

Eski self-healing: sistemi yeniden başlat.

Yeni self-healing: sistemi yeniden yaz ve deploy et.

Bunun güvenli olabilmesi için yapay zekanın etrafında deterministik bir güvenlik çemberi gerekiyor: E2E testleri, statik kod analizi, tanımlı mimarı kurallar, security scanning, health checks, rolling deployment ve otomatik rollback.

Yazılımda nasıl herşeyi artık otomatize edebiliyorsak, ürünün canlıya alınış ve işletilmesini de o derece otomatize edebiliriz.

Yazılımcı olarak çok heyecanlı zamanlar bizi bekliyor.