Kategoriler
Vibe Coderin El Kitabı

Vibe Coder #3.3: Lokal LLM – Kendi Jeneratörünü Kurmak

Bölüm 3.2’de beş dakikada gelen prototipi konuşmuş, sözü şuraya bağlamıştım: bir sonraki bölümde buluta hiç uğramadan çalışmayı konuşacağız. Sözümü tutuyorum.

Lokal LLM meselesi sahada genelde iki cümleye sıkışıyor: “Kod benim makinemden çıkmaz” ve “jeton parası ödemem”. İkisi de doğru. Kimsenin söylemediği üçüncü cümle şu: kabloyu şebekeden çektiğiniz anda elektriği, jeneratörü ve bakımı da siz üstlenirsiniz.

Bulut modeli kullanmak şebekeden elektrik almaya benzer. Prize takarsınız, çalışır, ay sonunda sayaç kadar ödersiniz. Lokal model ise bahçeye jeneratör kurmaktır: makineyi peşin alırsınız, yakıtı siz doldurursunuz, ne kadar priz besleyebileceğine cihazın gücü karar verir. Kimseye hesap vermezsiniz. Ama elektrik kesilirse suçlayacak kurum da yoktur.

Gelin faturanın kalemlerine tek tek bakalım: hangi model makinenize sığar, bağlam penceresi neden sessizce kırpılır, lisans metninde gerçekten ne yazar, ve bütün bunlar PHP çalıştıran bir sunucuda ne anlama gelir.

Jeneratör Neyi Çözer, Neyi Çözmez?

Önce beklentiyi hizalayalım, çünkü lokal model tartışmasının yarısı yanlış beklentiden çıkıyor.

Çözdüğü: Müşteri kodu, veritabanı şeması ve müşteri verisi makineden çıkmaz. Bu, müşteriyle imzaladığınız gizlilik maddesinin teknik karşılığıdır; “sağlayıcı verimi eğitimde kullanmıyor” cümlesine güvenmek zorunda kalmazsınız. İnternet gitse de çalışır. Aylık kota yoktur, dolayısıyla “bu prompt’u bir daha denesem mi” diye düşünmezsiniz.

Çözmediği: Gecikme. Bulutta gecikmeyi sağlayıcının veri merkezi belirler, evde sizin kartınız belirler. Sınıfının en iyi modeli de gelmez; ağırlıkları indirilebilen modellerle kapalı modeller arasındaki mesafe kapanıyor ama sıfırlanmış değil. Ve en sinsisi: bağlam penceresi artık bedava değildir. Buluta 200 bin tokenlik bir bağlam göndermek para, evde aynı şeyi yapmak yer ister.

Jeneratör ışığı yakar. Klimayı da çalıştırır mı, gücüne bakmak lazım.

Birinci Kalem: Jeneratörün Gücü

Model seçimi romantik bir tercih değil, bir sığdırma problemidir. Aşağıdaki tablodaki indirme boyutları Ollama kütüphanesinden, parametre ve bağlam değerleri modellerin resmi kartlarından alındı (27 Eylül 2026 itibarıyla).

ModelToplam / aktif parametreYerel bağlamLisansOllama indirme
qwen3-coder:30b30,5B / 3,3B262.144 tokenApache-2.019 GB
qwen3-coder:480b480B / 35B262.144 tokenApache-2.0290 GB
llama4:16x17b (Scout)109B / 17B10M (ilan edilen)Llama Community License67 GB
llama4:128x17b (Maverick)400B / 17Bilan edilmediLlama Community License245 GB

Tablodaki asıl mesaj sütunlarda değil, aradaki uçurumda. Qwen3-Coder’ın 30B sürümü uzmanlar karışımı (MoE) bir model: toplamda 30,5 milyar parametresi var ama her token için yalnızca 3,3 milyarı çalışıyor. Yani hafızaya tamamını yüklersiniz, hesabı bir bölümü yapar. 19 GB’lık indirme tek başına makul görünür; sorun şu ki o 19 GB’ın üstüne bir de bağlam için ayrılan alan biner.

Acı Gerçek: İndirme boyutu, çalışma boyutu değildir. “Diskte 19 GB, kartımda 24 GB var, olur” hesabı, pencereyi açtığınız anda bozulur.

