Yazar arşivleri: Özcan Acar

Özcan Acar hakkında

Bilgisayar mühendisi olan Özcan Acar 1997 yılından beri programcı olarak çalışıyor. KurumsalJava.com, SmartHomeProgrammer.com ve Mikrodevre.com adresleri altında blog yazıyor. Pratik Programcı Yayınları bünyesinde Pratik Spring, Pratik Agile, Pratik Git ve Design Patterns ismini taşıyan kitapları bulunmaktadır. 21.12.2009 tarihinde Java Champion olarak seçildi.

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.

Eskiden Girisimcilik – Simdi Girisimcilik

Eskiden girişimcilik:

— Bir fikrim var ama emin değilim. Önce birkaç kişiye danışayım.

— Fikir fena görünmüyor. Biraz pazar araştırması yapayım.

— Galiba olabilir. Bir MVP geliştireyim.

— Bunun için bir ekip ve bütçe lazım.

— Birkaç ay sonra MVP hazır. Şimdi test edebiliriz.

Şimdi girişimcilik:

— Bir fikrim var.

— Ürünü yaptım.

— 2 gün sonra: Test eder misin?

Holakrasi Nasıl Hayata Geçirilir?

Yönetim kültüründen daha önce bahsetmiştim. Biz şirket olarak holakrasi yönetim modelini benimsedik ve şirket içinde bu yönetim tarzını kullanacağız.

Holakrasi ile hiçbir çalışanın doğrudan bir amiri olmayacak. Çalışanlar belirli bir alan için kurulmuş bir hücre içinde faal olacaklar. Her hücre içinde maksimum 7-9 çalışan olacak.

Hücre içinde de doğrudan liderlik söz konusu değil. Şahıslar yerine roller tanımlı olacak; örneğin Backend Engineer, Product Owner ya da Customer Success gibi.

Holakrasi hakkında detayları daha önce yazdığım “Holakrasi ile Yeni Bir Yönetim Kültürü Oluşturmak” başlıklı yazımda bulabilirsiniz.

Yönetim kültürünü oturtabilmek için onun yaşanabilir hale gelmesi, yani günlük faaliyetlerin çerçevesini oluşturacak şekilde hayata geçirilmesi gerekiyor.

Bunun en akılcı yolu ise şirket içi süreçleri buna göre şekillendirmek.

Klasik şirketlerde süreçlerin büyük bir kısmı hiyerarşi üzerine kuruludur. Biz bunun tam tersini yapmak istiyoruz.

Kararın mümkün olduğu kadar kararın oluştuğu yerde alınmasını istiyoruz.

Bunun için şirket içindeki süreçleri kişiler üzerine değil, roller ve yetki alanları üzerine kuruyoruz.

Peki bunu günlük hayatta nasıl yaşatacağız?

Bunu desteklemek amacıyla şirket içi iletişim için kullandığımız Vellkam Connect uygulamasına holakratik yönetim modelini destekleyen özellikler ekledik.

Organizasyon menüsünden şirketin tüm holakratik yapısına erişmek mümkün. Her şey en tepede Kurucu Çember ile başlıyor; buradan alt çemberlere, hücrelere, rollere ve bu rollere tanımlanmış yetkilere kadar inilebiliyor.

Böylece organizasyon yapısı bir şema olmaktan çıkıp günlük çalışma hayatının bir parçası haline geliyor.

Bir çalışan kimin amiri olduğunu değil, hangi role sahip olduğunu, sorumluluklarının neler olduğunu ve hangi konularda karar verme yetkisine sahip olduğunu görüyor.

Temel prensibimiz basit:

Karar, mümkün olduğu kadar kararın oluştuğu yerde alınmalı.

Çalışanlar içinde bulundukları hücrenin hedeflerini biliyorlar. Bu hedeflerin ne oranda gerçekleştirildiğini ölçmek için çeşitli metrikler tanımlı.

Bunun yanı sıra çalışanlar kendi haftalık, aylık ve yıllık hedeflerini Vellkam Connect üzerinden yayınlayıp takip edebiliyorlar.

Buradaki nihai amacımız hücrelere ve dolayısıyla hücre sakinlerine mümkün olduğu kadar fazla otonomi kazandırmak.

