# LLM sağlayıcısını (Ollama → Bedrock/OpenAI) nasıl soyutlamalıyım?

> Tek bir dar arayüz (complete(prompt, opts)) ve config ile seçilen üç implementasyon kurun; context penceresi, gecikme ve maliyeti config olarak taşıyın.

- Soruldu: 2026-05-03
- Yanıtlandı: 2026-05-06
- Soran: Deniz
- Etiketler: mimari
- Kaynak: https://muhammetsafak.com/tr/sor-bakalim/ollama-dan-uretimde-bedrock-openai-a-gecerken-llm-soyutlamasi/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** Uygulamaya kod analizi ve metin özetleme yapan bir AI özelliği ekliyoruz. Geliştirici makinelerinde maliyet olmasın diye Ollama + yerel LLM (Llama 3) kullanıyoruz; üretimde AWS Bedrock veya OpenAI planlıyoruz.

LLM sağlayıcısını soyutlamak için hangi tasarım kalıbını uygulamalıyım? Lokaldeki token sınırları ve yanıt süreleriyle üretimdeki yapısal farkları mimaride nasıl tolere ederim?


Kısa cevap: Sağlayıcının etrafına değil, **yeteneğin** etrafına dar bir port/adapter (Strategy) kurun. Küçük bir arayüz + config'le seçilen gerçek implementasyonlar; daha fazlası değil.

## Kısa cevap

Sizin asıl tehlikeniz aşırı soyutlama: insanlar bunu jenerik bir "AI framework"e çevirmeye çalışıp aylarını yiyor. İhtiyacınız olan tek bir ince arayüz. Laravel tarafında bu arayüzün hangi implementasyona bağlanacağını seçen mekanizma zaten elinizde — [servis sağlayıcı ve container yazısında](/tr/blog/laravelde-servis-saglayici-ve-containeri-dogru-kullanmak/) anlattığım binding tam olarak bu iş içindir.

## Neden

1. **Vendor'ı değil yeteneği soyutlamak arayüzü küçük tutar.** `complete(prompt, opts): Result` gibi minik bir kontrat yeter; Ollama, Bedrock ve OpenAI bunun üç implementasyonu olur. Sağlayıcıya özel parametreleri core mantığa sızdırdığınız anda soyutlama işlevini kaybeder.

2. **Farklar iş mantığında değil konfigürasyonda yaşamalı.** "Lokalde küçük, üretimde büyük context penceresi" gibi ayrımlar `if` bloğuna dönüşürse, her yeni sağlayıcı kod tabanına yeni bir dallanma ekler.

## Ne yapmalı

1. **Arayüzü yetenek üzerinden tanımlayıp seçimi config'e bırakın.** Hangi implementasyonun çalışacağını `config`/`env` seçsin; çağıran taraf hangi sağlayıcıyla konuştuğunu bilmesin.

2. **Açık timeout + ucuz fallback koyun.** Üretimde sağlayıcı yavaşlar veya rate-limit yer; her çağrıya net bir timeout verin ve gerektiğinde ucuz/yerel bir fallback'e düşün.

3. **Token bütçesini kenarda yönetin.** Her modelin context penceresi farklı; girdiyi modele sığacak şekilde kenarda truncate/özetleyin.

4. **Streaming'i aynı kontratın arkasına koyun.** İhtiyaç varsa opsiyonel olarak aynı arayüzde tutun; çağıran taraf sağlayıcının stream API'sını bilmesin.

5. **Golden-prompt test seti tutun.** Aynı prompt setini her sağlayıcıya karşı çalıştırın; sağlayıcı değiştirdiğinizde neyin bozulduğunu bu yakalar.

**Sonuç:** Ben olsam tek bir küçük arayüz, üç gerçek implementasyon ve config-tabanlı seçim kurardım — fazlası YAGNI. Yerel Ollama dev maliyeti ve hızlı iterasyon içindir; üretimdeki context penceresi, gecikme, rate-limit ve maliyet farklarını **konfigürasyon** olarak ele alın, iş mantığına dallanma olarak değil. Soyutlama dar oldukça sağlam olur.

## İlgili Yazılar

- [AI-Assisted Engineering Workflow'um](https://sade.dev/tr/journal/ai-assisted-engineering-workflow) — sade.dev
- [Gitflow'dan Trunk-Based'e geçerken feature flag mimarisini nasıl konumlandırırım?](https://muhammetsafak.com/tr/sor-bakalim/gitflow-mu-trunk-based-mi-ve-feature-flag-mimarisi/) — Sor Bakalım
- [CQRS'i ne zaman uygulamalı ve okuma/yazma modellerini nasıl senkronlamalıyım?](https://muhammetsafak.com/tr/sor-bakalim/cqrs-ne-zaman-uygulanir-ve-okuma-yazma-senkronizasyonu/) — Sor Bakalım
- [Esnek ürün nitelikleri için NoSQL mu, PostgreSQL mi seçmeliyim?](https://muhammetsafak.com/tr/sor-bakalim/esnek-urun-nitelikleri-icin-nosql-mu-postgresql-mi/) — Sor Bakalım
