kertenkerem_
· LLM Tools · 4 dk okuma

Yazılım Geliştirmede ‘Stage-Gated’ Disiplin: LLM Çıktılarını Kontrol Altına Alın

Artık hemen hepimiz bir LLM (Büyük Dil Modeli) ile yan yana kod yazıyoruz. İster Cursor kullanın ister Claude veya Copilot, yapay zekanın birkaç saniyede yüzlerce satır kod üretmesi büyüleyici bir his. Ancak dürüst olalım: Üretilen kodun arkasında bazen var olmayan kütüphane bağımlılıkları, sinsi mantık hataları ve ciddi güvenlik açıkları saklanıyor. Hızlı yazıyoruz ama arkamızı toplamaya çalışırken daha çok yoruluyoruz. Burada eski ama sağlam bir disiplin geri dönüyor: stage-gated yaklaşımı.

Bu yazıda geleneksel mühendislikten ödünç aldığımız bu “aşamalı kapı” sistemini yapay zeka destekli bir pipeline içine nasıl entegre edebileceğimizi, bizzat kurup test ettiğim bir senaryo üzerinden anlatıyorum. Amacımız yapay zekayı yavaşlatmak değil, yapay zeka güvenliği standartlarından taviz vermeden kodu üretime (production) taşımak.

Şelale (Waterfall) mezardan mı çıktı? “Stage-gated” nedir?

Eski usul Waterfall (Şelale) metodolojisini hatırlarsınız: Bir faz bitmeden diğeri başlamaz, arada kalın onay kapıları bulunur. Çevik (Agile) dünyada bundan nefret ettik, çünkü hızı kesiyordu. Fakat işin içine modeller ve tahmin edilemez çıktılar girince dengeler değişti.

Stage-gated mekanizması, üretilen bir çıktının bir sonraki aşamaya geçebilmesi için belirli kriterleri (“kapıları”) geçmek zorunda olduğu bir filtreleme modelidir. Bir LLM’e “Bana şu API servisini yaz” dediğinizde kodu doğrudan ana dala (main branch) göndermezsiniz. Kod, tanımladığınız kapılardan sırayla geçer. Herhangi bir kapıda takılırsa ya düzeltmesi için LLM’e geri fırlatılır ya da doğrudan reddedilir.

Test masası: 4 kapılı bir pipeline mimarisi

Teoriyi bırakıp pratiğe geçelim. Denemek için yerel ortamımda FastAPI ile basit bir servis geliştiren bir akış kurdum. Modeli (Claude 3.5 Sonnet) bir komut satırı aracıyla tetikledim ve kodu şu 4 kapıdan geçirdim:

Kapı 1: Sözdizimi (Syntax) ve tip kontrolü

LLM’ler bazen parantezleri unutur, bazen var olmayan metodları çağırır. İlk kapımız en ucuz ve en hızlı olanı: AST (Soyut Sözdizim Ağacı) kontrolü ve mypy tip denetimi. Modelin çıktısı bu aşamada Python tarafından derlenemiyorsa sonraki aşamaya geçemez.

Kapı 2: Statik güvenlik analizi (SAST)

Model istemeden de olsa SQL Injection açığı üretmiş olabilir. Ya da hardcoded bir API anahtarı bırakmış olabilir. Bu kapıda açık kaynaklı statik analiz araçları (örneğin Semgrep veya Bandit) devreye girer. Güvenlik açığı tespit edilirse pipeline kırılır.

# Semgrep ile yerel pipeline kontrolü çalıştırma
semgrep scan --config auto --error ./generated_code/

Kapı 3: Otomatik birim testleri ve “self-healing”

En sevdiğim bölüm burası. Kod ilk iki kapıyı geçtiyse, önceden tanımlanmış test senaryoları (Pytest) çalıştırılır. Test başarısız olursa hata raporu otomatik olarak tekrar LLM’e gönderilir: “Kodun şu testten geçmedi, hata mesajı bu. Kodu tekrar düzenle.” Sektörde buna self-healing (kendi kendini onarma) döngüsü deniyor. En fazla 3 deneme hakkı tanıyoruz.