Kendi kararlarını verebilmeleri, bu kararların sorumluluğunu üstlenebilmeleri, günlük faaliyetlerini hücresel ve kişisel hedefler doğrultusunda şekillendirebilmeleri ve başarılarını tanımlı metrikler üzerinden ölçebilmeleri gerekiyor.

Çünkü otonomi sadece karar verme özgürlüğü değildir.

Otonomi, karar verme yetkisi ile sonuçların sorumluluğunu aynı kişide buluşturmaktır.

Böyle bir organizasyon doğal olarak farklı bir çalışan profiline ihtiyaç duyuyor.

Sorumluluk alabilen, karar verebilen, bağımsız hareket edebilen, ekip içinde çalışabilen ve kendisine sürekli ne yapması gerektiğinin söylenmesine ihtiyaç duymayan insanlara ihtiyacımız var.

Bu yüzden aday mülakat süreçlerimizi de bu kriterlere göre şekillendireceğiz.

Bizim için bir adayın sadece teknik olarak ne kadar iyi olduğu yeterli olmayacak.

Kendisine verilen otonomiyi kullanıp kullanamayacağı, sorumluluk üstlenip üstlenemeyeceği ve bir hücrenin bağımsız bir parçası olarak hareket edip edemeyeceği de en az teknik yeterlilik kadar önemli olacak.

Çünkü kurmaya çalıştığımız yapıda en son istediğimiz şey, bir kenarda oturup kendisine iş verilmesini bekleyen bir çalışan.

Holokraside kimse size iş vermek zorunda değil.

Hedefi biliyorsunuz. Rolünüzü biliyorsunuz. Yetkinizi biliyorsunuz. Metrikleri biliyorsunuz.

Geriye tek bir şey kalıyor:

Sorumluluk almak ve harekete geçmek.

Birgün böyle bir hücrede birlikte çalışma ümidiyle.

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.

Hayaller Nasıl Gerçekleşir?

Ok, biraz da vizyon ve hayallerin nasıl gerçekleştirilebileceğinden bahsedlim.

Bunun için karanlık oda prensibine deyinmek gerekiyor.

Önce evrenden başlayalım.

Evren genişliyor. Üstelik çok uzak mesafelerde bu genişleme öyle boyutlara ulaşabiliyor ki, bugün bazı galaksilerden yayılan ışık gelecekte bize hiçbir zaman ulaşamayacak. Burada ışığın uzay içerisinde ışık hızından daha hızlı hareket etmesinden değil, uzayın kendisinin genişlemesinden bahsediyoruz.

Evrenin genişlediği yer de mekan mı olusuyor yoksa o mekan orada var mı, bilmiyoruz. Büyük bir ihtimalle hiçlikten bahsediyoruz. Bu bir şehir kurmak gibi bir şey olsa gerek. Önce şehrin üzerinde kurulacağı alan hazırlanıyor. Ardından altyapı geliyor. Kanalizasyon, elektrik, yollar, caddeler ve nihayet o caddelerin üzerinde evler yükseliyor.

Evren örneğinde ışığın hareket edebilmesi için mekan içindeki alanlara (field) ihtiyacı var. Bunlari manyetik alanlar gibi düsünün. Tren raylari gibi de düşünebiliriniz. O halde evrenin genişlemediği yerlere ışığın ulaşması imkansız, çünkü orada yayılabilmek için gerekli alanlar yok. Bu yüzden büyük bir ihtimalle evren yayılmaya meğil ettiği yerlere o mekan ve zaman oluşuyor.  Dediğim gibi, bilmiyoruz. Belki fizik bilen arkadaşlar burayı yorumlayabilirler.

Şimdi bunu bir adım daha ileri götürelim. Yeni oluşan bir mekan karanlıktır. Karanlık bir oda gibi düşünün. Oraya ilk ışık fotonları ulatığında odada bir lamba yanar gibi o mekan aydınlanacaktır. Yani önden oluşumu devam eden karanlık içindeki mekanı ortaya çıkaran ışığın kendisi.

Şimdi buradan kendi hayal ve vizyonlarımızı nasıl gerçekleştireceğimiz dair bir analoji oluşturalım.

Hayal ve vizyonlarda evredenki oluşmamış mekanlardır. Onlara görünür hale getirmek için lambayı yakmamız gerekiyor.

Bu yakılan lamba önce hayalin ya da vizyonun son halini göz önüne getirme ve en ince detayına kadar işçel yaşama şeklidir. Ne kadar çok olacaklar hakkında zihninizde görseller oluşturabilirseniz, o oranda düşünceleriniz için gerçekleşebileceği mekan ve alanları yaratırsınız. Hayalinizi yaşamadan yaşayınız.

Tabi bu kuru kuru rüya kur anlamında söylenmiş bir şey değildir.

Birinci adım görselleştirmek ise, ikinci adım niyeti ortaya koymaktır. Bu hereket etmek istediğiniz anlıma gelir. Herakete geçmek için de azme ihtiyacımız var.

Bu üçü bir araya geldiğinde hayallerin gerçekleşmesinin önünde hiçbir engel olamaz.

Sosyal Sorumluluk Kültürü

Yönetim kültürü ve şirket kültüründen bahsettik. Bir şirketi ayakta tutabilecek, faaliyetlerini anlamlı kılacak, çalışanlarında aidiyet hissi oluşturacak ve onları tatmin edecek üçüncü bir ayaktan bahsetmek istiyorum.

Sosyal sorumluluk kültürü.

Bir şirket ekonomik kazanç oluşturmak için kurulur. Bu kazanç çok küçük bir oranda şirketin çalışanlarına yansırken, büyük bir kısmı şirket sahiplerinin ceplerinde kaybolur. Bu sebeple şirket sahipleri aslında sihirbazdırlar. Oluşan ekonomik kazancı kimsenin göremeyeceği bir şekilde kendi çıkarları için yok etmeyi bilirler. Burada geçerli olan tek bir kapitalist kural vardır: “Patron benim, her şey benim!”

Bu böyle olmak zorunda değil!

Ekonomik kazanç toplumsal kazanca dönüştürülebilir.

Şirketi kurarken kafamdaki düşünce tam olarak buydu.

Şirket bizim çalışma motorumuz. Üretiyor, büyüyor, müşteriler kazanıyor ve para kazanıyor. Ama bütün bunların nihai amacı sadece daha büyük bir şirket olmak ya da sahiplerini daha zengin yapmak değil.

Şirketin ürettiği ekonomik güç, sosyal sorumluluk bilincinde kurduğumuz vakfın toplumsal gücüne dönüşecek. Bknz: https://asyabilge.org

Bir tarafta ticari dünyada rekabet eden, teknoloji üreten ve ekonomik değer oluşturan şirket var. Diğer tarafta bu ekonomik değeri eğitim, bilim ve toplumsal projelere dönüştüren şirketin ait olduğu bir vakıf.

Biri motor, diğeri amaç.

Bu yüzden sirketimizde çalışan bir insan sadece bir yazılım geliştirmiyor, sadece satış yapmıyor, sadece müşteriye destek vermiyor.

Yaptığı işin sonunda oluşan değerin nereye aktığını biliyor.

Bugün yazdığı bir satır kod, kazandırdığı bir müşteri ya da çözdüğü bir problem; yarın bir çocuğun eğitimine, bir araştırma projesine dönüşebilir.

Bence aidiyet tam da burada başlıyor.

İnsan sadece maaşı için çalıştığı bir yere bağlılık hissetmekte zorlanabilir. Ama kendi emeğinin kendisinden daha büyük bir amaca hizmet ettiğini gördüğünde yaptığı iş başka bir anlam kazanır.

Bu sebeple sosyal sorumluluk şirket için şirketin kazandığı paradan sonradan ayrılan küçük bir bütçe kalemi olmayacak.

Şirketin varlık sebeplerinden sadece birisi de olmayacak. Mevcudiyetinin tek sebebi bu olacak!

Şirket ekonomik değer üretecek.

Vakıf bu değeri toplumsal değere dönüştürecek.

Ve böylece ortaya sadece büyüyen bir şirket değil, büyüdükçe topluma daha fazla şey geri verebilen bir organizma çıkacak.

Belki de kapitalizmin “patron benim, her şey benim” anlayışına verilebilecek en güzel cevap budur:

Şirket benim olabilir. Ama ürettiğimiz değer hepimizin.

Şirket Kültürü Hakkında

Yönetim kültüründen bahsettikten sonra, şirketin çalışanları için oluşturacağı ortamın temeli olan şirket kültüründen bahsedelim.

İnsanlar arasındaki ilişkiler kültürleri seviyesinde şekillenir. Kültür, öğrenilmiş birlikte yaşama kurallarını da ihtiva eder.

Bir toplumda insanların birbirleriyle nasıl konuşacağı, birbirlerine nasıl davranacağı, neyin kabul edilebilir, neyin kabul edilemez olduğu büyük ölçüde o toplumun kültürü tarafından belirlenir.

Şirketler de aslında küçük toplumlardır.

Onların da zaman içerisinde oluşan bir dili, davranış biçimleri, değerleri, ritüelleri ve yazılı olmayan kuralları vardır.

Bir çalışan hata yaptığında ne olur?

Hatasını saklamaya mı çalışır, yoksa rahatlıkla ortaya koyup diğerleriyle birlikte çözüm mü arar?

Bir çalışan yöneticisinden farklı düşündüğünde bunu söyleyebilir mi?

Bir problem gördüğünde “bu benim işim değil” deyip geçer mi, yoksa kendisini o problemin çözümünün bir parçası olarak mı görür?

Başka bir çalışanın yaptığı işi eleştirmek saldırı olarak mı algılanır, yoksa yapılan işi daha iyi hale getirmenin doğal bir parçası olarak mı?

Bütün bunların cevabını organizasyon şeması vermez.

Şirket kültürü verir.

Bu yüzden çalışanlara sadece nasıl çalışacağımızı değil, birlikte nasıl yaşayacağımızı da tarif etmemiz gerekiyor.

Özellikle kendi kendini yöneten küçük hücrelerden oluşan bir organizasyon kurmak istiyorsak, şirket kültürü klasik şirketlerden çok daha önemli hale geliyor.

Çünkü ortada sürekli emir veren bir yönetici olmayacak.

İnsanların davranışlarını yukarıdan gelen otorite değil, ortaklaşa kabul edilmiş değerler ve birlikte yaşama kuralları şekillendirecek.

Başka bir ifadeyle:

Yöneticinin olmadığı yerde boşluğu kültür doldurur.

Bu nedenle kuracağımız şirket kültürü, holakratik yönetim modelimizin yanında duran güzel sözlerden oluşan bir manifesto değil, bu sistemin çalışmasını sağlayan temel altyapıdır.

Oluşturulan bu kültürün ne pahasına olursa olsun korunması gerekir.

Çünkü kültür sadece içeriden inşa edilmez. Dışarıdan gelen her yeni insan da beraberinde kendi alışkanlıklarını, değerlerini ve davranış biçimlerini getirir.

Bu yüzden şirket kültürüne dışarıdan bir virüs gibi sızabilecek ve zaman içerisinde onu enfekte edebilecek insanların daha en başından tespit edilmesi gerekir.

Burada mesele farklı düşünen insanları elemek değildir. Tam tersine, farklı düşünceler kültürü besler ve geliştirir.

Mesele, birlikte yaşamayı mümkün kılan temel değerlerle çatışan davranış biçimleridir.

Sorumluluk almayan, sürekli başkalarını suçlayan, bilgiyi güç olarak görüp saklayan, insanları manipüle eden, güven ilişkilerini bozan ya da kendi çıkarını içinde bulunduğu topluluğun çıkarlarının sürekli önüne koyan bir insan teknik olarak ne kadar iyi olursa olsun bu kültürün bir parçası olamaz.

Bu sebeple mülakatların da bu konu göz önünde bulundurularak şekillendirilmesi gerekir.

Bir adayın teknik yeterliliği aslında tek başına yeterli bir kriter değildir.

Adayın şirket kültürüne uygunluğu ayrıca test edilmeli, bu kültüre ne oranda adapte olabileceği, hatta zaman içerisinde onu ne oranda ileriye taşıyabileceği anlaşılmalıdır.

Çünkü işe aldığınız insan sadece bir pozisyonu doldurmaz. Şirket kültürünün yeni bir taşıyıcısı olur.

Burada şirketlerin çok sevdiği başka bir söyleme de değinmek gerekiyor:

“Biz bir aileyiz.”

Bir patronun bu konuda ne kadar ciddi olduğunu söylemlerinden değil, o aileyi ne kadar ciddiye aldığını gösteren davranışlarından anlamak gerekir.

İnsanlar kendi aileleri içerisinde mutlu, huzurlu, sorumluluk, sadakat ve harmoni içerisinde yaşama çabasında olurlar. Çünkü kendilerini o yapının sadece çalışanı ya da işlev gören bir parçası olarak değil, bir bireyi olarak görürler.

Aidiyet tam olarak burada oluşur.

İnsan bir yere ait olduğunu hissettiğinde, o yapının kendisine ait olduğunu da hissetmeye başlar.

Böyle bir ortam insanların birey olmalarını engellemez. Tam tersine, birey olarak kabul edildiklerini hissetmelerini sağlarken aynı zamanda daha büyük bir bütünün parçası oldukları duygusunu oluşturur.

Ve insan kendisini parçası olarak gördüğü şeyi korur.

Üstüne düşen sorumlulukları sadece kendisine söylendiği için değil, o yapının devamını ve başarısını önemsediği için yerine getirir.

Belki de şirket kültürünün ulaşabileceği en güçlü nokta budur:

İnsanların şirket için çalıştıklarını değil, ait oldukları bir yapıyı birlikte inşa ettiklerini hissetmeleri.

Holakrasi İle Yeni Bir Yönetim Kültürü Oluşturmak

Yeni bir yönetim kültürü modeli olan holakrasiye, en azından bizim yeni oluşturduğumuz startup bünyesinde bunu nasıl implemente etmek istediğimize değinmek istiyorum.

Abdullah Kiğılı’nın bir sözü var:

“Çalışanlar müdüre başka, patrona başka davranırlar. Türkiye’de patron işin başında olmadığı sürece o iş yürümez.”

Haklı!

Ama bunun sebebi, yanlış yönetim kültürünün bizzat patron tarafından bu şekilde inşa edilmiş olmasıdır.

Klasik yönetim kültüründe yönetici sınıfı ve çalışan sınıfı diye iki sınıf vardır. Her şey yukarıdan aşağıya doğru dikte edilir. Aşağıda ne olup bittiğine dair çoğu zaman hiçbir fikri olmayan yönetici tayfası da bunu kompanze etmek için yukarıdan daha fazla baskı uygular ki herkes adam gibi çalışsın.

Bu yönetim tarzı tamamen çöptür.

Yerine çalışanı bir birey olarak kabul eden, ona sorumluluk ve bu sorumlulukla beraber karar yetkisi veren bir yönetim modeline ihtiyacımız var. Holakrasi bunlardan birisi.

Holakraside şirket, canlı bir organizmaya benzer şekilde oluşturulur ve yönetilir.

CEO, CTO, CFO gibi klasik yönetici pozisyonları yoktur. Bölüm başkanları, bölüm müdürleri, takım yöneticileri vs. yoktur.

Bunun yerine ne vardır?

Hücreler.

Canlı bir organizmanın nasıl çalıştığına bir bakalım.

Canlı, en temelde hücrelerden oluşur. Hücre üzerine düşen görevi kendi işlev türüne göre kendisi yönetir. Her yaptığı iş için gidip beyinden izin almaz.

Ama organizmadan bağımsız da değildir.

Hücreler dokuları, dokular organları, organlar da organizmayı oluşturur.

Benzer bir yapıyı şirket içinde de oluşturmak mümkün.

En tabanda örneğin 7-8 çalışandan oluşan ve tanımlı bir faaliyet alanına sahip hücreler oluşturulur.

Bu hücrenin içinde klasik anlamda bir yönetici yoktur. Bunun yerine roller vardır.

Örneğin bir hücre bir ürün geliştiriyorsa burada backend engineer, frontend engineer, product owner gibi roller bulunabilir.

Her rolün kendi sorumluluk alanı ve bu sorumluluktan doğan karar yetkisi vardır.

Backend engineer rolündeki bir çalışan:

“Ben veri tabanına yeni bir tablo ekleyeceğim.”

diyorsa, bunu rolünden aldığı otoriteyle kendisi yapabilir.

Bunun için hücredeki diğer yedi kişiyi toplantıya çağırıp izin almasına gerek yoktur.

Ama aynı kişi:

“Ürüne şu yeni özelliği ekleyelim.”

diyemez.

Çünkü bu artık sadece backend engineer rolünün sorumluluk alanında değildir. Product owner ve konuyla ilgili diğer rollerle istişare etmesi gerekir.

Yani herkes her konuda karar vermez.

Herkes kendi sorumluluğunu taşıdığı konuda karar verir.

Eğer alınması gereken karar hücrenin kendi domain sınırlarını aşıyorsa, o zaman konu bir üst yapıya taşınır.

Burada üst circle’lar devreye girer.

Bu circle’lar alt hücrelerden gelen temsilcilerden oluşabilir. Onların görevi alt hücreleri yönetmek değildir. Hücrelerin tek başlarına çözemeyecekleri, birden fazla hücreyi ilgilendiren konularda koordinasyonu ve karar mekanizmasını sağlamaktır.

Eğer mesele onların da yetki alanını aşıyorsa bir üst circle’a taşınır.

Bu yapı en tepedeki kurucu circle’a kadar devam edebilir.

Nihai olarak şirketin tamamını ilgilendiren ve alt yapılarda çözülemeyen konular burada ele alınabilir.

Ama önemli olan şu:

Çoğu kararın hiçbir zaman buraya gelmemesi gerekir. Çünkü sistemin amacı bütün kararları yukarı taşımak değil, mümkün olduğu kadar kararın doğduğu yerde alınmasını sağlamaktır.

Hücre otonomdur.

Kendi sorumluluk alanı içerisinde kararlarını kendisi alır ve çalışmalarını sürdürür.

Burada çok önemli bir ayrım var:

Yönetici ortadan kalkar ama sorumluluk ortadan kalkmaz.

Tam tersine sorumluluk artar.

Çalışan artık:

“Bana böyle söylendi.”

“Ben müdürün dediğini yaptım.”

“Kararı ben vermedim.”

diyerek sorumluluğu yukarıya devredemez.

Çünkü kendi rolünün sınırları içerisinde hem kararın hem de ortaya çıkan sonucun sahibidir.

Böyle bir yapı birçok sorunu ortadan kaldırıyor:

– Patron olmadan şirket işlemeye devam eder.

– Karar mekanizmaları çalışanlara dağıtılır.

– Kararlar, konu hakkında en fazla bilgiye sahip olan insanların bulunduğu yerde alınır.

– Çalışan sadece görev değil, sorumluluk da üstlenir.

– Gereksiz yönetici hiyerarşileri ortadan kalkar.

– Her küçük kararın yukarı taşınması gerekmediği için şirket hızlanır.

– Patron şirketin darboğazı olmaktan çıkar.

– Patron-çalışan ilişkisi yerine “hepimiz aynı gemideyiz ve birlikte kürek çekiyoruz” mentalitesi gelişir.

Bence burada en önemli nokta şu:

Holakrasi yöneticisiz bir şirket kurmak değildir.

Yönetim fonksiyonunu birkaç yöneticinin elinden alıp organizasyonun tamamına dağıtmaktır.

Bir hücrenin çalışabilmesi için CEO’nun gelip ona ne yapacağını söylemesine gerek yoktur.

Tıpkı vücudumuzdaki bir hücrenin her hareketi için beynimizden izin istememesi gibi.

Ama hücre organizmadan bağımsız da değildir. Bir amacı vardır. Bir görevi vardır. Bir sorumluluk alanı vardır. Ve sınırları vardır.

Biz kurdugumuz startup bünyesinde tam olarak böyle bir organizasyon kültürü oluşturmak istiyoruz.

İnsanların yukarıdan emir beklediği değil, kendi sorumluluk alanlarında karar aldığı; yöneticilerin insanları kontrol ettiği değil, rollerin ve sorumlulukların sistemi yönettiği bir şirket.

Çünkü patron olmadan çalışmayan bir şirket, güçlü bir şirket değildir. Patronuna bağımlı bir şirkettir.

Asıl başarı, kurucusu ortadan kaybolduğunda bile ne yapması gerektiğini bilen ve çalışmaya devam eden bir organizma oluşturabilmektir.

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.