İkinci Kalem: Kaç Prizi Besliyor?

Bu bölümün en pahalı cümlesi burada. Ollama, bağlam penceresini elinizdeki VRAM’e göre kendisi seçiyor. Kendi dokümanındaki değerler şöyle:

  • 24 GB’ın altında VRAM: 4.000 token
  • 24–48 GB arası: 32.000 token
  • 48 GB ve üzeri: 256.000 token

Şimdi şunu yan yana koyun: yukarıdaki tabloda Qwen3-Coder’ın yerel bağlamı 262.144 token yazıyor. Elinizde 16 GB’lık bir kart varsa o modeli 4.096 tokenlik bir pencereyle çalıştırırsınız. Model yine aynı model. Pencere sizinki.

İşin can sıkıcı tarafı, bunun sessizce olması. Hata almazsınız, uyarı görmezsiniz. Sadece ajan üçüncü dosyadan sonra ilk dosyada ne yazdığını unutur ve siz “lokal modeller işe yaramıyormuş” dersiniz. Bu tam olarak balık hafızası yazısında anlattığım tabloya benziyor, ama sebebi modelin kendisi değil; sizin ayarınız.

Ollama’nın kendi dokümanı bu konuda net: arama, ajan ve kodlama araçları gibi büyük bağlam isteyen işler en az 64.000 token‘a ayarlanmalı. Sunucuyu öyle başlatın:

OLLAMA_CONTEXT_LENGTH=64000 ollama serve

İstek bazında ayarlamak isterseniz alan options.num_ctx. Aynı gövdede keep_alive da var ve varsayılanı 5 dakika: bu sürenin sonunda model bellekten atılır, sonraki isteğinizde yeniden yüklenir. Sabah ilk sorunuzun neden bu kadar geç cevaplandığını merak ediyorsanız cevap büyük ihtimalle burada.

curl http://localhost:11434/api/chat -d '{
  "model": "qwen3-coder:30b",
  "messages": [{"role": "user", "content": "Bu SQL neden yavas?"}],
  "stream": false,
  "keep_alive": "30m",
  "options": { "num_ctx": 64000, "temperature": 0.2 }
}'

Sonuç: Lokal modelde asıl ayar düğmesi model adı değil, pencere genişliği ve modelin bellekte kalma süresidir.

Üçüncü Kalem: Lisans Metnini Kim Okuyor?

“Açık model” ile “açık kaynak model” aynı şey değil ve bu fark müşteriye teslim ettiğiniz projede karşınıza çıkar.

Qwen3-Coder, Hugging Face’teki model kartında Apache-2.0 ile yayınlanıyor. Tanıdık, tahmin edilebilir, kurumsal hukukun tartışmadığı bir lisans. Modeli Alibaba bünyesindeki Qwen ekibi geliştiriyor; 480B sürümü 22 Temmuz 2025’te duyuruldu.

Llama tarafında durum farklı. Meta’nın modelleri “açık ağırlık” olarak dağıtılıyor ama lisans Llama Community License; Apache ya da MIT değil. Open Source Initiative, 18 Şubat 2025 tarihli yazısında bu lisansın Açık Kaynak Tanımı’nı karşılamadığını söylüyor: modeli her amaçla kullanma özgürlüğünü kısıtlıyor, kullanıcılar arasında ayrım yapıyor ve çalışma alanına sınır koyuyor.

Kendi makinenizde deneme yaparken bunların hiçbiri sizi ilgilendirmez. Modeli müşterinin sunucusuna kurup fatura kestiğiniz gün ilgilendirir. Sözleşme imzalamadan önce iki dakikanızı ayırıp lisans dosyasını açın; bu, yükseltme öncesi sürüm destek tarihlerine bakmakla aynı kategoride bir iş.

Motor Başka, İstemci Başka

Bölüm 3.1’de editörün tek kapı olmadığını konuşmuştuk. Lokal tarafta bu ayrım daha da keskin: modeli çalıştıran katman ile onunla konuşan katman ayrı yazılımlardır ve ayrı ayrı seçilir.

Çalıştırma motoru

Bu işin temelinde llama.cpp var: MIT lisanslı, C/C++ ile yazılmış, 1,5 bitten 8 bite kadar nicemleme (quantization) destekleyen çıkarım motoru. Projeyi Georgi Gerganov (@ggerganov) başlattı; 20 Şubat 2026’da ggml ekibi Hugging Face’e katıldı ve duyuruda proje için “yüzde yüz açık kaynak ve topluluk odaklı kalmaya devam edecek”, teknik yönde ekibin “tam özerkliği” var dendi. Bir altyapının arkasında maaş ödeyen bir kurum olması, o altyapıyı üretimde kullananlar için iyi haberdir.

Ollama (MIT) bu motorun üstüne paket yöneticisi ve HTTP sunucusu koyuyor; son sürümü 23 Eylül 2026’da çıkan 0.34.4. LM Studio ise masaüstü tarafında en rahat arayüzü veriyor ama kapalı kaynak: kullanım şartları kişisel ve kurum içi kullanım için ücretsiz olduğunu, yazılımın dağıtılamayacağını söylüyor.

İstemci tarafı

Cline (Apache-2.0, Cline Bot Inc.) VS Code ve JetBrains tarafında çalışıyor, sağlayıcı olarak Ollama’yı ve LM Studio’yu doğrudan destekliyor; taban adres http://localhost:11434. Dokümanı lokal kullanımda “Use Compact Prompt” seçeneğini açmayı ve görevleri küçük tutmayı öneriyor. Yani yukarıdaki bağlam derdini onlar da biliyor.

Aider (Apache-2.0), Paul Gauthier‘nin terminal tabanlı eşli programlama aracı; neredeyse her modele, lokal olanlar dahil, bağlanabiliyor. PyPI’daki son sürümü 12 Şubat 2026 tarihli 0.86.2.

Üçüncü bir isim daha vardı: Continue. Aynı kategoride, Apache-2.0, Continue Dev Inc. arkasında. Deponun bugünkü hâli ise şu: “artık aktif olarak bakımı yapılmıyor ve tüm kullanıcılar için salt okunur”. Buradan çıkan ders aracın kendisiyle ilgili değil: akışınızı tek bir eklentinin üstüne kurmayın. Motoru standart tutun, istemciyi değiştirilebilir bırakın.

Bulut tarafındaki ajanlar — OpenAI Codex, Anthropic Claude Code, Google Antigravity — bu tablonun dışında değil, karşısında. Aynı işi yapan üç farklı ekosistem var ve seçim ideolojik değil, işin niteliğine göre yapılır.

KatmanÖrnekLisansNerede çalışır
Çıkarım motorullama.cppMITSizin donanımınız
Motor + paket yöneticisiOllama 0.34.4MITSizin donanımınız
Masaüstü arayüzLM StudioKapalı kaynak, kişisel/kurum içi ücretsizSizin donanımınız
Editör ajanıClineApache-2.0Lokal veya bulut modeliyle
Terminal ajanıAider 0.86.2Apache-2.0Lokal veya bulut modeliyle
Bulut ajanıCodex, Claude Code, AntigravityTescilli servisSağlayıcının altyapısı

PHP Tarafında Bu Ne İşe Yarar?

Lokal modelin PHP projesindeki en dürüst kullanımı “kodumu o yazsın” değil, dışarı çıkmaması gereken metni işlemek. Müşteri sipariş notları, destek talepleri, hata logları, sözleşme metinleri. Bunları buluta göndermek istemediğiniz durumlarda jeneratör tam olarak bunun için var.

Desen, Crawl4AI yazısındaki ile aynı: PHP tarafı HTTP ile lokal servise konuşur, ağır iş orada döner. Aşağıdaki sınıf çerçeve bağımsız, düz PHP 8.3. Bir DI kabınız varsa oraya koyarsınız, yoksa doğrudan new ile kullanırsınız; ikisinde de aynı çalışır. php -l ile sözdizimi kontrolünden geçirildi.

<?php

declare(strict_types=1);

final class OllamaClient
{
    public function __construct(
        private readonly string $baseUri = 'http://127.0.0.1:11434',
        private readonly string $model   = 'qwen3-coder:30b',
        private readonly int $numCtx     = 64000,
        private readonly int $timeout    = 180
    ) {
    }

    /**
     * @param array<int, array{role: string, content: string}> $messages
     */
    public function chat(array $messages): string
    {
        $payload = [
            'model'      => $this->model,
            'messages'   => $messages,
            'stream'     => false,
            'keep_alive' => '30m',
            'options'    => [
                'num_ctx'     => $this->numCtx,
                'temperature' => 0.2,
            ],
        ];

        $ch = curl_init($this->baseUri . '/api/chat');
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => $this->timeout,
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
            CURLOPT_POSTFIELDS     => json_encode($payload, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
        ]);

        $raw  = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        $err  = curl_error($ch);
        curl_close($ch);

        if ($raw === false) {
            throw new RuntimeException('Ollama erisilemedi: ' . $err);
        }

        if ($code !== 200) {
            throw new RuntimeException('Ollama HTTP ' . $code . ': ' . substr((string) $raw, 0, 300));
        }

        $data = json_decode((string) $raw, true, 512, JSON_THROW_ON_ERROR);

        if (!isset($data['message']['content'])) {
            throw new RuntimeException('Beklenmeyen yanit govdesi.');
        }

        return trim((string) $data['message']['content']);
    }
}

Üç ayrıntı önemli. num_ctx burada açıkça veriliyor, çünkü sunucunun varsayılanına güvenmek yukarıda anlattığım tuzağın ta kendisi. keep_alive yarım saate çekildi, çünkü arka planda çalışan bir kuyrukta modelin her seferinde yeniden yüklenmesi süreyi katlar. Zaman aşımı ise 180 saniye: bulut API’sinden alıştığınız üç saniyelik cevapları evde beklemeyin.

Ollama’nın OpenAI uyumlu ucu da var (http://localhost:11434/v1/chat/completions). Elinizde hazır bir OpenAI istemcisi varsa taban adresi değiştirmek çoğu zaman yetiyor.

Ne Zaman Jeneratör, Ne Zaman Şebeke?

DurumTercihNeden
Müşteri kodu veya kişisel veri işleniyorLokalVeri makineden çıkmıyor; sözleşme maddesi teknik olarak karşılanıyor
Tekrarlayan, kalıplı iş (log sınıflandırma, metin temizleme)LokalHacim yüksek, görev basit, kota yok
Uçtan uca mimari kurma, büyük refactorBulutGeniş bağlam ve en güçlü akıl yürütme gerekiyor
16 GB’ın altında VRAMBulut4.000 tokenlik pencere ajan işine yetmiyor
İnternetsiz ortam, kapalı ağLokalTek çalışan seçenek

Bu ikisi birbirinin alternatifi değil. Ciddi kurulumlarda ikisi birden bulunur: hassas veri lokalde, ağır düşünme bulutta. Anahtarı elinizde tutmanın yolu, istemciyi sağlayıcıdan bağımsız yazmaktan geçiyor; yukarıdaki sınıfta taban adresin yapılandırılabilir olması tam olarak bu yüzden.

Bedava Elektrik Diye Bir Şey Yok

Lokal model faturayı ortadan kaldırmaz, kalemlerini değiştirir. Jeton yerine VRAM ödersiniz, kota yerine bağlam, sağlayıcı kesintisi yerine kendi bakımınız. Karşılığında aldığınız şey gerçek ve küçümsenecek gibi değil: kodunuzun nereye gittiğini bilmek.

Kurarken üç şeyi not edin: pencereyi elle ayarlayın, lisansı indirmeden önce okuyun, motoru istemciden ayrı tutun. Üçünü de yaparsanız jeneratör evi aydınlatır. Yapmazsanız elinizde 19 GB’lık bir dosya ve üçüncü dosyada ne yazdığını unutan bir ajan kalır.

Bir sonraki bölümde (4.1) yönü değiştiriyoruz: Mega-Prompting, yani AI’ı projenin baş mimarı yapmak. Modelin nerede çalıştığından bağımsız olarak, ona ne anlattığınız belirleyici hâle geliyor. Serinin tamamı ve yayınlanan bölümlerin listesi Vibe Coder El Kitabı sayfasında.

Teknolojiyle kalın, faturayı okumadan imzalamayın.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir