İçeriğe Atla
MS Mehmet Sarı Çözüm mimarisi notları

AI Faturanı Düşürmenin 7 Yolu: 'Tokenpocalypse' Çağında Akıllı

AI servislerinin faturası kontrolden mi çıkıyor? Token maliyetlerini düşürmek için lokal LLM'ler, prompt engineering, RAG, önbellekleme ve daha fazlasını…

100%

Bugünlerde herkesin dilinde AI var; benim kendi otomasyon platformumda da operasyonel işleri kolaylaştırmak için yoğun bir şekilde AI kullanıyorum. Ancak bir süre sonra faturalar kabarmaya başlayınca, “Tokenpocalypse” denen o tatsız gerçekle yüzleştim. Büyük dil modelleri (LLM’ler) inanılmaz yetenekli olsa da, her API çağrısı ve her token bir maliyet demek. Özellikle MSP işinde, çok müşterili ortamlarda veya arka planda sürekli çalışan otomasyonlarda bu maliyetler hızla çığ gibi büyüyebilir.

Ben de bu durumu kendi sistemlerim üzerinde tecrübe edince, AI maliyetlerini düşürmek için ne gibi pratik adımlar atabileceğimi araştırmaya ve uygulamaya başladım. Bu yazıda, “Tokenpocalypse” çağında AI faturalarınızı düşürmenin yedi farklı yolunu kendi deneyimlerimden yola çıkarak anlatacağım. Amacım, size sadece teorik bilgiler vermek değil, aynı zamanda sahada işe yarayan somut stratejiler sunmak.

1. Lokal LLM’lerle Başlamak: Hassas Veri ve Maliyet Dengesi

Bulut tabanlı LLM servisleri kullanışlı olsa da, özellikle hassas verilerle çalışırken hem güvenlik hem de maliyet açısından lokal çözümleri değerlendirmek şart. Ben kendi otomasyon platformumda finansal analizler veya müşteri verileri gibi hassas içerikleri işlerken bu dengeyi hep göz önünde bulunduruyorum. Claude API gibi servisleri daha genel analizler veya kamuya açık veriler için kullanırken, kritik verileri işlemek için lokal LLM’lere yöneldim.

Lokal bir LLM çalıştırmak ilk başta biraz kurulum eforu gerektirse de, uzun vadede hem veri güvenliği hem de maliyet açısından büyük avantajlar sağlıyor. Örneğin, Ollama gibi araçlar sayesinde kendi sunucumda veya hatta güçlü bir iş istasyonumda çeşitli açık kaynaklı modelleri (Mistral, Llama 3 gibi) kolayca çalıştırabiliyorum. Bu sayede, hassas verilerin üçüncü taraf bir bulut servisine gitmesini engellerken, token başına maliyet derdim de kalmıyor. Tek maliyetim, modeli çalıştırdığım donanımın kendisi oluyor.

Lokal modelleri kullanmak, özellikle tekrarlayan, yüksek hacimli veya düşük gecikme gerektiren görevler için biçilmiş kaftan. Örneğin, aylık durum raporları oluştururken veya log analizlerinde belli kalıpları ararken, her seferinde bulut API’ye gitmek yerine lokal modelimi kullanarak maliyetimi sıfırlıyorum. Kendi sistemimde Docker Compose ile Nginx reverse proxy arkasında Ollama’yı nasıl çalıştırdığımı gösteren temsili bir yapılandırma örneği şöyle olabilir:

# docker-compose.yml
version: '3.8'
services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    # Eğer GPU kullanmak istiyorsanız:
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]
    restart: always

  nginx:
    image: nginx:latest
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - ollama
    restart: always

volumes:
  ollama_data:

Bu yapılandırma ile Ollama’yı bir Docker container’ında çalıştırıp Nginx üzerinden güvenli bir şekilde erişilebilir kılıyorum. Nginx burada sadece reverse proxy görevi görmekle kalmıyor, aynı zamanda SSL termination gibi güvenlik katmanları da sağlıyor. Bu sayede, kendi otomasyonlarım veya diğer servislerim, lokal LLM’e güvenli bir şekilde erişebiliyor.

2. Prompt Engineering Sanatı: Daha Az Token, Daha Çok İş

AI modelleriyle çalışırken, yazdığınız prompt’lar (istemler) hem çıktının kalitesini hem de tüketilen token miktarını doğrudan etkiler. Aynı görevi çok daha az token ile halletmek mümkünken, kötü yazılmış bir prompt gereksiz yere yüzlerce, hatta binlerce token harcamanıza neden olabilir. Bu durumu kendi otomasyonlarımda defalarca gözlemledim; özellikle ilk denemelerde prompt’ları çok genel yazdığımda gereksiz detaylar veya tekrarlar içeren yanıtlar alıyordum.

