AI tarafından üretilen kod tabanlarında güvenlik, performans ve güvenilirliği değerlendirmek için pratik bir rehber; inceleme, test ve izleme için net kontrol listeleri.

“AI tarafından üretilen kod” takımınıza ve kullandığınız araçlara bağlı olarak çok farklı anlamlara gelebilir. Bazıları için var olan bir modülde birkaç satırl otomatik tamamlama demektir. Diğerleri için uç noktalar, veri modelleri, migration’lar, test iskeletleri veya bir prompt’tan üretilmiş büyük bir refaktör olabilir. Kaliteyi değerlendirmeden önce, repoda AI tarafından üretilen şeyin ne sayılacağını yazın: snippet’ler, tam fonksiyonlar, yeni servisler, altyapı kodu veya “AI destekli” yeniden yazımlar.
Ana beklenti: AI çıktısı bir taslaktır, garanti değil. Oldukça okunabilir olabilir ama hâlâ kenar durumları kaçırabilir, bir kütüphaneyi yanlış kullanabilir, kimlik doğrulama kontrollerini atlayabilir veya ince performans darboğazları getirebilir. Hızlı bir genç ekip arkadaşından gelen kod gibi ele alın: hız kazandırır ama inceleme, testler ve net kabul kriterleri gerekir.
Eğer bir “vibe-coding” iş akışı kullanıyorsanız (ör. Koder.ai gibi bir platformda bir sohbet promptundan tam özellik üretmek—frontend React, backend Go ve PostgreSQL ile veya bir Flutter mobil uygulaması), bu zihniyet daha da önem kazanır. Üretilen yüzey alanı ne kadar büyükse, “tamamlandı”nın derlenmesinin ötesinde ne anlama geldiğini tanımlamak o kadar önemli olur.
Güvenlik, performans ve güvenilirlik, onları istemezseniz ve doğrulamazsanız üretilen kodda kendiliğinden ortaya çıkmaz. AI, inandırıcılık ve yaygın desenleri optimize etme eğilimindedir; sizin tehdit modelinizi, trafik şeklinizi, hata modlarınızı veya uyumluluk yükümlülüklerinizi değil. Açık kriterler yoksa, ekipler sık sık demo ortamında çalışan ama gerçek yük veya saldırgan girişim altında başarısız olan kodu merge eder.
Uygulamada bu alanlar örtüşür. Örneğin, hız sınırlama hem güvenliği hem de güvenilirliği iyileştirir; önbellekleme performansı artırabilir ama kullanıcılar arasında veri sızdırırsa güvenliğe zarar verebilir; katı zaman aşımı ayarları güvenilirliği artırır ama yeni hata yollarını ortaya çıkarıp bunların da güvenli hale getirilmesi gerekir.
Bu bölüm temel zihniyeti belirler: AI kod yazmayı hızlandırır, ama “üretime hazır” kalite barını siz tanımlarsınız ve sürekli doğrulamanız gerekir.
AI tarafından üretilen kod genellikle düzenli ve kendinden emin görünür, ama en sık görülen problemler stil meselesi değildir—yargı boşluklarıdır. Modeller derleyen ve temel testleri geçen makul uygulamalar üretebilirken sisteminizin bağlamını sessizce kaçırabilir.
İncelemelerde tekrarlayan kategoriler:
catch blokları kullanma.Üretilen kod gizli varsayımlar taşıyabilir: saat dilimlerinin hep UTC olduğu, ID’lerin her zaman sayısal olduğu, isteklerin hep düzgün biçimlendirilmiş olduğu, ağ çağrılarının hep hızlı olduğu veya tekrar denemelerin hep güvenli olduğu gibi. Ayrıca kısmi uygulamalar içerebilir—güvenlik kontrolü yerleştirilmemiş, TODO yolu veya kapalı kalmak yerine varsayılan veri döndüren bir fallback.
Yaygın başarısızlık modu, başka bir yerde doğru olan bir deseni burada bağlamı olmadığı halde ödünç almaktır: doğru parametrelerle kullanılmayan bir hashing yardımcı fonksiyonunu yeniden kullanmak, çıktınıza uymayan genel bir sanitize ediciyi uygulamak veya isteği istemeden artıran bir retry döngüsü benimsemek.
Kod üretilse bile, sorumluluk insanlardadır; üretim davranışından insanlar sorumludur. AI çıktısını bir taslak olarak ele alın: tehdit modelini, kenar durumları ve sonuçları siz üstlenirsiniz.
AI tarafından üretilen kod kendinden emin ve eksiksiz görünme eğilimindedir—bu da kolayca şu temel soruyu atlamanızı sağlar: “Ne koruyoruz ve kimden koruyoruz?” Basit bir tehdit modeli, güvenlik kararlarını kod sabitlenmeden önce açık tutan kısa, sade bir alışkanlıktır.
İlk olarak, ele geçirilmesi zarar verici olan varlıkları adlandırın:
Sonra aktörleri listeleyin: normal kullanıcılar, yöneticiler, destek personeli, harici servisler ve saldırganlar (credential stuffing, dolandırıcılar, botlar).
Son olarak güven sınırlarını çizin veya tanımlayın: browser ↔ backend, backend ↔ veritabanı, backend ↔ üçüncü taraf API’ler, dahili servisler ↔ halka açık internet. Eğer AI, bu sınırlar arasında “hızlı” kısayollar öneriyorsa (ör. halka açık bir uç noktadan doğrudan veritabanı erişimi), bunu hemen işaretleyin.
Kısa tutun ki gerçekten kullanılsın:
Yanıtları PR açıklamasına yazın veya karar uzun ömürlü ise kısa bir ADR (Architecture Decision Record) oluşturun (örn. token formatı, webhook doğrulama yaklaşımı). Gelecekteki inceleyenler böylece AI tarafından yapılan değişikliklerin orijinal niyetle hâlâ örtüşüp örtüşmediğini ve hangi risklerin bilerek kabul edildiğini görebilir.
AI tarafından üretilen kod temiz ve tutarlı görünebilir ama yine de varsayılanlar, hata yönetimi ve erişim kontrolleri etrafında güvenlik tuzakları saklayabilir. İnceleme sırasında stilden çok “bir saldırgan bununla ne yapabilir?” sorusuna odaklanın.
Güven sınırları. Verinin sisteme nereden girdiğini (HTTP istekleri, webhooklar, kuyruklar, dosyalar) belirleyin. Doğrulamanın sınırda yapıldığından emin olun, “sonradan bir yerde” değil. Çıktı için, bağlama uygun kodlamanın (HTML, SQL, shell, loglar) yapıldığını kontrol edin.
Kimlik doğrulama vs yetkilendirme. AI kodu sıklıkla isLoggedIn kontrolleri içerir ama kaynak seviyesi yetkiyi kaçırır. Her hassas eylemin hangi kişinin hangi nesne üzerinde işlem yapabileceğini kontrol ettiğini doğrulayın (ör. URL’deki userId sadece var mı diye kontrol edilmemeli; izin kontrolü yapılmalı).
Gizli bilgiler ve konfigürasyon. API anahtarları, tokenlar ve bağlantı dizileri kaynakta, örnek konfigürasyonda, loglarda veya testlerde olmamalı. Ayrıca “debug modu”nun varsayılan olarak etkin olmadığını kontrol edin.
Hata yönetimi ve loglama. Hataların ham istisnalar, yığın izleri, SQL hataları veya dahili ID’ler döndürmediğinden emin olun. Loglar faydalı olmalı ama kimlik bilgileri, erişim tokenları veya kişisel veriler sızdırmamalı.
Riskli yol başına bir negatif test isteyin (yetkisiz erişim, geçersiz girdi, süresi dolmuş token). Kod böyle test edilemiyorsa, genellikle güvenlik sınırının net olmadığı işaretidir.
AI tarafından üretilen kod genellikle paketler ekleyerek “çözüm” getirir. Bu, saldırı yüzeyini ve bakım yükünü sessizce genişletebilir: daha fazla bakımcı, daha fazla güncelleme trafiği ve istemeden çekilen dolaylı bağımlılıklar.
Bağımlılık seçimini kasıtlı yaparak başlayın.
Basit bir kural iyi işler: her yeni bağımlılık için PR açıklamasına kısa bir gerekçe yazılmadan ekleme yok. AI bir kütüphane önerdiyse, standart kütüphane veya zaten onaylı bir paketle halledilip halledilemeyeceğini sorun.
Otomatik taramalar sadece bulgular aksiyon üretiyorsa kullanışlıdır. Ekleyin:
Sonra iş kurallarını belirleyin: hangi şiddet seviyesinin merge’i engellediği, hangilerinin bir issue ile zaman kutusuna alınabileceği ve kimlerin istisnayı onaylayacağı. Bu kuralları katkı rehberinizde belgeleyin.
Çoğu olay dolaylı bağımlılıklardan gelir. PR’lerde lockfile farklarını inceleyin ve kullanılmayan paketleri düzenli olarak temizleyin—AI kodu “ihtimal” için yardımcı import’lar ekleyebilir ve asla kullanmayabilir.
Güncellemelerin nasıl yapılacağını yazın (zamanlanmış bump PR’leri, otomatik araçlar veya manuel) ve kim onaylıyorsa bunu belirtin. Net sahiplik, zayıf ve savunmasız paketlerin üretimde kalmasını önler.
Performans “uygulama hızlı hissetmesi” değildir. İnsanların ürünü gerçekte nasıl kullandığına ve çalıştırma maliyetine bağlı ölçülebilir hedefler setidir. AI tarafından üretilen kod çoğunlukla testleri geçer ve temiz görünür ama yine de CPU yakar, veritabanına çok sık gider veya gereksiz bellek ayırır.
Herhangi bir şeyi optimize etmeden önce “iyi”yi sayısal olarak tanımlayın. Tipik hedefler:
Bu hedefler gerçekçi iş yüküne (mutlu yol + yaygın sıçramalar) bağlı olmalı, sentetik tek bir benchmark’a değil.
AI tarafından üretilen kod tabanlarında verimsizlik genellikle öngörülebilir yerlerde ortaya çıkar:
Üretilen kod genellikle “yapı itibariyle doğru” ama “varsayılan olarak verimli” değil. Modeller okunabilir, genel yaklaşımları seçme eğilimindedir (fazla soyutlama, tekrar dönüşümler, sınırsız sayfalama)—kısıtları belirtmezseniz.
Tahmin yürütmekten kaçının. Üretime benzeyen bir ortamda profil ve ölçümle başlayın:
Hedeflerinize karşı bir öncesi/sonrası iyileşmesi gösteremiyorsanız, yaptığınız değişiklik optimizasyon değil, gereksiz uğraştır.
AI tarafından üretilen kod genellikle “çalışıyor” ama gizlice zaman ve para yakar: ekstra veritabanı turları, istemeden N+1 sorguları, büyük veri kümeleri üzerinde sınırsız döngüler veya bitmeyen tekrar denemeler. Korumalar performansı kahramanca bir sonradan uğraş değil, varsayılan haline getirir.
Önbellekleme yavaş yolları gizleyebilir ama veriyi sonsuza dek bayat da bırakabilir. TTL, event tabanlı invalidasyon veya versiyonlanmış anahtar gibi net bir invalidasyon stratejisi olması gerekir. Bir önbelleğe alınan değerin nasıl yenileneceğini açıklayamıyorsanız, önbellekleme yapmayın.
Zaman aşımı, tekrar denemeler ve backoff ayarlarının kasıtlı yapıldığından emin olun (sonsuz beklemeler olmasın). Her dış çağrı—HTTP, veritabanı, kuyruk veya üçüncü taraf API—için:
Bu, yük altındayken kaynakları meşgul eden “yavaş başarısızlıkların” önüne geçer.
Async yollar içinde bloklayıcı çağrılardan kaçının; thread kullanımını kontrol edin. Yaygın suçlular: senkron dosya okuma, event loop üzerinde CPU ağırlıklı işler veya async handler içinde bloklayıcı kütüphaneler kullanmak. Ağır hesaplama gerekiyorsa offload edin (işçi havuzu, arka plan işi veya ayrı bir servis).
Toplu işlemler ve sayfalama sağlayın. Bir koleksiyon döndüren herhangi bir uç nokta limit ve cursor desteklemeli; arka plan işler parçalar halinde işlemeli. Bir sorgu kullanıcı verisiyle büyüyebiliyorsa, bununla yaşanacağını varsayın.
CI’ya performans testleri ekleyin. Küçük ama anlamlı olsunlar: birkaç sıcak uç nokta, temsilî bir veri seti ve eşikler (gecikme yüzdelikleri, bellek ve sorgu sayıları). Başarısızlıkları test başarısızlığı gibi ele alın—"yeniden çalıştırıp geçene kadar bekleme" değil, inceleyip düzeltme yapın.
Güvenilirlik sadece “çökme yok” demek değildir. AI tarafından üretilen kod için, sistemin dağınık girdiler, kesintili servisler ve gerçek kullanıcı davranışı altında doğru sonuç üretmesi; üretemediğinde ise kontrollü şekilde başarısız olması anlamına gelir.
Uygulama ayrıntılarına bakmadan önce, her kritik yol için “doğru”nun nasıl görüneceği konusunda anlaşın:
Bu sonuçlar, inceleyenlere AI tarafından yazılan mantığı değerlendirirken standart sağlar—mantıklı görünse bile kenar durumları gizlenmiş olabilir.
AI tarafından üretilen handlerlar sıklıkla “sadece işi yapıp” 200 döner. Ödemeler, iş işleme ve webhook alımı için bu risklidir çünkü tekrarlar normaldir.
Kodu idempotent kılacak şeyleri kontrol edin:
Akış veritabanına, kuyruğa ve önbelleğe dokunuyorsa, tutarlılık kurallarının kodda açıkça yazılı olduğundan emin olun—varsayılmasın.
Arananlar:
Dağıtık sistemler parça parça çöker. Kodun “DB yazıldı, olay yayınlanamadı” veya “HTTP çağrısı timeout oldu ama uzak taraf başarılı oldu” gibi senaryoları ele aldığını doğrulayın.
Sonsuz tekrarlar veya sessiz yutmalar yerine zaman aşımı, sınırlı tekrarlar ve dengeleme eylemlerini tercih edin. Bu durumları testlerde doğrulayın (daha sonra /blog/testing-strategy-that-catches-ai-mistakes adresinde ele alındığı gibi).
AI tarafından üretilen kod genellikle “tamamlanmış” görünür ama boşluklar gizleyebilir: eksik kenar durumları, girdiler hakkında iyimser varsayımlar ve asla çalıştırılmamış hata yolları. İyi bir test stratejisi her şeyi test etmekten çok, sürpriz yaratabilecek şeyleri test etmektir.
Önce mantık için unit testleri, sonra gerçek sistemlerin mock’lardan farklı davranabildiği yerler için integration testleri ekleyin.
En çok hata glue kodunda çıkar: yanlış SQL varsayımları, hatalı retry davranışı veya hatalı API modellemesi.
AI kodu genellikle hata yönetimini az belirtir. Sistemin güvenli ve öngörülebilir tepki verdiğini kanıtlayan negatif testler ekleyin.
Bu testler önemli çıktılara (doğru HTTP durum kodu, hata mesajlarında veri sızıntısı olmaması, idempotent tekrarlar, kibar fallback’ler) assert koymalı.
Bir bileşen girdileri ayrıştırıyorsa, sorgu kuruyorsa veya kullanıcı verisini dönüştürüyorsa, geleneksel örnekler garip kombinasyonları kaçırır.
Property-based testler sınır hatalarını (uzunluk limitleri, kodlama sorunları, beklenmeyen null’lar) yakalamada özellikle etkilidir.
Kapsam sayıları asgari bir bar olarak yararlıdır, hedef değil.
Önceliklendirme: kimlik doğrulama/yetkilendirme kararları, veri doğrulama, para/credit işlemleri, silme akışları ve retry/zaman aşımı mantığı. Emin değilseniz hangi yolun “yüksek risk” olduğunu görmek için isteği halka açık uç noktadan veritabanı yazısına kadar izleyin ve yol üzerindeki dalları test edin.
AI tarafından üretilen kod “bitti” görünürken işletilmesi zor olabilir. Ekiplerin üretimde en çok yandığı durum genellikle eksik görünürlüktür. Gözlemlenebilirlik sürpriz bir olayı rutin bir düzeltmeye çevirir.
Yapılandırılmış loglamayı zorunlu kılın. Düz metin loglar yerelde yeterli olabilir ama çoklu servis ve dağıtım olduğunda ölçeklenmez.
Zorunluluklar:
Hedef: tek bir istek ID’si ile “ne oldu, nerede ve neden” sorularına tahmin etmeye gerek kalmadan cevap alınabilmesi.
Loglar neden olduğunu anlatır; metrikler ne zaman bozulma başladığını söyler.
Ekleyin:
AI kodu genellikle gizli verimsizlikler getirir (fazladan sorgular, sınırsız döngüler, chatty ağ çağrıları). Doygunluk ve kuyruk derinliği bunları erken yakalar.
Bir uyarı grafik yerine bir karara işaret etmelidir. Gürültülü eşiklerden kaçının (“CPU > %70”)—bunlar kullanıcı etkisine bağlı olmadıkça anlamsız olabilir.
İyi uyarı tasarımı:
Uyarıları kasıtlı test edin (staging’de veya planlı tatbikat sırasında). Uyarının gerçekten tetiklenip eyleme dönüştüğünü doğrulayamıyorsanız, o uyarı umut olmaktan öte değildir.
Kritik yollar için hafif runbook’lar yazın:
Runbook’ları kod ve süreçlere yakın tutun (ör. repoda veya dahili dokümanda), böylece sistem değiştiğinde güncellenirler.
AI tarafından üretilen kod akışı hızı artırabilir ama varyansı da artırır: küçük değişiklikler güvenlik sorunları, yavaş yollar veya gizli doğruluk hataları getirebilir. Disiplinli bir CI/CD hattı bu varyansı yönetilebilir kılar.
Bu aynı zamanda uçtan uca üretim iş akışlarının ekstra disipline ihtiyaç duyduğu yerdir: bir araç hızlıca üretebilir ve deploy edebilir (Koder.ai gibi yerleşik dağıtım/barındırma, özel domainler ve snapshot/geri alma ile), pipeline kapıları ve geri alma prosedürleriniz de benzer hız ve standarda sahip olmalı—böylece hız güvenliğe mal olmaz.
Pipeline’ı merge ve release için asgari bar olarak değerlendirin—“acil düzeltme” için istisna yok. Tipik kapılar:
Önemli bir kontrolse blocklayıcı yapın. Gürültülü ise ince ayar yapın—görmezden gelmeyin.
“Aynı anda herkese” dağıtımları yerine kontrollü açılışları tercih edin:
Otomatik geri alma tetiklerini (hata oranı, gecikme, doyma) tanımlayın ki rollout kullanıcı hissinden önce durdurulsun.
Geri alma planı hızlı değilse gerçek değildir. Veritabanı migration’larını mümkün olduğunca tersine çevrilebilir tutun; tek yön şema değişikliklerinden kaçının veya test edilmiş bir ileri-düzeltme planınız olsun. Periyodik “geri alma tatbikatları” yapın.
Niyet, risk ve test notlarını yakalayan PR şablonları zorunlu kılın. Sürümler için hafif bir değişiklik günlüğü tutun ve net onay kuralları uygulayın (ör. rutin değişiklikler için en az bir onay, güvenlik hassasiyeti olan alanlar için iki onay). Daha derin bir inceleme iş akışı için /blog/code-review-checklist adresine bakın.
AI tarafından üretilen kod için “üretime hazır” demek “makinemde çalışıyor” demek olmamalı. Bunun anlamı: kod bir ekip tarafından güvenle işletilebilir, değiştirilebilir ve güvenilebilir—gerçek trafik, gerçek hatalar ve gerçek teslim tarihlerinde.
Herhangi bir AI-üretimli özellik gönderilmeden önce bu dört madde doğru olmalı:
AI kod yazabilir ama sahiplenemez. Her üretilmiş bileşen için net bir sahibi atayın:
Sahiplik net değilse, üretime hazır değildir.
Kullanılacak kadar kısa tutun:
Bu tanım “üretime hazır”ı somut tutar—daha az tartışma, daha az sürpriz.
AI tarafından üretilen kod, bir prompttan modele dayalı olarak yapısal veya mantıksal olarak önemli ölçüde üretilmiş herhangi bir değişikliktir—bu birkaç satırl otomatik tamamlama, bir fonksiyonun tamamı veya bir hizmet iskeleti olabilir.
Pratik bir kural: Aracı kullanmadan aynı şekilde yazmazdınızsa, bunu AI-üretimli sayın ve aynı inceleme/test barını uygulayın.
AI çıktısını taslak olarak değerlendirin; okunabilir olsa bile yanlış olabilir.
Bunu hızlı bir genç takım arkadaşı gibi kullanın:
Çünkü güvenlik, performans ve güvenilirlik genellikle üretilen koda “tesadüfen” gelmez.
Hedefleri (tehdit modeli, gecikme bütçeleri, hata davranışı) belirtmezseniz, model makul desenleri optimize eder—sizin trafik şeklinizi, uyumluluk ihtiyaçlarınızı veya hata modlarını değil.
Tekrarlayan boşluklara dikkat edin:
Ayrıca TODO dalları veya fail-open varsayımları gibi kısmi uygulamalara tarama yapın.
Küçük ve uygulanabilir bir tehdit modeliyle başlayın:
Sonra sorun: “Kötü niyetli bir kullanıcı bu özellik ile en kötü ne yapabilir?”
Yüksek sinyal veren birkaç kontrolde yoğunlaşın:
Riskli yol için en az bir negatif test isteyin (yetkisiz, geçersiz giriş, süresi dolmuş token gibi).
Model bir problemi paketlerken genellikle paket eklemeyi önerir; bu da saldırı yüzeyini ve bakım yükünü artırır.
Koruyucu önlemler:
PR’lerde lockfile farklarını inceleyin ki dolaylı (transitive) riskleri yakalayabilesiniz.
“İyi”yi sayıyla tanımlayın ve gerçek iş yüküne bağlayın:
Ayrıca profilleme yapmadan optimize etmeyin—ürün ortamına benzeyen bir yerde ölçün ve bir değişiklik yapıp yeniden ölçün.
Yaygın regresyonları önleyen önlemler kullanın:
Güvenilirlik; yeniden denemeler, zaman aşımı, kısmi kesintiler ve karmaşık girdiler altında da doğru davranmak demektir.
Önemli kontroller:
Sınırlı tekrar denemeleri ve net hata modlarını sonsuz denemeler yerine tercih edin.