4 Aralık 2025 Perşembe

WebGPU ile Tarayıcıda Yapay Zeka Çalıştırma: ONNX Runtime Web ve Transformers.js ile Adım Adım Rehber

Tarayıcıda yapay zeka modelleri çalıştırmak, son iki yılda WebGPU’nun olgunlaşmasıyla pratik hale geldi. WebGL ve saf WebAssembly çözümleri artık yerini daha modern, düşük seviye ve yüksek performanslı WebGPU’ya bırakıyor. Bu rehber, WebGPU destekli ONNX Runtime Web ve Transformers.js kullanarak istemci tarafında model çalıştırmayı adım adım anlatır; kurulum, performans ipuçları, geriye uyumluluk ve sorun giderme başlıklarını içerir.

WebGPU neden önemli?

WebGPU, GPU’ya daha doğrudan erişim sağlar, bellek kopyalamayı azaltır ve paralel işlemleri daha verimli yürütür. Görüntü sınıflandırma, metin gömme (embedding), duygu analizi, hatta küçük dil modelleri gibi görevlerde CPU’ya kıyasla ciddi hızlanma sağlayabilirsiniz. Üstelik tüm bunlar, veriyi sunucuya göndermeden, gizliliği koruyarak gerçekleşir.

Önkoşullar ve tarayıcı desteği

Güncel Chrome/Edge (121+), Safari 17+ (veya Technology Preview) ve Firefox Nightly, değişen derecelerde WebGPU desteği sunar. Chrome’da sorun yaşarsanız chrome://flags altında “Unsafe WebGPU” seçeneğini kontrol edin. Kurumsal cihazlarda kısıtlamalar olabilir. Destek yoksa ONNX Runtime Web’in WASM sağlayıcısına otomatik geçiş yapabilirsiniz.

Proje kurulumu (Vite + NPM)

Hızlı başlamak için Vite ile bir ön yüz projesi kurabilir ve hem düşük seviyeli API (onnxruntime-web) hem de yüksek seviyeli bir sarmalayıcı (Transformers.js) ekleyebilirsiniz. Aşağıdaki komutlar, örnek bir React projesi içindir; framework bağımlı değilsiniz, vanilla JS ile de kullanabilirsiniz.

# Proje oluşturma
npm create vite@latest webgpu-ai -- --template react
cd webgpu-ai

# Bağımlılıklar
npm i onnxruntime-web @xenova/transformers

# Geliştirme sunucusu
npm run dev

ONNX Runtime Web ile WebGPU’da model çalıştırma

ONNX Runtime Web (ORT Web), aynı API ile birden fazla yürütme sağlayıcısını (WebGPU, WebGL, WASM) destekler. Aşağıda WebGPU var ise onu, yoksa WASM’i kullanacak minimal bir örnek yer alıyor. Burada mobilenet gibi hafif bir görüntü sınıflandırma modeli varsayılmıştır.

import * as ort from 'onnxruntime-web';

async function loadSession() {
  const hasWebGPU = typeof navigator !== 'undefined' && !!navigator.gpu;

  const session = await ort.InferenceSession.create('/models/mobilenetv2.onnx', {
    executionProviders: hasWebGPU ? ['webgpu'] : ['wasm'],
    graphOptimizationLevel: 'all'
  });

  return session;
}

async function run(session, inputTensor) {
  const [inputName] = session.inputNames;
  const [outputName] = session.outputNames;
  const feeds = { [inputName]: inputTensor };

  const results = await session.run(feeds);
  const output = results[outputName]; // ort.Tensor
  return output;
}

// Basit ön işleme (örnek): 224x224, [1,3,224,224], normalize edilmiş Float32Array
// Gerçek uygulamada resmi canvas ile yeniden boyutlandırıp kanalları CHW formatına çevirin.

Modelin giriş/çıkış adları modellere göre değişir; yukarıdaki gibi session.inputNames ve session.outputNames kullanmak en güvenli yoldur. Performans için FP16’ye dönüştürülmüş modeller ve 224x224 gibi küçük giriş boyutları tercih edin. Ayrıca tek seferde birden fazla örnek (batch) işletecekseniz tarayıcı GPU belleği sınırlamalarını aklınızda tutun.

Transformers.js ile “yüksek seviyeli” kullanım

@xenova/transformers, tarayıcıda hazır NLP ve bazı görsel modelleri kolayca çalıştırmanızı sağlar. Arkada ONNX Runtime Web ve uygun olduğunda WebGPU kullanır. Aşağıdaki örnek duygu analizi içindir:

import { pipeline } from '@xenova/transformers';

async function runSentiment() {
  const hasWebGPU = typeof navigator !== 'undefined' && !!navigator.gpu;
  const device = hasWebGPU ? 'webgpu' : 'cpu'; // 'cpu' = WASM

  const pipe = await pipeline(
    'text-classification',
    'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
    { device }
  );

  const out = await pipe('Bu film şaşırtıcı derecede iyiydi!');
  console.log(out);
}

Transformers.js, ilk çalıştırmada modeli indirip tarayıcı önbelleğine alır. Üretim ortamında model dosyalarını kendi CDN’inizden sunmak ve sürümleri sabitlemek iyi bir pratiktir. Bazı modeller büyük olduğundan, başlangıç gecikmesini azaltmak için “tiny” veya “base” sürümleri tercih edin.

Performans ipuçları

1) Doğru veri türü: FP16 modeller WebGPU’da bellek ve bant genişliği avantajı sağlar. Mümkünse ağırlıkları FP16’ya dönüştürün. 2) Boyutlandırma: Görsel görevlerde 160–224 piksel aralığı mobil cihazlar için iyi bir dengedir. 3) Ön bellekleme: Uygulama açılışında session’ı yükleyip sıcak tutmak (warm-up) soğuk başlangıç gecikmesini azaltır. 4) I/O bağlama: ORT Web’de (sürümünüze bağlı) tensörleri GPU belleğinde tutmak için IOBindings seçeneklerini inceleyin. 5) Paralellik: WASM’a düşerseniz SIMD ve çok iş parçacığı hız kazandırır; bunun için COOP/COEP başlıklarıyla cross-origin isolation etkin olmalı.

Geriye uyumluluk ve düşüş (fallback) stratejisi

Her cihaz WebGPU desteklemeyebilir. Bu yüzden navigator.gpu kontrolüyle otomatik geçiş uygulayın: WebGPU → WASM. Kullanıcıya “hızlandırma kapalı” gibi basit bir durum göstergesi sunmak, deneyimi şeffaf kılar. Mobilde pil ve termal kısıtlar için bir “düşük güç modu” eklemek de değerlidir.

Güvenlik ve gizlilik

İstemci tarafı çıkarım (inference), verinin cihazdan çıkmamasını sağlar. Ancak model dosyaları herkese açık sunuluyorsa, telif ve lisans koşullarını gözden geçirin. Ayrıca büyük modeller cihaz belleğini hızla tüketebilir; kademeli yükleme (lazy load) ve dinamik boşaltma (dispose) uygulayın.

Sorun giderme

WebGPU görünmüyor: Kurumsal politikalar veya eski tarayıcı sürümü olabilir; flags ve sürüm kontrolü yapın. GPU belleği yetersiz: Giriş çözünürlüğünü ve batch boyutunu düşürün, FP16 kullanın. Yavaş ilk çalıştırma: Modeli önden ısıtın ve CDN’de sıkıştırma (gzip/br) + cache headers kullanın. WASM fallback çok yavaş: cross-origin isolation ile WASM SIMD/threads’i etkinleştirin ve daha hafif bir model seçin.

Sonuç

WebGPU, tarayıcıda yapay zekayı gerçek zamanlıya yaklaştırıyor. ONNX Runtime Web ile ince ayarlı, Transformers.js ile hızlı ve pratik bir deneyim kurabilirsiniz. Doğru model boyutu, FP16, akıllı ön/son işlem ve sağlam fallback stratejisiyle hem masaüstü hem mobilde akıcı bir kullanıcı deneyimi sunmak mümkün.

3 Aralık 2025 Çarşamba

Next.js ile Passkey (WebAuthn) Entegrasyonu: Parolasız Girişe Adım Adım Rehber

Giriş: Neden Passkey (WebAuthn)?

Parolalar hem kullanıcılar hem de geliştiriciler için baş ağrısı. Zayıf parolalar, kimlik avı, sızıntılar ve unutma problemi derken, güvenli ve sorunsuz bir deneyim için endüstri Passkey (FIDO2/WebAuthn) standartına hızla geçiyor. Passkey ile kullanıcılar biyometri (Face ID, Touch ID), donanım güvenlik anahtarı veya cihaz PIN’iyle güvenli ve parolasız giriş yapabiliyor. Bu rehberde, Next.js ve simplewebauthn kullanarak uçtan uca bir Passkey akışını nasıl kurabileceğinizi adım adım anlatıyorum.

Gereksinimler ve Kurulum

Başlamadan önce Node.js 18+, Next.js 13/14 App Router, bir veri tabanı (PostgreSQL veya MongoDB) ve HTTPS (localhost için Chrome’da güvenilir sertifika veya bir tünel aracı) gerekli. WebAuthn, origin ve rpID değerlerine duyarlıdır; yerel geliştirmede localhost ve üretimde gerçek alan adını kullanın. Kütüphaneler için npm i @simplewebauthn/server @simplewebauthn/browser komutunu çalıştırın.

Mimari: Kayıt ve Giriş Akışı

Passkey iki ana akıştan oluşur: Kayıt (Registration) ve Doğrulama (Authentication). Kayıtta sunucu bir challenge üretir, istemci bu veriyi cihazın güvenli donanımına kaydeder ve attestation verisini sunucuya geri yollar. Girişte ise sunucu yeni bir challenge üretir, istemci cihazı bunu imzalar ve imzalı assertion sunucuda doğrulanır. Tüm süreçte challenge değerini oturum (session, Redis) gibi geçici ve güvenli bir yerde tutmak önemlidir.

Sunucu Tarafı: Endpoints ve Doğrulama

Next.js App Router’da app/api altında iki çift endpoint tanımlayın: /register/generate ve /register/verify, /login/generate ve /login/verify. @simplewebauthn/server içindeki generateRegistrationOptions, verifyRegistrationResponse, generateAuthenticationOptions ve verifyAuthenticationResponse yardımcıları işinizi hızlandırır.

Önemli alanlar: rpID alan adınız (ör. example.com), origin tam kök adresiniz (ör. https://example.com). Üretimde bunların sabit ve doğru olması gerekir. Kayıt doğrulandıktan sonra veritabanında şu alanları saklayın: kullanıcı kimliği, credential ID (base64url), publicKey, counter, transports, backupEligibility/backupState bilgileri. Girişte doğrulama sonrası karşılaştırma için counter değerini güncelleyerek yeniden oynatma saldırılarını engelleyin.

İstemci Tarafı: Tarayıcı API’leriyle Etkileşim

Tarayıcı tarafında @simplewebauthn/browser kütüphanesinin startRegistration ve startAuthentication fonksiyonlarını kullanın. Kayıt için önce /register/generate endpoint’inden seçenekleri alın, startRegistration çağrısını yapın ve sonucu /register/verify’e gönderin. Giriş için benzer şekilde /login/generate → startAuthentication → /login/verify akışını izleyin. Bu işlemler sırasında kullanıcı, cihazında biyometrik doğrulama veya güvenlik anahtarına dokunuş gibi bir etkileşimle süreci tamamlar.

Pratik İpuçları ve Sık Hatalar

- Origin/RP ID uyuşmazlığı: En yaygın hata budur. Geliştirmede https://localhost:3000 origin ile rpID=localhost kullanın. Üretimde https://alanadiniz.com ve rpID=alanadiniz.com şart.

- Challenge saklama: Challenge’ı oturumda tutmazsanız doğrulama başarısız olur. Kısa ömürlü bir store (Redis, Signed Cookie) güvenlidir.

- Discoverable credentials: Kullanıcının e-posta girmeden giriş yapabilmesi için resident keys (discoverable) açılabilir. Gizlilik ve UX dengesini iyi düşünün; bazı senaryolarda kullanıcı kimliğini yine de isteyebilirsiniz.

- Platform desteği: iOS/Android, Chrome/Safari/Edge yeni sürümlerde destekler iyi durumdadır; ancak eski cihazlarda güvenlik anahtarı (YubiKey) fallback’i planlayın.

Güvenlik ve Uyum Notları

WebAuthn, kimlik avını ciddi ölçüde azaltır; çünkü imza domain’e (origin) bağlıdır. Yine de bazı ek önlemler gerekir: her istek için CSRF koruması, üretimde HTTPS zorunluluğu, gelen yanıtlar için origin doğrulaması, güvenli cookie ayarları (HttpOnly, SameSite=Lax/Strict, Secure). Kullanıcının birden fazla cihazda passkey kullanabilmesi için hesap başına birden fazla credential kaydına izin verin ve kolay yönetim ekranları oluşturun.

Kurumsal ortamlarda enforce MFA ve politika tabanlı kayıt akışlarını düşünebilirsiniz. Ayrıca, backup/icloud passkey senkronizasyonu devredeyse, cihaz değişiminde kullanıcı deneyimi daha pürüzsüz olur. Bu arada, userVerification modunu required olarak ayarlamak, cihazda biyometrik/PIN doğrulamasını zorunlu kılarak güvenliği artırır.

Örnek Veri Modeli ve Loglama

Basit bir credential tablosu şu alanları içerebilir: id, userId, credentialId (unique), publicKey, counter, deviceType (platform/cross-platform), backupState, transports, createdAt, lastUsedAt. Her doğrulamada lastUsedAt ve counter değerlerini güncelleyin. Üretimde başarısız doğrulamalar için detaylı ancak kişisel veriyi ifşa etmeyen loglar tutun; PII saklamamaya özen gösterin.

Performans ve UX İyileştirmeleri

İlk boyamada kullanıcıya cihazın passkey desteklediğini hızlıca göstermek için PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() ile bir özellik kontrolü yapabilirsiniz. Desteklenmiyorsa alternatif girişi (OTP/Magic Link) otomatik önerin. SSR yerine istemci tarafında akışı tetikleyip, istekleri mutate eden bir data fetching yaklaşımı (SWR/React Query) ile ağ hatalarında kullanıcıya net geri bildirim sağlayın.

Sonuç

Passkey (WebAuthn) entegrasyonu, hem güvenliği hem de dönüşüm oranlarını artıran çağdaş bir yaklaşım. Next.js ve simplewebauthn ile kurulum nispeten hızlı; kritik nokta ise rpID/origin doğruluğu, challenge yönetimi ve credential saklama stratejisi. Bu rehberdeki adımları izleyerek parolasız deneyimi projenize ekleyebilir, kullanıcılarınıza modern ve güvenli bir giriş akışı sunabilirsiniz.

2 Aralık 2025 Salı

Passkey (WebAuthn/FIDO2) ile Parolasız Giriş: Next.js Üzerinde Adım Adım Kurulum

Passkey nedir ve neden önemlidir?

Parolasız kimlik doğrulama, son yılların en önemli güvenlik trendlerinden biri. Passkey teknolojisi (WebAuthn/FIDO2), kimlik doğrulamayı klasik parolaların ötesine taşıyarak kimlik avına dayanıklı ve kullanıcı dostu bir deneyim sunuyor. Apple, Google ve Microsoft’un ekosistemleriyle entegre çalışan passkey’ler; cihazdaki güvenli donanım veya güvenli alanı kullanarak anahtar çifti üretir ve web sitelerine girişte yalnızca özel anahtar cihazda kalır. Böylece kullanıcılar Touch ID/Face ID, Windows Hello veya Android’in biyometrik yöntemleriyle tek dokunuşla güvenli giriş yapabilir.

Nasıl çalışır? (Kısa teknik özet)

Passkey, tarayıcıların sunduğu WebAuthn API üzerinden etkileşim kurar. Site (Relying Party), kayıt sırasında tarayıcıya bir “challenge” ve alan adı (rpID) gönderir. Kullanıcının cihazı bir anahtar çifti üretir; genel anahtar sunucuya kaydedilir, özel anahtar cihazda kalır. Giriş esnasında sunucu yeni bir “challenge” üretir; cihaz bu “challenge”ı özel anahtarla imzalar ve sunucu imzayı doğrular. Bu yapı sayesinde şifre sızması, parola doldurma saldırıları ve kimlik avı riskleri önemli ölçüde azalır.

Önkoşullar ve mimari

Bu rehberde Next.js 14 (App Router) üzerinde örnek bir passkey akışı kuracağız. İhtiyacınız olanlar: Node.js 18+, Next.js projesi, HTTPS (geliştirirken localhost desteklenir), bir veritabanı (ör. PostgreSQL, MongoDB) ve WebAuthn yardımcı kütüphaneleri. Üretimde rpID değeriniz, gerçek alan adınız (ör. example.com) olmalı; doğrulama başarısızlıklarının büyük kısmı rpID/domain uyumsuzluğundan kaynaklanır.

Adım 1: Kurulum ve bağımlılıklar

Örnek projeyi başlatmak için npx create-next-app@latest passkey-demo komutunu kullanın. Ardından sunucu ve istemci tarafı için popüler bir yardımcı set olan @simplewebauthn/server ve @simplewebauthn/browser paketlerini ekleyin: npm i @simplewebauthn/server @simplewebauthn/browser. Ortam değişkenleri için RP_NAME ve RP_ID tanımlayın (ör. RP_NAME="Passkey Demo", RP_ID="localhost" veya üretimde example.com).

Adım 2: Kayıt (Registration) akışı

Kayıt akışı iki uç noktadan oluşur: seçenek üretimi ve doğrulama. Sunucuda önce generateRegistrationOptions ile kullanıcıya özel bir challenge ve seçenekler oluşturulur. Örnek kullanım: const opts = generateRegistrationOptions({ rpName, rpID, userID, userName, attestationType: 'none', authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred' } }). Bu opts istemciye döndürülür ve tarayıcıda startRegistration(opts) çağrısı yapılır. Tarayıcı, cihazın güvenli alanında anahtar çifti üretir ve sonucu (credential) sunucuya gönderir.

Doğrulama aşamasında sunucuda verifyRegistrationResponse ile imza ve köken (origin) kontrolü yapılır. Başarılıysa kullanıcının hesabına credentialID, publicKey, signCount gibi alanları kaydedin. Birden fazla cihaza passkey eklenmesini desteklemek için kullanıcı başına birden çok credential saklamak iyi bir pratiktir.

Adım 3: Giriş (Authentication) akışı

Giriş için benzer şekilde önce generateAuthenticationOptions çağrılır. Kullanıcıya ait credential’lar biliniyorsa allowCredentials listesi ile sınırlandırabilir veya cihazın keşfedilebilir kimlik bilgilerini (discoverable credentials) desteklemek için boş bırakabilirsiniz. İstemci tarafında startAuthentication(opts) çalıştırılır ve elde edilen yanıt sunucuya doğrulama için gönderilir.

Sunucuda verifyAuthenticationResponse ile imza, challenge, origin, rpID ve sayacın (signCount) ilerleyişi kontrol edilir. Başarılı doğrulamada kullanıcı oturumunu başlatın ve credential’ın signCount değerini güncelleyin. Geriye dönük saldırıları önlemek için aynı imzayı tekrar kabul etmeyin.

İyi uygulamalar (Security + UX)

- HTTPS zorunludur: Üretimde daima HTTPS kullanın; rpID alan adınız ile origin (ör. https://example.com) örtüşmelidir. Geliştirmede localhost istisna olarak desteklenir.
- Biyometrik doğrulama: userVerification: 'required' seçeneği güvenliği artırır ancak bazı eski cihazlarda uyumluluğu azaltabilir. Dengeli yaklaşım için 'preferred' iyi bir başlangıçtır.
- Platform ve geçiş anahtarları: Kullanıcılara hem cihaz içi (platform) hem de harici güvenlik anahtarlarıyla kayıt seçeneği sunun.
- Hesap kurtarma: Passkey harika bir deneyim sunar; yine de e‑posta tabanlı oturum açma bağlantısı veya sınırlı süreli OTP gibi bir kurtarma kanalı tutun.
- Çoklu cihaz: iCloud Anahtar Zinciri veya Google Password Manager senkronizasyonu sayesinde kullanıcı farklı cihazlardan giriş yapabilir; bu durumda kullanıcı akışını basit ve yönlendirici metinlerle destekleyin.

Test, hata ayıklama ve dağıtım

Geliştirme sırasında WebAuthn’ı about://webauthn veya Chrome’un Geliştirici Araçları altındaki Sanal Kimlik Doğrulayıcı ile test edebilirsiniz. Gerçek cihaz testi için ngrok gibi tünelleme araçlarıyla geçici bir HTTPS alan adı edinip RP_ID’yi bu alan adına ayarlayın. iOS 16+, Android 9+ ve modern masaüstü tarayıcılar passkey’i destekler. Üretime alırken CORS, SameSite ve Secure bayraklı çerez ayarlarını kontrol edin; kimlik doğrulama uç noktalarınızı rate limit ve CSRF koruması ile güçlendirin.

Sık karşılaşılan hatalar ve çözümleri

- Invalid Relying Party ID: rpID ile sitenin alan adı eşleşmiyordur. Alt alan adlarında rpID üst etki alanı olabilir (ör. app.example.com için example.com).
- NotAllowedError: Kullanıcı tarayıcı diyalogunu iptal etmiştir veya zaman aşımı yaşanmıştır. İstemci tarafında daha anlaşılır hata mesajları ve tekrar dene düğmesi gösterin.
- User verification required: Sunucuda userVerification 'required' iken cihaz biyometrik doğrulama sunmuyorsa 'preferred' ile test edin.
- Counter mismatch: signCount geriye düştüyse credential’ı güvenlik gerekçesiyle askıya alın ve kullanıcıdan yeniden kayıt isteyin.

Sonuç

Passkey, güvenliği artırırken kullanıcı deneyimini hızlandıran güçlü bir yaklaşım. Next.js ile WebAuthn/FIDO2 entegrasyonu birkaç uç nokta ve doğru yapılandırmayla kısa sürede hayata geçebilir. Bu rehberdeki adımlarla kayıt ve giriş akışlarını kurabilir, üretimde HTTPS, rpID, sayım ve köken kontrolleriyle sisteminizi sertleştirebilirsiniz. Parolasız geleceğe geçiş için en iyi zaman, kullanıcılarınız hazır ve modern tarayıcılar destekliyorken bugündür.

1 Aralık 2025 Pazartesi

Docker Buildx ile Çok Mimarili Konteyner İmajı Oluşturma ve GitHub Actions ile Otomasyon

Giriş: Neden Çok Mimarili İmaj?

Apple Silicon (ARM64) cihazların, bulut sağlayıcıların ve edge cihazların yükselişi, tek mimariye derlenmiş konteyner imajlarının yeterli olmadığı bir dönemi başlattı. Uygulamanızı hem linux/amd64 hem de linux/arm64 üzerinde sorunsuz çalıştırmak istiyorsanız, Docker Buildx ve QEMU emülasyonu devreye giriyor. Bu yazıda, yerelde hızlıca çok mimarili imaj üretecek, ardından GitHub Actions ile her push veya tag’de otomatik olarak registry’ye yayınlayacak bir kurulum yapacağız.

Önkoşullar ve Temel Kavramlar

Başlamadan önce sisteminizde Docker Engine veya Docker Desktop’ın güncel bir sürümü kurulu olmalı. Buildx varsayılan olarak Docker ile gelir, ancak Linux kullanıcıları için docker buildx komutunun aktif olduğundan emin olun. Yerelde farklı mimariler için derleme yaparken QEMU desteği gerekir; Buildx bunu otomatik konfigüre edebilir. Ayrıca Docker Hub veya GHCR (GitHub Container Registry) gibi bir kayıt defterinde hesabınız ve kimlik bilgisi gerekecek. “Mimari” derken kastedilen: Intel/AMD tabanlı sunucular için amd64, Apple M serisi ve çoğu ARM tabanlı cihaz için arm64.

Dockerfile: Çok Aşamalı ve Mimariden Bağımsız

Örnek olarak küçük bir Go uygulaması için çok aşamalı bir Dockerfile kullanalım. Go, cross-compile’a yatkın olduğu için çok mimarili imajlarda pratiktir. Buildx, derleme sırasında TARGETPLATFORM ve TARGETARCH gibi değişkenleri otomatik olarak geçirir.

# syntax=docker/dockerfile:1.6
FROM golang:1.22-alpine AS build
WORKDIR /src
COPY . .
# CGO'yu kapatıp hedef mimariyi Buildx'ten alıyoruz
ARG TARGETARCH
ENV CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /out/app .

FROM alpine:3.20 AS runtime
RUN adduser -D -u 10001 app
USER app
COPY --from=build /out/app /app
EXPOSE 8080
ENTRYPOINT ["/app"]

Yukarıdaki Dockerfile, cache mount’larını kullanarak derlemeleri hızlandırır, root olmayan bir kullanıcı ile çalıştırır ve minimum imaj boyutu sağlar. Benzer bir yaklaşımı Node.js, Python veya Rust projelerinde de çok aşamalı yapı ile uygulayabilirsiniz.

Buildx’i Etkinleştirme ve Yerelde Test

Önce Buildx builder’ını oluşturun ve QEMU’yu başlatın:

docker buildx create --name xbuilder --use
docker buildx inspect --bootstrap

Ardından çok mimarili imajı derleyip bir kayıt defterine itin. Örnek olarak Docker Hub kullanıyorsanız:

docker login
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t KULLANICI_ADI/uygulama:1.0.0 \
-t KULLANICI_ADI/uygulama:latest \
--push .

İmajı emülasyonla farklı mimarilerde çalıştırmayı test edebilirsiniz:

docker run --rm --platform linux/arm64 KULLANICI_ADI/uygulama:1.0.0 --help

GitHub Actions ile Otomatik Yayın

Süreci otomatikleştirmek için depo köküne .github/workflows/build.yml adında bir iş akışı ekleyin. Aşağıdaki örnek, GHCR’ye push eder; Docker Hub için registry ve kimlik bilgilerini uyarlayın.

name: build-and-push-multi-arch
on:
push:
branches: ["main"]
tags: ["v*"]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=ref,event=branch
type=raw,value=latest,enable={{is_default_branch}}
- uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

Bu iş akışı; QEMU’yu kurar, Buildx’i etkinleştirir, GHCR’ye giriş yapar, semantik veya branch tabanlı etiketleri otomatik üretir ve iki mimari için imajı derleyip yayınlar. Docker Hub kullanıyorsanız registry satırını kaldırıp username/password için DOCKERHUB_USERNAME ve DOCKERHUB_TOKEN gibi secret’lar tanımlayın.

İnce Ayar: Performans, Güvenlik ve Boyut

Derlemeleri hızlandırmak için cache kullanımı kritik önemdedir. Yerelde --cache-to ve --cache-from bayrakları veya GitHub Actions’ta type=gha ile katmanları önbelleğe alın. .dockerignore dosyası ile gereksiz dosyaları dışarıda bırakın. Güvenlik açısından root olmayan kullanıcı kullanmak, yalnızca gerekli portları açmak, en küçük taban imajlarını (ör. alpine veya distroless) tercih etmek, SBOM ve kaynak kanıtı için --sbom=true ve --provenance=true kullanmak iyi pratiklerdir. İmajlarınızı imzalamak için cosign ile CI adımı ekleyebilirsiniz. Etiket stratejisinde hem latest hem de v1.2.3 gibi sürüm etiketlerini birlikte yayınlamak, geriye dönük izleme ve hızlı geri dönüş (rollback) sağlar.

Yayına Alındıktan Sonra Doğrulama

Yayınlanan imajın manifest listesine bakarak gerçekten çok mimarili olup olmadığını doğrulayın: docker buildx imagetools inspect ghcr.io/HESAP/REPO:latest. Çıktıda hem linux/amd64 hem de linux/arm64 gördüğünüzde her şey yolundadır. Üretim ortamında çekme yapan sistemlerin doğru mimariyi otomatik seçeceğini unutmayın.

Sonuç

Docker Buildx, modern çok mimarili dünyada tek komutla iki farklı platforma hitap eden imaj üretmeyi kolaylaştırır. GitHub Actions ile birleştirildiğinde, her commit veya sürümde otomatik ve tekrarlanabilir bir yayın hattı elde edersiniz. Bu yaklaşım, M serisi Mac’lerde yerel geliştirmeyi hızlandırırken, bulut ve edge ortamlarında tutarlı dağıtım sağlar. Küçük dokunuşlarla (önbellek, minimal taban imaj, imzalama) performansı artırabilir ve güvenliği güçlendirebilirsiniz.

30 Kasım 2025 Pazar

Passkey (WebAuthn) ile Şifresiz Giriş: Next.js ve SimpleWebAuthn ile Uçtan Uca Kurulum

Passkey (WebAuthn) ile Şifresiz Giriş: Adım Adım Uygulama Rehberi

Parola yorgunluğu, kimlik avı ve SMS tabanlı doğrulamanın zayıflıkları derken, modern web uygulamalarında şifresiz giriş kaçınılmaz hale geldi. Passkey’ler, WebAuthn ve FIDO2 standartlarıyla desteklenen, biyometri veya cihaz kilidiyle korunan anahtar çiftlerine dayanır. Kullanıcı deneyimini hızlandırır, kimlik avına dayanıklıdır ve iCloud Anahtar Zinciri ile Google Password Manager gibi yöneticiler arasında senkronize olabilir. Bu yazıda, Next.js ve SimpleWebAuthn kütüphanesi ile uçtan uca bir passkey (WebAuthn) entegrasyonunu nasıl kuracağınızı adım adım anlatıyorum.

Neden Passkey?

Passkey, kullanıcının cihazında saklanan bir özel anahtar ile sunucunun sakladığı açık anahtarın eşleşmesine dayanır. Parola gönderilmez, dolayısıyla veri tabanı sızıntılarında parolaların çalınması gibi riskler ortadan kalkar. Kullanıcı cihazında biyometri (Face ID, Touch ID), donanım anahtarı (YubiKey) veya cihaz PIN’i ile doğrulama yapar. Tarayıcı ve platform desteği artık yaygınlaştı; Chrome, Safari ve Firefox, iOS/Android ve masaüstü işletim sistemlerinde kullanılabiliyor.

Mimari ve Gereksinimler

WebAuthn iki ana akış içerir: kayıt (registration) ve kimlik doğrulama (authentication). Her akışta sunucu benzersiz bir challenge üretir, istemci tarafında tarayıcı navigator.credentials API’si ile doğrulama cihazıyla imza atılır ve bu yanıt sunucuda doğrulanır. Üretimde HTTPS zorunludur ve RP ID (Relying Party ID) alan adınızla birebir eşleşmelidir (ör. rpID = example.com).

Teknoloji Seçimi

Örnek kurulum için Next.js 14 (Route Handlers veya App Router), sunucu tarafında @simplewebauthn/server, istemci tarafında @simplewebauthn/browser kullanılabilir. Veritabanı olarak Postgres veya bir KV deposu tercih edebilirsiniz. Saklanacak başlıca alanlar: kullanıcı kimliği, credentialID, publicKey, counter ve tercihen cihaz/metaveri.

Kayıt Akışı (Registration)

1) Kullanıcı e-posta/ID ile kayıt başlatır. Sunucu generateRegistrationOptions ile seçenekleri üretir, challenge’ı geçici olarak saklar ve istemciye döner. Örnek:

const opts = generateRegistrationOptions({ rpName: 'Uygulama Adı', rpID: 'example.com', userName: 'ali', userID: 'user-123', attestationType: 'none', authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred', authenticatorAttachment: 'platform' } });

2) İstemci, tarayıcıda @simplewebauthn/browser yardımıyla kullanıcıdan biyometri izni ister ve kimlik bilgisi oluşturur:

const attResp = await startRegistration(opts);

3) Sunucu, verifyRegistrationResponse ile gelen cevabı doğrular; doğrulama başarılıysa credentialID, publicKey ve counter değerlerini kullanıcıyla ilişkilendirerek kalıcı olarak saklar.

Giriş Akışı (Authentication)

1) Kullanıcı giriş sayfasında e-posta/ID girer veya koşullu UI ile otomatik olarak öneri alır. Sunucu generateAuthenticationOptions ile yeni bir challenge üretir. İsteğe bağlı olarak yalnızca ilgili kullanıcının kayıtlı cihazlarını allowCredentials ile sınırlandırabilirsiniz.

2) İstemci tarafında çağrı yapılır:

const authResp = await startAuthentication(options);

3) Sunucu verifyAuthenticationResponse ile imzayı ve origin/rpID alanlarını doğrular, counter değerini günceller. Başarılıysa oturumu (cookie/JWT) kurar.

Koşullu UI (Conditional Mediation) ile Tek Tık Giriş

Chrome ve destekleyen tarayıcılarda, kullanıcı adı alanı odaktayken passkey önerilerini otomatik gösterebilirsiniz. Basitçe bir email input’unuz varken:

navigator.credentials.get({ publicKey: authOptions, mediation: 'conditional' });

Bunun çalışması için sayfanız HTTPS olmalı, autocomplete öznitelikleri doğru ayarlanmalı ve kullanıcı daha önce passkey kaydetmiş olmalıdır. Bu yöntem giriş sürtünmesini ciddi şekilde azaltır.

Güvenlik İpuçları ve En İyi Uygulamalar

- RP ID alan adınızla aynı olmalı; yerelde test ederken localhost kullanın veya geçerli bir sertifika ile alt alan adı hazırlayın.

- attestationType: 'none' çoğu senaryo için en iyisidir; gereksiz attestation verisi toplamayın.

- userVerification için 'required' yüksek güvenlikli sayfalar için uygundur (örn. ödeme, ayarlar). Genel girişte 'preferred' iyi bir dengedir.

- Kullanıcıların cihaz değiştirme/ekleme senaryoları için birden fazla passkey kaydına izin verin ve kurtarma seçenekleri (e-posta bağlantısı veya destek akışı) sunun.

- Rate limit, yeniden oynatma (replay) engelleme, kaynak (origin) ve challenge ömrünü doğrulamayı ihmal etmeyin.

Hata Ayıklama ve Test

- SecurityError: The operation is insecure genelde HTTPS veya RP ID uyuşmazlığını gösterir.

- NotAllowedError kullanıcı etkileşimi yokken veya işlemi iptal ettiğinde görülür; buton tıklamasıyla tetikleyin.

- Unknown authenticator veya eşleşmeyen credentialID için doğru kullanıcıyla ilişkilendirme yapıldığından emin olun.

- Tarayıcı konsolu ve about://webauthn (Chrome) test araçları ile sanal güvenlik anahtarı oluşturup akışları yerelde deneyebilirsiniz.

Performans ve UX

Passkey akışı minimal JSON veri alışverişine dayanır; SSR ve edge işleme ile gecikmeyi azaltabilirsiniz. Başarılı kayıt sonrası kullanıcının cihazı üzerinde parolayı da “kaldırmayı” önermek, geçişi hızlandırır. Kullanıcıya hangi cihazların kayıtlı olduğunu gösteren bir yönetim ekranı sunmak güveni artırır.

Sonuç

Passkey (WebAuthn) ile şifresiz giriş, güvenliği artırırken kullanıcı deneyimini de basitleştirir. Next.js ve SimpleWebAuthn ile kurulumu birkaç uç noktaya indirgenebilir: kayıt için seçenek üretme/doğrulama ve giriş için seçenek üretme/doğrulama. RP ID, HTTPS ve challenge yönetimi gibi kritik ayrıntılara dikkat ettiğiniz sürece, modern tarayıcılarda hızlı ve güvenli bir oturum altyapısı sağlayabilirsiniz.

29 Kasım 2025 Cumartesi

pgvector ile RAG Uygulaması: Docker Compose ile PostgreSQL 16 ve Basit Semantik Arama API’si

RAG (Retrieval-Augmented Generation), büyük dil modellerinin (LLM) güncel ve alanınıza özgü verilerle daha doğru yanıtlar üretmesini sağlar. Bu yaklaşımda, soruyu bir vektöre dönüştürür, vektör veritabanından benzer içerikleri geri çağırır ve modeli bu bağlamla beslersiniz. Özel bir vektör veritabanına ihtiyaç duymadan, PostgreSQL 16 + pgvector ile etkili bir semantik arama katmanı kurmak mümkündür. Bu yazıda, Docker Compose ile PostgreSQL’i ayağa kaldıracak, pgvector eklentisini etkinleştirecek ve basit bir API üzerinden semantik arama yapabileceğiz.

Neden PostgreSQL + pgvector? PostgreSQL hâlihazırda üretim ortamlarında yaygın, güvenilir ve güçlü bir ilişkisel veritabanıdır. pgvector eklentisi, vektör tipini, benzerlik metriklerini (cosine, L2, inner product) ve ivfflat/HNSW benzeri indeksleme stratejilerini destekler. Küçük ve orta ölçekli RAG projeleri için tek bir veritabanı üzerinde hem ilişkisel hem de vektörel sorgular yürütmek operasyonel anlamda sade ve maliyet-etkindir.

Önkoşullar: Makinenizde Docker ve Docker Compose kurulu olmalı. Embedding üretimi için OpenAI hesabı (veya yerelde Ollama gibi bir çözüm) işinizi kolaylaştırır. Örneklerde OpenAI’nin “text-embedding-3-small” (1536 boyut) modelini referans vereceğiz; yerel seçenek kullanacaksanız embedding boyutunu ona göre ayarlamalısınız.

Adım 1: Docker Compose ile PostgreSQL 16 ve pgvector
Basit bir docker-compose.yml dosyası oluşturun ve şu servisi tanımlayın:
version: "3.9"
services:
  db:
    image: pgvector/pgvector:pg16
    environment:
      - POSTGRES_USER=rag
      - POSTGRES_PASSWORD=ragpass
      - POSTGRES_DB=ragdb
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:
Dosyayı kaydedip docker compose up -d komutunu çalıştırın. Bu imaj, pgvector eklentisi ile birlikte gelir.

Adım 2: pgvector’ü etkinleştirmek ve şema hazırlığı
Veritabanına bağlanın: psql -h localhost -U rag -d ragdb ve şu komutları çalıştırın:
CREATE EXTENSION IF NOT EXISTS vector;
OpenAI’nin “text-embedding-3-small” boyutuna uygun bir tablo oluşturun:
CREATE TABLE docs (
  id BIGSERIAL PRIMARY KEY,
  content TEXT NOT NULL,
  embedding vector(1536)
);
Arama performansı için ivfflat indeksini kurun (cosine metrik popüler bir tercih):
CREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
İndeksin etkili çalışması için tabloyu analiz edin: ANALYZE docs;

Adım 3: Embedding üretimi ve veri ekleme
Örnek içerikler ekleyelim: ürün açıklamaları, SSS, teknik notlar vs. Python ile kısa bir betik yazabilirsiniz. OpenAI için mantık şu şekildedir:
- Metni al, client.embeddings.create(model="text-embedding-3-small", input=metin) ile vektörü üret.
- Vektörü PostgreSQL’e parametreli bir sorgu ile yaz: INSERT INTO docs(content, embedding) VALUES ($1, $2).
Yerel alternatif isterseniz, Ollama’da ollama pull nomic-embed-text diyerek bir embedding modeli çekebilir, http://localhost:11434/api/embeddings üzerinden benzer bir akış kurabilirsiniz. Dikkat: embedding boyutunu (ör. 768) tablo şemanızla tutarlı yapın.

Adım 4: Semantik arama sorgusu
Kullanıcı sorgusunu da embedding’e çevirin ve ORDER BY embedding <=> $1 ifadesiyle benzerliğe göre sıralayın. Örnek bir SQL:
WITH q AS (SELECT $1::vector AS v)
SELECT id, content
FROM docs, q
ORDER BY docs.embedding <=> q.v
LIMIT 5;
Burada <=>, pgvector’ün benzerlik operatörüdür (cosine için mesafe). Bu sonuçları LLM’e bağlam olarak verip RAG yanıtı oluşturabilirsiniz.

Adım 5: Basit bir API ile uçtan uca akış
Hızlı bir prototip için Python FastAPI idealdir. Akış şöyledir:
1) POST /search: query alır, embedding üretir, PostgreSQL’den top-k döner.
2) POST /ask: query ve top-k bağlamı alır, seçtiğiniz LLM (OpenAI veya yerel) ile yanıt üretir.
Üretimde, sonuçları önbelleğe almak (ör. Redis), indeks lists değerini veri büyüklüğüne göre artırmak ve maintenance_work_mem, shared_buffers gibi PostgreSQL ayarlarını optimize etmek önemlidir.

İleri seviye ipuçları
- HNSW: pgvector 0.7+ sürümlerinde HNSW desteği bulunur; okuma gecikmesini düşürür, ancak indexleme süresi ve bellek kullanımı artar. Benchmark yapmadan geçiş yapmayın.
- Normalize embedding: Cosine benzerliğinde vektörleri normalize etmek sonuç tutarlılığını artırabilir.
- Chunking ve metadata: Belgeleri 300–800 token aralığında parçalara bölün. Kaynak, tarih, başlık gibi metadata alanlarını tabloya ekleyin ve sonuçlarda gösterin.
- Güncelleme stratejisi: Sık değişen veriler için upsert akışı oluşturun; embedding’i yalnızca içerik değiştiğinde güncelleyin.
- Güvenlik: Üretimde veritabanını dışarıya kapatın, SSL kullanın, sıkı rol ve politika tanımları yapın.

Sonuç
PostgreSQL 16 ve pgvector ile, ek bir servis karmaşıklığına girmeden güçlü bir semantik arama ve RAG katmanı kurabilirsiniz. Docker Compose yapılandırması hızlı kurulum sağlar; embedding üretimi için OpenAI veya yerel modelleri kullanabilirsiniz. Üzerine basit bir API ekleyerek hem prototip hem de üretim öncesi pilot projelerinizi hızla hayata geçirmeniz mümkün. Doğru indeks, boyut ve ayarlarla, pgvector küçük-orta ölçekli prodüksiyon yüklerini rahatlıkla karşılayacaktır.

28 Kasım 2025 Cuma

RAG ile Türkçe Soru-Cevap Sistemi Kurma: Vektör Veritabanı, Yeniden Sıralama ve Prompt Tasarımı

RAG (Retrieval-Augmented Generation), büyük dil modellerinin (LLM) güncel ve alanınıza özel bilgilerle desteklenmesini sağlayan, üretken yapay zekâ projelerinde giderek standarda dönüşen bir yaklaşımdır. Bu yazıda, Türkçe odaklı bir doküman arama ve soru-cevap sistemini RAG mimarisiyle nasıl kurabileceğinizi; veri hazırlığından vektör veritabanına, yeniden sıralamadan (re-ranking) prompt tasarımına kadar adım adım anlatıyorum.

Amaç, kullanıcı sorusuna dayanarak şirket içi PDF’ler, politika metinleri, ürün katalogları veya destek dökümanları içinden ilgili pasajları bulmak ve LLM’nin yalnızca bu pasajları referans alarak doğru, denetlenebilir cevaplar üretmesini sağlamaktır. Böylece hem halüsinasyonları azaltır hem de cevaplara kaynak gösterebilirsiniz.

Mimari Özeti: RAG iki parçadan oluşur. Birincisi bilgi erişimi (retrieval): Belgeleri parçalayıp (chunking), vektörlerine dönüştürerek bir vektör veritabanına koyar ve sorguya en yakın aday pasajları getirir. İkincisi jenerasyon (generation): LLM, gelen pasajları bağlam olarak kullanıp nihai cevabı üretir. İsteğe bağlı üçüncü bir katman olan yeniden sıralama (re-ranking) ile en iyi adayları üst sıralara taşıyarak doğruluğu yükseltirsiniz.

1) Veri Toplama ve Temizleme: PDF, HTML, Word veya düz metin kaynaklarınızı tek bir havuzda toplayın. Başlık, bölüm, tarih ve izin seviyesi gibi meta verileri koruyun. OCR gerekiyorsa hatalı karakterleri düzeltin, tabloları metne uygun biçimde dönüştürün. Aynı belgenin eski sürümlerini işaretleyerek sürüm çakışmalarını engelleyin.

2) Parçalama (Chunking): Türkçe dilinde bağlamı korumak için paragraf temelli veya cümle temelli parçalama tercih edin. 400–800 token aralığı pratikte iyi sonuç verir; çok küçük parçalarda bağlam kaybolur, aşırı büyük parçalarda ise arama isabeti düşer. Kayma penceresi (overlap) 50–100 token aralığında seçildiğinde cümle bütünlüğü ve referanslar daha sağlam kalır.

3) Gömme (Embeddings) Seçimi: Çok dilli Sentence Transformers tabanlı modeller veya Türkçe uyumlu modern embedding modelleri tercih edin. Türkçe morfolojisi nedeniyle kök/ek varyasyonlarını iyi yakalayan çok dilli modeller pratikte güçlüdür. Vektörleri L2 normla normalize etmeniz kozinüs benzerliği için istikrar sağlar. Boyut (dimensionality) arttıkça isabet artsa da depolama ve gecikme maliyeti yükselir; üretim için 384–1024 aralığı dengelidir.

4) İndeksleme ve Vektör Veritabanı: FAISS ile lokal hızlı prototipleme yapabilir, üretimde Qdrant, Weaviate, Pinecone ya da Elasticsearch’ün yoğun vektör (dense) alanlarını kullanabilirsiniz. HNSW veya IVF-PQ gibi yaklaşık en yakın komşu (ANN) indeksleri gecikmeyi düşürür. Meta veri filtreleme (ör. dil, departman, tarih) ile hassas eşleşme yaparak alakasız sonuçları erkenden eleyin.

5) Hibrit Arama: Tek başına vektör benzerliği bazen anahtar kelime ağırlıklı soruları ıskalayabilir. BM25 + vektör aramayı birleştirerek iki dünyanın en iyisini alabilirsiniz. RRF (Reciprocal Rank Fusion) veya ağırlıklı skor birleştirme ile son aday listesini oluşturun. MMR (Maximal Marginal Relevance) kullanarak çeşitliliği artırın; böylece benzer pasajlar yerine farklı açılardan destekleyen pasajlar üst sıralara gelir.

6) Yeniden Sıralama (Re-ranking): İlk 50–200 adayı, küçük ama hassas bir çapraz-enkoder re-ranker modeliyle yeniden puanlayın. Re-ranker, sorgu ile pasaj arasındaki anlam ilişkisini derinlikli değerlendirir ve isabeti gözle görülür şekilde artırır. Özellikle Türkçe sorgularda, re-ranker kullanımı yanlış pozitifleri ciddi biçimde azaltır.

7) Prompt Tasarımı: Sistem talimatına “Sadece sağlanan bağlamdan yararlan, kaynak yoksa ‘yeterli bilgi yok’ de” gibi net kısıtlar ekleyin. Kullanıcı sorusu, seçilen pasajlar ve gerekirse kısa bir özet talimatı tek bir prompt içinde verilebilir. Her pasajın yanında kaynak kimliği (belge adı, sayfa, bölüm) tutarak yanıta otomatik kaynakça ekleyin; bu, güven ve denetlenebilirlik sağlar.

8) Cevap Üretimi ve Biçimlendirme: Uzun cevaplar için madde işaretleri, kısa cevaplar için net tek paragraf formatı tercih edin. Modelin “uydurma” eğilimini azaltmak için bağlam penceresini verimli kullanın; gerekirse soruyu alt-sorulara bölüp her alt-soru için mini retrieval akışı kurgulayın (multi-step RAG). Hassas alanlarda (hukuk, finans, sağlık) kesinlik dilini yumuşatın ve gerekiyorsa uyarı notu ekleyin.

9) Değerlendirme ve İzleme: Recall@k, MRR, nDCG gibi arama metrikleri ile konteks isabetini ölçün. Yanıt kalitesi için bağlam kapsamı, doğruluk ve kaynak tutarlılığına bakın. Üretim ortamında RAG değerlendirme çerçeveleri (ör. otomatik değerlendirme ve örneklem tabanlı insan denetimi) kurarak sürekli iyileştirme döngüsü oluşturun. Yanlış eşleşen pasajları etiketleyip yeniden eğitime dahil ederek sistematik hataları azaltın.

10) Performans, Maliyet ve Bakıma Dair İpuçları: Sorgu tarafında embedding önbelleği, sonuç tarafında yanıt önbelleği (semantic cache) maliyeti düşürür. ANN indeks parametrelerini (efSearch, nprobe vb.) gecikme/hedef isabet dengesine göre ayarlayın. Kenar cihazlarda veya düşük bütçede 4-bit/8-bit quantized LLM’ler iş görür. Büyük kurumsal koleksiyonlarda artımlı indeks güncellemeleri ve arka plan yeniden inşa stratejisi planlayın.

11) Güvenlik ve Uyumluluk: Kurumsal RAG’da erişim kontrolünü indeks katmanında uygulayın; kullanıcının yetkisi olmayan belgeler retrieval aşamasına hiç girmesin. PII maskeleme ve günlükleme (audit) politikalarını belirleyin. Oran sınırlama (rate limiting) ve anomali tespiti ile kötüye kullanımı engelleyin.

Sık Yapılan Hatalar: Çok büyük chunk boyutları kullanmak, yalnızca vektör aramaya güvenmek, re-ranker atlamak, prompt’ta kaynak gösterimi istememek ve üretim izleme metriklerini kurmamak. Ayrıca embed modeli ile arama dili uyumsuz olduğunda isabet hızla düşer; çok dilli kullanımda model seçimini A/B testleriyle doğrulayın.

Sonuç: RAG, Türkçe belgelerle çalışan soru-cevap sistemleri için pratik, ölçeklenebilir ve denetlenebilir bir çözüm sunar. Doğru chunking, iyi seçilmiş embedding, hibrit arama ve re-ranking üçlüsü; üzerine titizlikle kurgulanmış prompt ve değerlendirme yönergeleri ile birleştiğinde, hem doğruluk hem de kullanıcı güveni açısından sınıf atlatır. Küçük bir pilot ile başlayıp metrikler ışığında iteratif optimize ederek kısa sürede üretime hazır, kaynaklı ve güvenilir bir RAG çözümü elde edebilirsiniz.