Prompt engineering aslında bir sanat ve zamanla gelişen bir beceri. Amacımız, modele ne istediğimizi mümkün olan en kısa, en net ve en yapılandırılmış şekilde anlatmak. Bu sadece token tasarrufu sağlamakla kalmaz, aynı zamanda modelin daha doğru ve kullanılabilir yanıtlar üretmesine de yardımcı olur. Örneğin, bir metni özetlemesini istediğimde, “Bu metni özetle” demek yerine, “Bu metni en fazla 100 kelimeyle, kritik noktaları vurgulayarak ve sadece ana fikri içerecek şekilde özetle” demek çok daha verimli sonuçlar verir.

Token tasarrufu için birkaç temel prompt engineering prensibi var:

  • Net ve Öz Olmak: Gereksiz kelimelerden, süslü ifadelerden kaçının. Doğrudan konuya girin.
  • Örnekler Vermek (Few-shot prompting): Modelden beklediğiniz çıktı formatına uygun birkaç örnek vermek, modelin beklentiyi daha iyi anlamasına ve gereksiz “düşünme” tokenlarından tasarruf etmesine yardımcı olur.
  • Kısıtlamalar Belirtmek: Çıktının uzunluğu, formatı (JSON, liste vb.) veya içermemesi gereken bilgileri net bir şekilde ifade edin.
  • Zincirleme (Chaining) Prompt’lar: Karmaşık görevleri tek bir devasa prompt yerine, daha küçük, yönetilebilir adımlara bölerek ayrı prompt’larla işlemek çoğu zaman daha verimlidir. Her adımın çıktısı, bir sonraki adımın girdisi olur.

Örneğin, bir log kaydından hata kodunu ve ilgili servis adını çıkarmak için şöyle bir prompt kullanabilirim:

Kötü Prompt:

Bu log kaydına bak ve hata kodunu ve servisi bul: "2023-10-27 14:35:01 ERROR [PaymentService] Transaction failed with code 500. User: Alice. Details: Connection timeout."

Bu prompt, modelin log kaydını tamamen anlamasını ve içinden bilgileri çıkarmasını bekler, bu da daha fazla token tüketebilir ve bazen gereksiz açıklamalara yol açabilir.

İyi Prompt:

Aşağıdaki log kaydından `ERROR` seviyesindeki hata kodunu ve hata mesajını oluşturan servis adını JSON formatında çıkar.
Log: "2023-10-27 14:35:01 ERROR [PaymentService] Transaction failed with code 500. User: Alice. Details: Connection timeout."
Format: {"error_code": "...", "service_name": "..."}

Bu prompt, hem çıktının formatını belirtiyor hem de modeli doğrudan istediğimiz bilgiye yönlendiriyor. Modelin ek açıklamalar yapmasını engelleyerek token kullanımını optimize ediyor.

3. RAG (Retrieval-Augmented Generation) ile Context Penceresini Daraltmak

Büyük dil modellerinin en büyük maliyet kalemlerinden biri, context penceresine (bağlam penceresi) eklediğimiz metin miktarıdır. Bir modele ne kadar fazla bilgi verirsek, o kadar çok token kullanırız ve faturamız o kadar artar. Özellikle uzun belgeler, kapsamlı log kayıtları veya geniş bilgi tabanları üzerinde sorgulama yapmamız gerektiğinde bu durum ciddi bir sorun haline gelir. İşte tam burada Retrieval-Augmented Generation (RAG) devreye giriyor.

RAG, modelin yanıtını oluşturmadan önce, harici bir bilgi tabanından (dokümanlar, veritabanları, web sayfaları vb.) ilgili bilgileri “çekip” almasını ve bu bilgileri prompt’a ekleyerek modelin context’ini zenginleştirmesini sağlayan bir yaklaşımdır. Benim kendi otomasyon platformumda, özellikle MSP müşterilerimin spesifik konfigürasyonları, sıkça sorulan sorular veya geçmiş problem çözümleri gibi bilgilere hızlıca erişmek ve bu bilgileri kullanarak otomatik yanıtlar veya triyaj önerileri üretmek için RAG’i yoğun olarak kullanıyorum.

