Kategori arşivi: Yapay Zeka

Nereden Nereye

Kurduğum setup içerisinde şu an tek darboğaz GPT.

Oluşturduğum Software Factory bünyesinde, Loop Engineering yaklaşımıyla projelerin nasıl otonom bir şekilde geliştirildiğinden daha önce birçok kez bahsettim.

Loop Engineering için GPT + Opus ikilisini kullanıyorum.

İş bölümü oldukça net:

Opus: Implementasyon ve kod geliştirme

GPT: Analiz, mimari değerlendirme ve code review

Opus Max 20x üyeliğiyle bu setup içerisinde 2-3 projeyi paralel olarak 7/24, kesintisiz geliştirmek mümkün. Üstelik haftalık ve saatlik kullanım limitlerim dolmuyor.

Lakin GPT tarafında durum farklı.

Özellikle Sol ve Astra modellerinin gelmesiyle birlikte haftalık kullanım kontenjanım artık iki gün bile yetmemeye başladı.

Bu yüzden haftalık rate limit engeline takılmamak için üç ayrı Pro hesabı kullanıyorum. Sürekli hesap değiştirmek zorunda kalıyorum.

İşin ilginç tarafı şu:

Artık yazılım üretim kapasitemi sınırlayan faktör ne yazılımcı sayısı ne de kod geliştirme hızı. Yapay zeka modellerinin kullanım limitleri.

Software Factory’nin üretim kapasitesi, kullandığım modellerin inference kapasitesine ve erişim kotalarına bağımlı hale gelmiş durumda.

Yazılım mühendisliğinde darboğazın nereden nereye taşındığına bakar mısınız? ;-)

Çocuk Oyuncağı

Gerçekler artık şu şekilde:

Software Engineer ünvanı artık sadece yazılım geliştirme yetkinliğini ifade etmiyor.

Bir Software Engineer’ın aşağıdaki rolleri de üstlenebilecek yetkinliğe sahip olması gerekiyor:

– Requirements Engineer

– Software Architect

– Test / QA Engineer

– Security Engineer

– Release and Deployment Engineer

– DevOps Engineer

– Performance Engineer

– Site Reliability Engineer (SRE)

Bir yazılımcının bütün bu işleri bizzat yapması gerekmiyor, ancak yapay zekanın yaptığı işleri değerlendirebilecek ve sonuçlarının sorumluluğunu üstlenebilecek yetkinliğe sahip olması gerekiyor.

Neden Vibe Coding Engineer diye bir mühendislik disiplini yok?

Çünkü artık kod yazmıyoruz ;-)

Kod yazmak, yazılım mühendisliğinin sadece bir parçasıydı. Yapay zeka bu kısmı büyük ölçüde üstlenmiş durumda.

Vibecoder’lara selamlarımla. 

Bu işin çocuk oyuncağı olduğunu düşünmeye devem edeebilirler.

Her Yazılımcı Artık bir Gereksinim Analizcisi

Yapay zeka sizi gereksinim analisti olmaya zorluyor.

Zamanla gereksinimleri ne kadar net ifade etmeniz gerektiğini anlıyorsunuz, çünkü yapay zekanın ürettiği çıktılar her zaman beklentilerinizle örtüşmüyor.

Bu noktada kendinize şu soruyu sormaya başlıyorsunuz: “Ben ne istediğimi nasıl daha iyi anlatabilirim?”

Bu soru sizi daha detaylı, daha sistematik ve daha analitik düşünmeye zorluyor.

Eskiden yazılımcıların gereksinim analizi konusunda ciddi eksikleri vardı. Büyük projelerde genellikle bir Requirements Engineer bulunurdu. Gereksinimler bu uzmanlar tarafından analiz edilir, detaylandırılır ve yazılımcılara hazır iş paketleri olarak sunulurdu.

Yani yazılımcılardan gereksinimleri keşfetmeleri değil, kendilerine verilen gereksinimleri implemente etmeleri beklenirdi.

Şimdi ise durum değişiyor.

Yapay zeka ile çalışan bir yazılımcı, öncelikle bir Requirements Engineer olmak zorunda.

Ne istediğini, neden istediğini, sistemin nasıl davranması gerektiğini ve hangi koşullarda ne yapacağını tarif edebilmesi gerekiyor.

Ardından bir Software Architect oluyor. Sistemin mimarisini, bileşenlerini, aralarındaki ilişkileri ve teknik sınırları belirliyor.

Sonra bir Test Engineer oluyor. Ortaya çıkan ürünün gereksinimleri karşılayıp karşılamadığını, beklenen davranışları sergileyip sergilemediğini doğruluyor.

Akabinde bir Release Engineer oluyor. Ürünün sürümlenmesini, paketlenmesini ve dağıtıma hazırlanmasını yönetiyor.

Son olarak bir DevOps Engineer oluyor. Ürünü canlıya alıyor, çalışmasını izliyor ve operasyonel sürekliliğini sağlıyor.

Dikkat ederseniz bütün bu süreçte yazılımcının kod yazmasından neredeyse hiç bahsetmedim, çünkü kodu artık büyük ölçüde yapay zeka yazıyor.

Ancak yapay zekanın neyi, nasıl ve neden yapacağını belirleyen kişi hala yazılımcı.

Eskiden yazılımcı, yazılım geliştirme sürecinin bir halkasıydı. Şimdi ise bütün zinciri yönetmek zorunda.

Artık yalnızca kod yazmayı bilmek yeterli değil. Yazılım mühendisliğinin tamamını anlamak gerekiyor.

Bu sebeple eskiden sadece kod yazan ama başka bir şeye karışmak istemeyen yazılımcıların kariyeri noktalanmıştır. Buna karşın interdisiplin çalışabilen mühendislere ihtiyaç daha da artacak.

Eğer kendinize yapay zeka çağında gelişmelere nasıl adapte edebilirim sorusunu soruyorsanız bu yazıda geçen mühendislik alanlarına naçizane odakllanmanızı tavsiye ederdim.  Ya tüm zincire hakimsiniz ya da oyun dışı kalırsınız.

Artık yazılım mühendisliğini gerçek anlamda bir bütün olarak yaşabileceğimiz bir safhaya geldik. Bu çok güzel bir haber, lakin bu her mühendislik alanında derinleşmeye gerektiriyor. Bunu zaten yıllarca yapmış olan senior developer’lar 10-0 öndeler.

Her İstediğini Yapabiliyor Olmak

Yapay zeka araçları ile çok hızlı proje çıkarmak mümkün.

Ancak bunun bir de karanlık tarafı var:

Maymun iştahlılık!

Bir girişimciyseniz, üstüne üstlük bir de yazılımcıysanız ve senior developer seviyesindeyseniz, yüzlerce yazılımcıdan oluşan bir ordunuz varmış gibi istediğiniz projeyi geliştirebiliyorsunuz.

Lakin bu muazzam üretim kapasitesi beraberinde ciddi bir tehlike getiriyor.

Bahsettiğim maymun iştahlılık ya bir ürüne odaklanıp onu hızlıca tamamlamanızı engelliyor ya da “Şu da olsun, bunu da ekleyeyim” diyerek ürünün gereksiz yere şişmesine ve zaman kaybetmenize neden oluyor.

Biraz önce baktım. Otuz civarında Git repository’si oluşmuş durumda. Bunların her biri ayrı bir proje. Çok geniş kapsamlı bir platform üzerinde çalışmanın getirdiği yük bu. Ama aklıma sürekli yeni fikirler gelmiyor da değil.

Peki ben bu maymun iştahlılığı nasıl kontrol etmeye çalışıyorum?

Öncelikle proje tamamlandığında nasıl bir ürünün ortaya çıkması gerektiğine dair çok net bir vizyona sahip olmak gerekiyor.

Ne pahasına olursa olsun, o vizyondan sapmamak lazım.

İkinci adımda alt projelerin öncelik sırası geliyor. “Hangi projeyi şimdi çıkarmak zorundayım, hangisini öteleyebilirim?” sorularını kendime soruyorum.

Buradan çıkan öncelik sırasına göre projeleri tamamlamaya çalışıyorum.

Genellikle aynı anda 2-3 proje üzerinde çalışıyorum. Bunların büyük bir kısmı zaten Software Factory ile otonom olarak oluşturulan uygulamalar. Yani inşa edildikleri süre boyunca onlara dokunmuyorum. Fabrikadan çıktıktan sonra ise finetuning ile gereksinimlere göre adaptasyonlarını yapmaya başlıyorum.

Bazen aklıma çok ilginç bir fikir geliyor ve onu hemen hayata geçirme dürtüsüyle baş etmekte zorlanıyorum.

Bu durumda mevcut işimi bırakıp yeni fikrin peşinden koşmak yerine, loop engineering ve prompt engineering süreçlerinde oluşan boşluklarda, bir side project olarak o fikir üzerinde çalışmaya başlıyorum.

Ama ana odağımı o projeye kaydırmıyorum.

Buradaki amacım ekran başındaki boş vakitleri değerlendirmek ve yeni fikirleri denemek. Ana projelerin önceliğini değiştirmek değil.

Eskiden en büyük problemimiz fikirlerimizi hayata geçirecek yeterli üretim kapasitesine sahip olmamaktı.

Şimdi ise üretim kapasitemiz o kadar arttı ki asıl problem hangi fikirleri hayata geçirmeyeceğimize karar vermek hâline geldi.

Yapay zeka çağında girişimcilerin en önemli becerilerinden biri de sanırım bu olacak:

Her yapabildiğini yapmamak.

DevOps Rolünün Geleceği

Daha önce de bahsetmiştim. Ajanların parladığı tek alan kod yazmak değil.

Canlı ortamların yönetimi için yapay zeka ajanları biçilmiş kaftan. DevOps süreçlerinin çok büyük bir bölümünü, hatta zamanla neredeyse tamamını ajanlara devretmek mümkün.

Bu amaçla Agentic Operations Center (AOC) adını verdiğim bir altyapı kurgulamaya başladım.

Bir uygulama düşünün. Bu uygulama bünyesinde aşağıdaki çalışma alanları tanımlı:

– Altyapı: Sunucular, CPU, RAM, disk ve diğer sistem kaynakları.

– Uygulamalar: Canlı ortamda çalışan servisler ve uygulamalar.

– Veritabanları: Performans, erişilebilirlik, bakım ve optimizasyon.

– Sürüm ve Deployment: Release, artifact ve deployment yönetimi.

– Güvenlik: Güvenlik açıklarının, tehditlerin ve anormal aktivitelerin tespiti.

– Incident Management: Sorunların tespiti, analizi, önceliklendirilmesi ve giderilmesi.

Her çalışma alanında görevleri ve sorumlulukları önceden belirlenmiş bir veya birden fazla ajan tanımlamak mümkün.

İkinci aşamada bu ajanların canlı ortama deploy edilmesi geliyor.

Bunun için canlı ortamda ajan koordinasyonunu, onboarding süreçlerini ve görev dağılımını yöneten merkezi bir uygulama bulunuyor.

Bu uygulama üzerinden yeni ajanların işbaşı yapmasını sağlamak, mevcut ajanlara görev vermek, çalışmalarını takip etmek ve hangi ajanın nerede, ne zaman, hangi işlemi gerçekleştirdiğini görmek mümkün olacak.

Yani bir nevi yapay zeka ajanlarından oluşan otonom bir operasyon ekibi kuruyoruz.

Üstelik bu ajanlar yalnızca sistemleri izlemekle kalmayacak. Sorunları analiz edecek, birbirleriyle koordineli çalışacak ve kendilerine tanınan yetkiler çerçevesinde gerekli müdahaleleri de gerçekleştirebilecekler.

Sistem henüz fikir ve tasarım aşamasında. Ancak birkaç gün içerisinde çalışan ilk versiyonunu ortaya çıkarmayı hedefliyorum.

Bir sonraki yazımda detaylarını sizlerle paylaşacağım.

Peki, DevOps mühendislerine ne olacak?

Bana kalırsa DevOps rolü ciddi bir dönüşüm geçirecek.

Bugün DevOps mühendislerinin gerçekleştirdiği operasyonel işlerin önemli bir kısmını gelecekte ajanlar üstlenecek.

DevOps mühendisleri ise doğrudan operasyonları gerçekleştirmek yerine, bu operasyonları yürüten ajan sistemlerini tasarlayan, geliştiren, yöneten ve denetleyen kişilere dönüşecekler.

Yani DevOps ortadan kalkmayacak. DevOps’un operasyonel iş gücü insanlardan ajanlara kayacak.

Gereksinim Analizi

Eskiden bir uygulamanın nasıl olması gerektiğini anlamak için gerçek anlamda bir araştırma yapmak, müşteriye detaylı sorular sormak, gereksinimleri çıkarmak, mockup ve prototipler hazırlamak, ardından mimariyi oluşturmak gerekiyordu.

Simdi yapay zekaya istediğiniz şeyin bir resmini vermeniz bile yeterli olabiliyor. Detaylara haftalarca kafa patlatmadan, “Şöyle bir şey istiyorum” diyorsunuz ve kısa süre içinde çalışan bir karşılığını görebiliyorsunuz.

Burada aslında çok daha hızlı bir şekilde müşterinin isteklerini aynalayan bir çözüme ulaşmanın yolu açılıyor.

Müşteri “Bu olmamış” dese bile artık bu eskisi kadar büyük bir problem değil. Çünkü gerekli değişiklikleri çok hızlı bir şekilde yapıp yeni versiyonu tekrar müşterinin önüne koyabiliyorsunuz.

Bir anlamda gereksinim analizi ürün geliştirmeden önce yapılan bir aşama olmaktan çıkıp, ürünün kendisi üzerinden yapılan sürekli bir keşif sürecine dönüşüyor.

Vibe Coding ve Kalp Cerrahları

İşin vahametini göstermek için bir analoji aktarayım.

Kalp cerrahlarını düşünün.

Şimdi de herkesin yapay zeka aracılığıyla kalp ameliyatı yapabileceğine inandığını ve gerçekten ameliyat yapmaya başladığını düşünün.

Yazılım geliştirmek, özellikle büyük ve kritik sistemlerde, her zaman açık kalp ameliyatı yapmak gibiydi.

Bir cerrahin insan vücuduna müdahale edebilecek seviyeye gelmesi yıllar süren eğitim, gözetim ve pratik gerektirirken; yazılım dünyasında yeni mezun olmuş birisinin kurumsalda ise başlayıp birkaç hafta sonra binlerce insanın kullandığı sistemlerin kodunu değiştirmesi son derece normal karşılanıyordu.

Ama şimdi ölçek değişti.

Vibe coding yapanların projelere ne kadar büyük zarar verebileceklerini artık siz düşünün.

Çok acil bir şekilde bu mesleğe yeni başlayanların adam akıllı bir eğitim sürecinden geçirilmeleri ve zarar vermeden çalışabilecek seviyeye getirilmeleri gerekiyor.

Diskalifiye Olmayan Yazılımcı

Yapay zeka dönemini daha tam olarak idrak edememiş olanlara neden sadece deneyimli bir yazılımcının ön kişinin işini artık tek başına yapabileceğini hatırlatalım.

Evet, eskiden bir yazılım ürününü çıkarmak için frontend, backend, test, product owner, devops gibi rolleri üstlenen insanlara ihtiyacınız vardı. Yani bu işleri çoğu zaman 5-10 kişilik ekipler yapmak zorundaydı.

Şimdi bu 5-10 kişilik ekibin yaptıklarına bir göz atalım.

Neden bu kadar kişiye ihtiyaç vardı? Projeler neden aylar, hatta yıllar sürerdi?

Çünkü yapılması gereken muazzam miktarda manuel iş vardı. Sonra bunların hepsinin birbiriyle koordinasyonu gerekirdi. Toplantı, sprint, sürüm, deployment, müşteri istekleri derken iş uzayıp giderdi ve birçok elden geçerdi. 

Dolayısıyla klasik yazılım geliştirme metodolojilerinin önemli bir kısmı aslında sadece yazılım geliştirmek için değil, insanlar arasındaki bu koordinasyon problemini yönetebilmek için ortaya çıktı.

Şimdi denklemin temel parametrelerinden biri değişiyor.

Bir yazılımcının yanında artık kod yazabilen, test oluşturabilen, kod tabanını analiz edebilen, dokümantasyon hazırlayabilen, bug araştırabilen, refactoring yapabilen ve altyapı scriptleri oluşturabilen yapay zeka ajanları var.

Deneyimli bir yazılımcı artık tek başına eskiden on kişilik bir ekibin yaptığı işi yapabilir, daha doğrusu ekibin yerine ajanların geçmesini ve onların yönetimini sağlayabilir.

Daha önceki bir yazımda 200K maaş için adaydan beklentilerdile getirdim.

Çoğu gelen yorumda “koyunun altında buzağı arıyorsun, hiç kimsede bu kadar yetenek bir arada olamaz” dendi.

Şunun altını çizeyim. Bu hiçbir şey değil. Yapay zeka bu hızda ilerlemeye devam ettiğinde, adaylardan beklenen yetenek ve tecrübelerde o hızla artacak.

Artık ajanların neredeyse kendi başlalarına sistem kurabilecekleri safhaya gelmiş durumdayız. Yazılımcı olarak diskalilfiye olmamak için bu hızlı gidişata ayak uydurmamız gerekiyor.

Scrum ve Sprint’in Sonu

Extreme Programming gibi çevik süreçlerdeki ana çalışma prensiplerinden biri, müşteriye kısa aralıklarla ürünün ne durumda olduğunu gösteren çalışan prototipler sunmaktı.

Bunun için bir ya da iki haftalık sprint’ler planlanır, bu zaman zarfında seçilen user story’ler ürünün parçası haline dönüştürülürdü.

Peki neden bir ya da iki hafta?

Çünkü yazılım geliştirmek zaman alan ve maliyetli bir işti.

Analiz yapılması, kodun yazılması, test edilmesi, code review’dan geçmesi, entegre edilmesi ve müşterinin deneyebileceği bir ortama deploy edilmesi gerekiyordu.

Yapay zeka bu sürelerin tamamını dramatik biçimde aşağıya çekiyor.

Bir user story’nin implementasyonu artık günler değil saatler sürebilir. Testleri aynı anda üretilebilir. Review ajanlar tarafından paralel yapılabilir. Cİ/CD ve deployment otomasyonu ile birkaç dakika sonra çalışan sistem müşterinin önüne konulabilir.

Bu durumda 1-2 haftalık sprint kavramının da sorgulanması gerekiyor.

Çünkü sprint aslında feedback loop’un uzunluğuydu.

Yapay zeka ile feedback loop kısaldıkça sprint de küçülmek zorunda.

User Story → Implementasyon → Test → Deploy → Feedback

Bu döngünün iki hafta sürmesi gerekmiyorsa neden iki haftalık sprint yapalım? Bu iki hafta müşteriden kopmak anlamına gelir. Bu zaman zarfında zaten istenilen ürünü oluşturmuş olabiliriz.

Bence sprint kavramını tamamen ortadan kaldırmak lazım.

Müşteri ve yazılımcı arasında artık realtime bir ilişki söz konusu.

Yazılımcı müşterinin istediği değişiklikleri hemen implemente edebilir ve akabinden bunları müşteriye gösterip, geri bildirim alabilir. Akabinde döngü yine başlar.

Çevik süreçler tamamen geri bildirim (feedback cycle) üzerine kurgulanmıştı. Pair programming, TDD, CI vb yöntemlerin hepsi hızlı bir şekilde geri bildirim almak için vardı. 

Şimdi bunlara gerek kalmadan gerçek zamanlı geri bildirim döngüleri oluşturabiliyoruz.

Bu yüzden geliştirme sürecinin temel zaman birimi “sprint” değil, feedback loop olmalı.

Senior Developer

10+ yıl tecrübeli ve artık “dinozor” olarak görülen yazılımcılar ile çok az yazılım tecrübesi olan yazılımcıları aynı kefeye koymaya başlamışlar.

Kod yazmanın ya da yazdırmanın yeterli olduğunu düşünüyorlar.

Yapay zekanın kod yazıyor olması iki jenerasyon arasındaki farkı öyle kolay kolay kapatamaz.

10+ yıl tecrübeli bir senior yazılımcının ne anlama geldiğini bilmiyorlar sanırım.

Açıklayalım.

Yazılım da diğer meslekler gibi çıraklık, kalfalık ve ustalık safhaları ihtiva eder.

Yeni mezun birisi çıraktır. Bu çıraklık birkaç sene sürer. Sonra işi kavradıysa kalfa olur. Kalfalık döneminde artık kendi başına birçok işi yapabilir, fakat hala yıllar boyunca farklı sistemler, problemler ve başarısızlıklar görmesi gerekir.

10+ seneye gelindiğinde, eğer yazılımcı kendisini gerçekten geliştirebildiyse ustalaşmıştır.

Usta yazılımcının farkı daha hızlı kod yazması değildir. Hatta bazen daha az kod yazar.

Fark şudur:

Çırak kendisine verilen problemi çözer.

Kalfa çözümün nasıl implemente edileceğini bilir.

Usta ise önce o problemin gerçekten çözülmesi gereken problem olup olmadığını sorgular.

Çırak kodu görür.

Kalfa uygulamayı görür.

Usta sistemi görür.

Şimdi bu seviyedeki bir yazılımcının eline yapay zeka araçlarını verin ve sadece oturup, neler yapabildiğini seyredin. Çok hızlı bir şekilde senior developer ne anlama gelir, size göstersin.

Yeni Darboğaz CI / CD

Bir sonraki patlama CI/CD pipeline’larında yaşanacak.

Yapay zeka deli gibi kod yazıyor. Ama koddan belki daha hızlı test yazıyor.

Bunun sonucu kontrolsüz bir test enflasyonu.

Ben şu anda bu problemle bizzat savaşıyorum. Bir backend sürümünün test, release ve deployment süresi 90 dakikaya dayanmış durumda.

Asıl problem test sayısı da değil.

Bu testlerin önemli bir bölümü sistemin davranışını değil, implementasyonunu test ediyor. Yani bir işlemin kod içinde hangi adımlarla gerçekleştirildiğini tek tek doğruluyor.

Bunun uzun vadede değeri düşük. Çünkü implementasyon, sistemin o anki modelinin yalnızca bir temsilidir ve değişebilir.

Implementasyon değiştiğinde bu testlerin de değişmesi gerekir. Değişmediğinde ise binlerce test her entegrasyonda ve her sürümde aynı implementasyon detaylarını tekrar tekrar doğrular. Test sayısı büyür ama sağladığı güven aynı oranda büyümez.

Yapay zeka çağında test stratejisinin de değişmesi gerekiyor.

Ben çözümü giderek daha fazla iki noktaya odaklanmakta görüyorum:

Kabul kriterleri ve sistem invariantları.

Yani:

“Bu metot şu üç fonksiyonu şu sırayla çağırıyor mu?” yerine,

“Bu işlem tamamlandığında sistemde doğru sonuç ortaya çıkıyor mu?”

ve:

“Sistemin hiçbir koşulda bozmaması gereken kurallar hala geçerli mi?”

Bu yaklaşımla test sayısı drastik şekilde azaltılabilirken sistemin gerçek davranışı ve dogruluk seviyesi korunabilir.

Yapay zeka çağında hedef maksimum test coverage olmamalı. Hedef, minimum test maliyetiyle maksimum davranışsal güven olmalı.

Aksi takdirde yapay zekanin kod üretim hızının bedelini CI/CD pipeline’larında ödeyeceğiz.

Bu tempo devam ederse bugün 90 dakika süren bir release yarın saatler, daha sonra günler sürebilir.

Kod üretimindeki darboğazı kaldırırken yeni darboğazı CI/CD tarafında yaratıyoruz.

Yazılımcıları Vahşi Doğaya Salın

Yapay zekaya maruz kalan yazılımcıların bugün yaşadığı çok büyük bir problem var.

Yapay zeka ile çalışan yazılımcılar, iş yerlerinde prompt engineering yaptıkları için uzun süre bilgisayarın başında pasif bir şekilde oturuyorlar.

Bazen dakikalarca ekrana bakıyor, yapay zekanın işini bitirmesini bekliyorlar.

Bunun ana sebeplerinden biri, prompt engineering yönteminin profesyonel yazılım geliştirme süreçleri için ölçeklenebilir bir çalışma biçimi olmaması.

Bu, er ya da geç yöneticilerin de dikkatini çekecek.

Çünkü yapay zeka çağında yazılımcının en değerli zamanı, yapay zekanın kod yazmasını izlediği zaman değildir.

Yazılımcıları daha verimli hale getirmek istiyorsak, onları bilgisayar başından kaldırıp vahşi doğaya salmamız gerekiyor.

Peki vahşi doğa neresi?

Şirketin kendisi.

Diğer çalışanlar, departmanlar, iş süreçleri, müşteriler, problemler, darboğazlar ve henüz yazılıma dönüşmemiş ihtiyaçlar.

Yazılımcı artık bütün gün masasının başında oturup kendisine verilen gereksinimleri koda dönüştüren kişi olmamalı.

Şirketin içinde dolaşmalı.

İnsanlarla konuşmalı.

Süreçleri gözlemlemeli.

Müşterinin yanına gitmeli.

Problemleri yerinde görmeli.

Henüz kimsenin yazılım problemi olarak tanımlamadığı problemleri keşfetmeli.

Sonra bilgisayarının başına dönüp ajanlara şunu söylemeli:

“Çözmemiz gereken problem bu.”

Bu kadar. Sorun net olarak tanımlandıktan sonra yapması gereken tek şey ./loop.sh komutunu koşturmak. Loop engineering ile ürün kısa bir zamanda çalışır hale gelecektir. Bu arada yazılımcı başka bir işin peşinde koşuyor olur ve bön bön ekrana bakmaz.

Bir anlamda:

Yazılımcıları bilgisayar başından kaldırın.

Vahşi doğaya salın.

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.