Kapı 4: İnsan gözü (Human-in-the-Loop)

Bütün testlerden geçen kod bir Pull Request (PR) olarak açılır. Son kapı daima bir insandır. Bu aşamaya gelen kod sözdizimi, güvenlik ve temel iş kuralları açısından zaten elendiği için, inceleyen mühendisin harcadığı süre dakikalar yerine saniyelere iner.

Gerçek bir deney: SQL Injection girişimi kapıya takılınca

Pipeline’ı denemek için Claude’a bilerek hafif yönlendirici bir prompt verdim: “Kullanıcı ID’sine göre kullanıcı bilgilerini getiren ham SQL sorgulu bir fonksiyon yaz.”

Model, sorguyu f-string ile birleştiren tipik bir güvensiz kod bloğu üretti. Süreç şöyle işledi:

  • Kapı 1 (Syntax): Kod geçerli Python sözdizimine sahipti. Geçti.
  • Kapı 2 (Semgrep): Kırmızı alarm. python.lang.security.audit.sqli kuralı tetiklendi. Parametreli sorgu kullanılmadığı için kod hemen durduruldu.
  • Geri besleme: Pipeline, Semgrep hata çıktısını prompt’a ekleyip modeli uyardı.
  • Sonuç: İkinci denemede model kodu SQLAlchemy ORM parametreli sorgusuyla düzeltti ve Kapı 2’den başarıyla geçti.

Artılar ve eksiler: bu zahmete değer mi?

Her güvenlik katmanı biraz sürtünme getirir. Karar vermenizi kolaylaştırmak için gözlemlerimi özetledim:

Avantajlar Dezavantajlar
Halüsinasyon kaynaklı bağımlılık ve hatalar sisteme sızamaz. CI/CD süreçleri biraz daha uzun sürer (ortalama +40-90 saniye).
Yapay zeka güvenliği şirket politikaları seviyesinde garantiye alınır. LLM API maliyetleri (tekrar denemeler yüzünden) %15-20 artabilir.
Kıdemsiz geliştiricilerin fark edemediği açıklar erken yakalanır. İlk kurulum ve doğru kural setlerini yazmak teknik efor ister.

Hangi araçları kullanabilirsiniz? (Fiyat ve alternatifler)

Bu yapıyı kurmak için servet harcamanız gerekmiyor. Açık kaynak tarafında ücretsiz iyi seçenekler var:

  • Guardrails AI (Ücretsiz / Açık Kaynak): LLM çıktılarını belirli Pydantic şemalarına ve regex/güvenlik kurallarına zorlamak için biçilmiş kaftan. Kendi sunucunuzda tamamen ücretsiz çalıştırabilirsiniz.
  • Semgrep (Freemium): Statik kod analizinde sektör standardı hâline geldi. Açık kaynak sürümü CLI üzerinden yerelde veya GitHub Actions içinde tamamen ücretsizdir. Ekip yönetimi sunan Semgrep Cloud ise aylık kullanıcı başı yaklaşık $40 civarından başlar.
  • NeMo Guardrails (NVIDIA, ücretsiz): Özellikle diyalog ve mantık akışlarını kısıtlamak isteyenler için geliştirilmiş güçlü bir açık kaynak kütüphane.
  • SonarQube Community Edition (Ücretsiz): Kod kalitesini ve teknik borcu ölçmek için kendi sunucunuza kurabileceğiniz ücretsiz bir alternatif.

Son söz

Yapay zekanın kod yazma hızına hayran olmamak elde değil. Ancak kontrolsüz hız, teknik borç dağları ve güvenlik kabusları yaratır. Stage-gated yaklaşımı Agile pratikleri yavaşlatmak için değil, yapay zekayı sorumsuz bir stajyerden güvenilir bir takım arkadaşına dönüştürmek için ihtiyacımız olan emniyet kemeri. Henüz denemediyseniz, en azından bir GitHub Action içine basit bir linter + Semgrep kapısı koyarak ilk adımı atmanızı şiddetle tavsiye ederim.