RAG’in temel mantığı, modelin “her şeyi bilmesi” beklentisinden vazgeçmek ve ona sadece o an için gerekli olan, önceden taranmış ve indekslenmiş bilgiyi sunmaktır. Bu sayede, modelin context penceresine sadece birkaç yüz veya bin tokenlık alakalı bilgi göndererek, on binlerce tokenlık bir dokümanı göndermekten çok daha fazla tasarruf edebiliriz.

Basit bir RAG akışı şu adımlardan oluşur:

  1. Doküman Yükleme ve Parçalama (Chunking): Bilgi tabanınızdaki dokümanları (PDF, metin dosyası, HTML vb.) küçük, anlamlı parçalara ayırın.
  2. Embedding Oluşturma: Her bir doküman parçası için bir embedding (vektör temsili) oluşturun. Bu vektörler, metnin anlamsal içeriğini matematiksel olarak temsil eder.
  3. Vektör Veritabanına Kaydetme: Bu embedding’leri (ve orijinal metin parçalarını), hızlı arama yapmaya imkan tanıyan bir vektör veritabanına (örneğin Qdrant, Chroma, Pinecone) kaydedin.
  4. Sorgu Embedding’i Oluşturma: Kullanıcının sorusu geldiğinde, bu sorunun da bir embedding’ini oluşturun.
  5. Benzerlik Araması: Sorgu embedding’ini kullanarak vektör veritabanında en benzer doküman parçalarını bulun.
  6. Prompt Oluşturma: Bulunan ilgili doküman parçalarını alıp, kullanıcının orijinal sorusuyla birlikte LLM’e gönderilecek prompt’un içine yerleştirin.
  7. Yanıt Oluşturma: LLM, kendisine sunulan bu daraltılmış ve alakalı context’i kullanarak yanıtı oluşturur.

Bu yaklaşım, özellikle karmaşık ve geniş bilgi tabanlarına sahip KOBİ’ler için hem maliyet hem de doğruluk açısından ciddi avantajlar sunuyor. Örneğin, bir IT destek talebini otomatikleştirmek istediğimde, kullanıcının sorununu alıp, öncelikle geçmiş çözümler, ürün kılavuzları ve sıkça sorulan sorular veri tabanımda RAG ile arama yapıyorum. Ardından, bulunan en alakalı parçaları Claude API’ye veya lokal LLM’e göndererek, soruna özel ve doğru bir yanıt alıyorum. Böylece modelin her seferinde tüm dokümantasyonu “okumasına” gerek kalmıyor.

4. Akıllı Önbellekleme (Caching): Tekrar Eden İşlerde Altın Kural

AI servislerini kullanırken faturayı en çok şişiren durumlardan biri, aynı veya benzer sorguların defalarca tekrarlanmasıdır. Özellikle benim gibi MSP operasyonlarında, belirli tipteki alert triyajları, standart rapor özetleri veya sıkça sorulan sorulara verilen yanıtlar gibi görevler zaman zaman aynı girdilerle tekrar karşımıza çıkabiliyor. Her seferinde LLM API’sine gitmek yerine, önbellekleme (caching) mekanizmalarını devreye sokarak ciddi maliyet tasarrufu sağlayabiliriz.

Önbellekleme, bir sorguya verilen yanıtı bir sonraki aynı sorgu için saklamak anlamına gelir. Eğer aynı sorgu tekrar gelirse, LLM’e gitmek yerine önbellekten hazır yanıtı alıp döndürürüz. Bu, hem maliyeti sıfırlar hem de yanıt süresini önemli ölçüde hızlandırır. Tabii ki, önbellekleme her senaryo için uygun değil. Yanıtın dinamik olması gereken veya sürekli değişen bilgileri içeren durumlarda önbellekleme riskli olabilir. Ancak statik veya yavaş değişen bilgiler için altın değerinde bir stratejidir.

Önbellekleme stratejisi tasarlarken dikkat etmemiz gereken birkaç nokta var:

  • Anahtar Oluşturma: Her sorgu için benzersiz bir önbellek anahtarı oluşturmalıyız. Bu anahtar genellikle prompt’un kendisinden veya prompt’un kriptografik bir hash’inden (örneğin SHA256) türetilir.
  • TTL (Time-To-Live): Önbellekteki bir yanıtın ne kadar süreyle geçerli olacağını belirlemeliyiz. Çok kısa bir TTL, önbelleklemenin faydasını azaltırken, çok uzun bir TTL eski verilerin sunulmasına neden olabilir. Kullanım senaryosuna göre bu süreyi iyi ayarlamak gerekiyor.
  • İptal Mekanizmaları: Eğer bir bilginin değiştiğini biliyorsak, ilgili önbellek girdisini manuel olarak iptal etme (invalidate) mekanizmalarına sahip olmak önemlidir.
  • Depolama Alanı: Önbelleğin ne kadar büyük olabileceği ve ne kadar depolama alanı tüketeceği de göz önünde bulundurulmalıdır.

Basit bir Python örneğiyle Redis tabanlı bir önbellekleme mekanizması şöyle tasarlanabilir:

import redis
import hashlib
import json
from datetime import timedelta

# Redis bağlantısı
r = redis.Redis(host='localhost', port=6379, db=0)

def generate_cache_key(prompt_text, model_name="gpt-3.5-turbo"):
    """Prompt ve model adına göre benzersiz bir cache anahtarı oluşturur."""
    unique_string = f"{model_name}:{prompt_text}"
    return hashlib.sha256(unique_string.encode('utf-8')).hexdigest()

def get_llm_response_cached(prompt_text, llm_api_call_function, cache_ttl_seconds=3600):
    cache_key = generate_cache_key(prompt_text)
    
    # Önbellekte var mı kontrol et
    cached_response = r.get(cache_key)
    if cached_response:
        print("Önbellekten yanıt alınıyor...")
        return json.loads(cached_response)
    
    # Yoksa, LLM API'sini çağır
    print("LLM API'si çağrılıyor...")
    response = llm_api_call_function(prompt_text) # Gerçek API çağrısı
    
    # Yanıtı önbelleğe kaydet
    r.setex(cache_key, timedelta(seconds=cache_ttl_seconds), json.dumps(response))
    return response

# Temsili bir LLM API çağrısı fonksiyonu
def mock_llm_api_call(prompt):
    import time
    time.sleep(2) # API gecikmesini simüle et
    return {"text": f"Bu, '{prompt}' için LLM'den gelen bir yanıttır."}

# Kullanım örneği
prompt1 = "Bursa'daki hava durumu nasıl?"
prompt2 = "Bursa'daki hava durumu nasıl?" # Aynı prompt
prompt3 = "İstanbul'daki hava durumu nasıl?"

print(get_llm_response_cached(prompt1, mock_llm_api_call))
print(get_llm_response_cached(prompt2, mock_llm_api_call)) # Önbellekten gelecek
print(get_llm_response_cached(prompt3, mock_llm_api_call))

Bu örnekte, get_llm_response_cached fonksiyonu, önce Redis’te önbellek anahtarını kontrol ediyor. Eğer yanıt varsa onu döndürüyor, yoksa LLM API’sini çağırıp yanıtı önbelleğe alıyor. Bu basit mekanizma bile, belirli sorgu türlerinde AI faturamı önemli ölçüde düşürmeme yardımcı oldu. Özellikle MSP operasyonlarında sıkça rastladığımız “Bu hata kodunun anlamı nedir?” veya “Şu cihazın standart konfigürasyonu nasıldı?” gibi sorgular için birebir.

5. Doğru Modeli Doğru İşe Koşmak: Fiyat/Performans Dengesi

AI modelleri dünyası çok geniş; küçük, hızlı ve uygun fiyatlı modellerden, devasa, yetenekli ama pahalı modellere kadar birçok seçenek var. Benim kendi otomasyon platformumda ve MSP işlerimde, her zaman en büyük ve en yetenekli modeli kullanmak yerine, görevin gerektirdiği en uygun modeli seçmeye özen gösteriyorum. Bu, doğrudan maliyetleri etkileyen kritik bir karardır.

Örneğin, basit bir metin sınıflandırma veya anahtar kelime çıkarma görevi için GPT-4 Turbo gibi üst düzey bir model kullanmak, çoğu zaman gereksiz bir maliyettir. Bunun yerine, GPT-3.5 Turbo gibi daha uygun fiyatlı bir model veya hatta lokalde çalışan Mistral gibi açık kaynaklı bir model aynı işi fazlasıyla görecektir. Benim tercihim, genel analizler veya daha yaratıcı metin üretimi gerektiren durumlar için Claude API’yi (özellikle Claude 3 Haiku gibi daha uygun fiyatlı versiyonlarını) kullanırken, daha yapısal ve tekrarlayan işlerde lokal Ollama modellerimi devreye sokmak oluyor.

Model seçimi yaparken şu faktörleri göz önünde bulunduruyorum:

  • Görevin Karmaşıklığı: Görev ne kadar karmaşık? Yaratıcılık, ince nüansları anlama veya çok adımlı mantık yürütme gerektiriyor mu? Basit özetleme veya veri çıkarma mı?
  • Hassasiyet ve Doğruluk İhtiyacı: Yanıtın ne kadar doğru ve hassas olması gerekiyor? Yanlış bir yanıtın potansiyel maliyeti nedir?
  • Gecikme (Latency) Gereksinimi: Yanıtın ne kadar hızlı gelmesi gerekiyor? Kullanıcı etkileşimli bir uygulama mı, yoksa arka planda çalışan bir batch işi mi?
  • Maliyet Kısıtlamaları: Bütçeniz ne kadar? Token başına maliyetler, farklı modeller arasında ciddi farklılıklar gösterebilir.

Aşağıdaki tablo, temsili model maliyet farklarını gösteriyor (gerçek rakamlar API sağlayıcısına ve döviz kuruna göre değişir):

Model Giriş Token Maliyeti (1K token) Çıkış Token Maliyeti (1K token) Tipik Kullanım Alanı
GPT-4 Turbo ~$0.01 ~$0.03 Kompleks analiz, yaratıcı yazım, kod üretimi
GPT-3.5 Turbo ~$0.0005 ~$0.0015 Özetleme, sınıflandırma, sohbet botları
Claude 3 Haiku ~$0.00025 ~$0.00125 Hızlı özet, hafif sohbet, veri çıkarma
Mistral/Llama 3 Lokal (Donanım maliyeti) Lokal (Donanım maliyeti) Hassas veri işleme, tekrar eden basit görevler

Bu tabloya bakarak, örneğin bir metni sadece özetleyeceksem GPT-4 Turbo kullanmak yerine Claude 3 Haiku veya GPT-3.5 Turbo’ya yönelirim. Hassas verilerle çalışırken ise, kendi sunucumdaki Mistral modelini tercih ederim. Bu bilinçli seçimler, AI faturamda önemli düşüşler sağlıyor.

6. Çıktı Kontrolü ve Gerekli Detayı Yakalamak

AI modellerinden gelen yanıtların uzunluğu, doğrudan tüketilen token miktarını etkiler. Bazen model, istediğimizden çok daha fazla bilgi veya gereksiz detaylar içeren yanıtlar üretebilir. Bu durum, hem maliyeti artırır hem de gelen veriyi işleme süremizi uzatır. Bu yüzden, AI’dan gelen çıktıları kontrol etmek ve sadece ihtiyacımız olan bilgiyi almasını sağlamak, maliyet optimizasyonunda önemli bir adımdır.

Bu noktada prompt engineering’in “kısıtlamalar belirtme” ilkesi devreye giriyor. Modelden beklediğimiz çıktının formatını, uzunluğunu ve içermesi gereken anahtar bilgileri net bir şekilde belirterek, gereksiz token tüketimini engelleyebiliriz. Benim kendi otomasyon platformumda, özellikle rapor özetleri veya teknik analizler yaparken bu konuya çok dikkat ediyorum. Örneğin, bir log analizinden belirli hata kodlarını çıkarmasını istediğimde, modelin her bir hata kodu için uzun açıklamalar yapmasını değil, sadece hata kodu ve ilgili servis adını JSON formatında vermesini beklerim.

Modelden çıktı kontrolü için kullanabileceğim bazı stratejiler:

  • Maksimum Kelime/Token Sınırı Belirleme: Prompt’un içinde modelden “en fazla X kelime/token ile yanıtla” gibi bir kısıtlama isteyin.
  • Spesifik Format Belirtme: JSON, liste, madde işaretli liste gibi belirli bir çıktı formatı talep edin. Bu, modelin format dışı metinler üretmesini engeller.
  • Sadece Gerekli Bilgiyi İsteme: Modelden “sadece X, Y ve Z bilgisini ver” şeklinde net talimatlar verin. Ek açıklamalardan kaçınmasını isteyin.
  • Çıktıyı Sonradan İşleme: Eğer model hala gereksiz detaylar üretiyorsa,
Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

MS

Mehmet Sarı

Çözüm Mimarı & IT Altyapı Uzmanı (MSP)

Çözüm mimarisi, network, sunucu altyapıları, yedekleme, storage, güvenlik ve MSP operasyonu ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Haftalık özet — AI değil, bizzat ben seçiyorum

Haftada bir mail: o haftanın en önemli yazısı, perde arkası notları, ve "bu hafta gerçekten kullandığım araç" bölümü. Az gürültü, çok sinyal.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar