Laravel ile OpenAI API Entegrasyonu

Google News Google News Flipboard Flipboard Sesli oku Yazıyı beğen Favorilere Ekle 0 Yorumlar
Daha fazla
Laravel projelerinde OpenAI API entegrasyonu son bir yılda neredeyse standart bir gereksinim haline geldi. İçerik üretimi, müşteri destek botları, otomatik etiketleme, e-posta cevap taslakları ve çeviri gibi senaryoların hepsi aynı çekirdek üzerine kuruluyor: HTTP istemcisi, prompt yönetimi, hata kontrolü ve maliyet kısıtı. Bu rehber, sıfırdan bir Laravel uygulamasına OpenAI’ı bağlamak ve üretim ortamında sürdürülebilir hale getirmek için ihtiyacınız olan adımları derliyor. Önce paket seçimini ve env hazırlığını, sonra servis katmanını, ardından yaygın hata senaryolarını ve maliyet kontrolünü ele alıyoruz. Kod örnekleri Laravel 10/11 üzerinde çalışacak şekilde hazırlandı.

Laravel OpenAI API entegrasyonu: Laravel ile OpenAI API Entegrasyonu Neden Bu Kadar Yaygınlaştı?

Laravel OpenAI API entegrasyonu: Laravel ile OpenAI API Entegrasyonu Neden Bu Kadar Yaygınla
Laravel OpenAI API entegrasyonu: Laravel ile OpenAI API Entegrasyonu Neden Bu Kadar Yaygınla
Pratikte iki temel ihtiyaç var: hızlı prototip ve düşük operasyonel yük. Laravel’in service container’ı, queue altyapısı ve config yönetimi, OpenAI gibi rate limit’i ve maliyeti olan harici servisleri yönetmek için uygun bir temel sağlıyor. Tipik kullanım senaryoları:
  • WordPress veya headless bir CMS’ten gelen içerikleri özetleme.
  • Form girişlerinden otomatik e-posta taslağı üretme.
  • Ürün açıklamalarını çoklu dile çevirme.
  • Kullanıcı destek mesajlarını sınıflandırma.
  • E-ticaret aramasında semantic search için embedding üretimi.
Bu senaryoların ortak noktası, OpenAI’a istek atmanın aslında problemin %20’si olması. Geri kalanı; hatayı, maliyeti, gecikmeyi ve loglamayı disiplinli yönetmektir. Aşağıdaki bölümler bu disiplini somut adımlara çeviriyor.

Kurulum Öncesi Hazırlık

Entegrasyona başlamadan önce şu kontrolleri yapın:
  1. OpenAI hesabınızda billing aktif mi? Trial limiti bittiyse API 429 dönmeye başlar.
  2. Hangi modeli kullanacaksınız? gpt-4o-minigpt-4ogpt-4.1gpt-3.5-turbo arasında maliyet ve hız farkı belirgindir.
  3. API anahtarı yalnızca .env içinde saklanmalı. Repoya commit edilmiş bir anahtar varsa hemen revoke edin.
  4. Laravel sürümünüz 10 veya üzeri mi? php artisan --version ile doğrulayın.
  5. PHP 8.1+ olmalı; openai-php paketinin minimum gereksinimi budur.
.env dosyanıza şu değişkenleri ekleyin:
OPENAI_API_KEY=sk-...
OPENAI_ORGANIZATION=
OPENAI_DEFAULT_MODEL=gpt-4o-mini
OPENAI_REQUEST_TIMEOUT=30
config/services.php dosyasında ilgili bölümü tanımlamak, anahtara doğrudan env() çağrısı yapmaktan daha güvenlidir. Üretimde config:cache çalıştırıldığında runtime’da env() boş döner; config dosyası bu sorunu engeller.
'openai' => [
    'key' => env('OPENAI_API_KEY'),
    'organization' => env('OPENAI_ORGANIZATION'),
    'default_model' => env('OPENAI_DEFAULT_MODEL', 'gpt-4o-mini'),
    'timeout' => (int) env('OPENAI_REQUEST_TIMEOUT', 30),
],

openai-php/laravel Paketini Kurmak ve Yapılandırmak

openai-php/laravel Paketini Kurmak ve Yapılandırmak
openai-php/laravel Paketini Kurmak ve Yapılandırmak
İki yaygın yol var: openai-php/laravel paketi veya Laravel HTTP Client ile doğrudan istek. Üretim ortamı için resmi maintain edilen paket genellikle daha sürdürülebilir, çünkü tipli response objeleri ve hata sınıfları hazır gelir.

Composer ile kurulum

composer require openai-php/laravel
php artisan vendor:publish --provider="OpenAI\Laravel\ServiceProvider"
Bu komut config/openai.php dosyasını oluşturur. Dosyayı açıp şu satırı kontrol edin:
'api_key' => env('OPENAI_API_KEY'),
Paket facade olarak OpenAI sınıfını sağlar. Aynı zamanda OpenAI\Contracts\ClientContract arayüzünü service container üzerinden constructor injection ile alabilirsiniz. Bağımlılık enjeksiyonu test edilebilirlik açısından facade kullanmaktan daha temizdir; PHPUnit testlerinde client’i mock’lamak basitleşir.

Bağlantı testi

Hızlı bir tinker testi entegrasyonun çalıştığını doğrular:
php artisan tinker
>>> OpenAI::chat()->create([
...     'model' => 'gpt-4o-mini',
...     'messages' => [['role' => 'user', 'content' => 'Merhaba']],
... ]);
Cevap geliyorsa altyapı hazır. 401 dönerse anahtar yanlış, 429 dönerse kota veya rate limit problemi vardır. Bu testi staging ortamında da çalıştırmak deploy sonrası env yükleme sorunlarını erken yakalar.

İlk Servis Sınıfı: Chat Completion Örneği

Controller içinde doğrudan OpenAI çağırmak hızlı görünür ama uzun vadede bakım sorunu yaratır. Prompt değişikliği için her seferinde controller’a dokunmak istemezsiniz. Servis sınıfı pattern’i bu yüzden önerilir.
<?php

namespace App\Services\AI;

use OpenAI\Contracts\ClientContract;

class OpenAiChatService
{
    public function __construct(private ClientContract $client)
    {
    }

    public function summarize(string $text, int $maxTokens = 300): string
    {
        $response = $this->client->chat()->create([
            'model' => config('services.openai.default_model'),
            'messages' => [
                ['role' => 'system', 'content' => 'Türkçe, kısa ve net özet üret.'],
                ['role' => 'user', 'content' => $text],
            ],
            'temperature' => 0.4,
            'max_tokens' => $maxTokens,
        ]);

        return $response->choices[0]->message->content ?? '';
    }
}
Bu yapı üç avantaj sağlar: controller ince kalır, test ederken ClientContract mock’lanabilir ve prompt değişiklikleri tek dosyada toplanır. Birden fazla görev (özet, sınıflandırma, çeviri) varsa her biri için ayrı servis sınıfı yerine OpenAiChatService içinde public metotlar tutmak makul; ama servis büyürse SummaryServiceClassificationService gibi alt sınıflara bölmek bakımı kolaylaştırır.

Hata Yönetimi ve Yeniden Deneme Mantığı

Hata Yönetimi ve Yeniden Deneme Mantığı
Hata Yönetimi ve Yeniden Deneme Mantığı
OpenAI çağrılarında en sık karşılaşılan hatalar şunlardır:
  • 401 Unauthorized: Anahtar yanlış veya iptal edilmiş.
  • 429 Too Many Requests: Rate limit veya kota bitmiş.
  • 500 / 502 / 503: Geçici sunucu problemi.
  • 400 invalid_request_error: Genelde prompt çok uzun veya parametre yanlış.
Yeniden deneme yalnızca geçici hatalar için anlamlıdır. 401 veya 400 hatalarında retry yapmak gereksiz maliyet yaratır ve aynı sonucu döndürür.
public function summarizeWithRetry(string $text, int $maxAttempts = 3): string
{
    $attempt = 0;

    while (true) {
        try {
            return $this->summarize($text);
        } catch (\OpenAI\Exceptions\ErrorException $e) {
            $attempt++;
            $status = $e->getCode();
            $isRetryable = in_array($status, [429, 500, 502, 503], true);

            if (! $isRetryable || $attempt >= $maxAttempts) {
                throw $e;
            }

            // Üstel geri çekilme: 2, 4, 8 saniye
            sleep(2 ** $attempt);
        }
    }
}
Üretim senaryosunda bu mantığı bir Laravel queue job içinde çalıştırmak daha sağlıklıdır. HTTP request thread’inde 30+ saniye beklemek yerine kullanıcıya bir iş ID’si dönülür ve sonuç hazır olduğunda WebSocket, e-posta veya UI polling ile bildirilir.

Maliyet Kontrolü, Token Limiti ve Loglama

OpenAI maliyeti girdi tokenları ve çıktı tokenları üzerinden hesaplanır. Aşağıdaki tablo yaygın modellerin tipik kullanım yerlerini özetler. Birim fiyatlar zamanla değiştiği için kesin rakamlar için yayından önce OpenAI fiyatlandırma sayfasını kontrol edin.
Model Tipik Kullanım Yaklaşık Hız Maliyet Profili
gpt-4o-mini Özetleme, sınıflandırma, kısa cevaplar Hızlı Düşük
gpt-4o Karmaşık akıl yürütme, çok adımlı görevler Orta Orta-yüksek
gpt-4.1 Uzun bağlam, kod üretimi Orta Yüksek
text-embedding-3-small Semantic search, vektör DB Çok hızlı Çok düşük
Maliyet kontrol listesi:
  • Her serviste max_tokens mutlaka set edilmeli; aksi halde model bazen gereksiz uzun cevap üretir.
  • Prompt template’lerinde tekrar eden açıklamalar olmamalı.
  • Aynı girdi için cache: aynı metni iki kez özetlemeye göndermeyin. Redis veya database cache uygundur.
  • Kullanıcı başına günlük token limiti tanımlayın.
  • Her istek loglansın: model, input_tokens, output_tokens, latency, kullanıcı ID.
Basit bir log örneği:
\Log::channel('openai')->info('chat_completion', [
    'user_id' => $userId,
    'model' => $response->model,
    'prompt_tokens' => $response->usage->promptTokens,
    'completion_tokens' => $response->usage->completionTokens,
    'total_tokens' => $response->usage->totalTokens,
    'latency_ms' => $latencyMs,
]);
config/logging.php içinde ayrı bir kanal tanımlamak bu kayıtların ana log’la karışmasını engeller ve aylık maliyet analizi için kolayca grep’lenebilir/Loki sorgulanabilir hale getirir.

Güvenlik ve Yayın Öncesi Kontrol Listesi

Üretime almadan önce şu maddeleri tek tek doğrulayın:
  • .env dosyası repoda değil, .env.example içinde anahtar yok.
  • API anahtarı sadece backend tarafında; frontend’e asla gönderilmiyor.
  • Kullanıcı girdileri prompt’a eklenmeden önce uzunluk kontrolü ve sanitization yapılıyor.
  • Rate limit middleware ile kullanıcı başına dakika/saat tavanı belirlendi.
  • Hassas içerik (PII) prompt’a girmeden önce filtreleniyor veya rıza alınıyor.
  • Hata mesajları kullanıcıya try/catch ile sade gösteriliyor, raw exception sızdırılmıyor.
  • Production’da queue altyapısı çalışıyor; uzun istekler senkron tutulmuyor.
  • OpenAI dashboard’da Usage limit alarmı kuruldu.
  • Staging ortamında ayrı bir API anahtarı kullanılıyor.

Yaygın Hatalar ve Çözüm Adımları

Hata: curl error 28: Operation timed out Tipik nedeni paylaşımlı hosting veya yetersiz timeout. OPENAI_REQUEST_TIMEOUT değerini 30-60 saniyeye çıkarın. Uzun yanıtlar için işi queue’ya alın. Hata: context_length_exceeded Prompt + beklenen yanıt modelin context window’unu aşmış. Önce input metni özetleyin, sonra ikinci bir çağrıda detay isteyin. gpt-4o-mini için ~128k token üst sınırını dikkate alın; ama büyük input pratik olarak hâlâ pahalı olduğu için chunk’lama stratejisi tercih edilir. Hata: JSON parse hatası Modelden JSON istediğinizde model bazen açıklayıcı metin ekler. Çözüm: response_format: ['type' => 'json_object'] parametresini kullanın ve system prompt’ta net biçimde “Sadece geçerli JSON döndür, başka metin ekleme” deyin. Hata: Cevaplar tutarsız temperature değerini düşürün (0.2-0.4). Deterministik çıktı isteniyorsa 0 yapın. seed parametresi de tutarlılığı artırır ama tam deterministik garantisi vermez; sürüm değişiklikleri seed davranışını etkileyebilir.

Sonuç

Laravel ile OpenAI API entegrasyonu, doğru servis katmanı ve hata yönetimi ile küçük bir prototipten üretim sistemine evrilebilir. Anahtarı .env‘de saklamak, çağrıları servis sınıfı içinde tutmak, queue ve loglama ile gözlemlenebilir hale getirmek ilk üç adımdır. Sonraki adımlarda function calling, streaming cevaplar ve embedding tabanlı semantic search gibi konulara geçebilirsiniz.

Sıkça Sorulan Sorular

1. Laravel hangi sürümünden itibaren openai-php/laravel paketini destekler?

Resmi paket Laravel 9, 10 ve 11 sürümlerini destekler. PHP 8.1 ve üzeri minimum gereksinimdir. Daha eski Laravel projelerinde paketin sürümü doğrudan kurulmayabilir; bu durumda Guzzle veya Laravel HTTP Client ile manuel istek atmak daha sağlıklıdır.

2. OpenAI API maliyetini nasıl kontrol altında tutarım?

Her isteğe max_tokens limiti koyun, aynı girdiler için cache kullanın, uygun olduğunda gpt-4o-mini gibi düşük maliyetli modelleri tercih edin ve OpenAI dashboard’da kullanım limiti tanımlayın. İstek başına token kullanımını loglamak maliyet anomalilerini erken yakalamanızı sağlar; örneğin bir kullanıcının tek başına aylık ortalamanın 20 katı token tüketmesi loglardan hemen görülür.

3. API çağrısı çok yavaş, optimize etmek için ne yapmalıyım?

İlk adım senkron çağrıları queue job’a taşımak. Daha küçük modele geçiş, daha kısa system prompt, paralel istek (concurrent HTTP) ve streaming kullanımı tipik optimizasyon adımlarıdır. Yavaşlığın istemci tarafından mı yoksa API’dan mı kaynaklandığını ayırt etmek için her isteğin başlangıç ve bitiş zamanını loglayın; toplam süre içindeki ağ bekleme oranı ipucu verir.

4. Kullanıcıya streaming cevap göstermek için ne gerekir?

chat()->createStreamed() metodu cevap parçalarını chunk olarak verir. Frontend tarafında Server-Sent Events veya WebSocket üzerinden bu chunk’lar kullanıcıya iletilir. Laravel Echo + Reverb veya Pusher kombinasyonu pratik bir kurulum sağlar. Streaming kullanırken çıkış sansürü/sanitization da chunk bazında yapılmalı.

5. API anahtarı sızdı, ne yapmalıyım?

İlk adım OpenAI dashboard’dan ilgili anahtarı hemen revoke etmek. Sonra yeni bir anahtar oluşturup .env‘i güncelleyin ve php artisan config:cache komutunu yeniden çalıştırın. Eski anahtarın geçtiği commit varsa git geçmişinde de temizleyin (BFG Repo-Cleaner veya git filter-repo); aksi halde repo public olduğunda yine taranabilir hale gelir.

Laravel OpenAI API entegrasyonu için pratik kontrol listesi

Laravel OpenAI API entegrasyonu konusunda uygulamaya geçmeden önce mevcut yedeği doğrulayın, değişikliği küçük adımlarla test edin ve sonucu canlı sitede tekrar kontrol edin. Benzer konular için Laravel shared hosting ve Gemini API model hatası rehberlerine de bakabilirsiniz. Resmi kaynak olarak OpenAI API dokümantasyonu sayfasını incelemek faydalı olur.

SSS: Laravel ile OpenAI API Entegrasyonu

Laravel ile OpenAI API Entegrasyonu için ilk kontrol ne olmalı?
Önce sorunun kapsamını belirleyin. Sadece tek sayfada mı, tüm sitede mi, yoksa belirli kullanıcı veya cihazlarda mı göründüğünü kontrol edin.

Bu işlem SEO performansını etkiler mi?
Evet, teknik sorunlar kullanıcı deneyimini ve tarama kalitesini etkileyebilir. Bu nedenle değişiklikten sonra Search Console verilerini takip etmek gerekir.

Canlı sitede işlem yapmadan önce yedek almak gerekir mi?
Kesinlikle gerekir. Dosya ve veritabanı yedeği olmadan yapılan canlı değişiklikler, küçük bir hatada geri dönüşü zorlaştırabilir.

Değişiklikten sonra cache temizlemek şart mı?
Çoğu durumda evet. WordPress cache eklentisi, CDN ve tarayıcı cache’i eski çıktıyı göstermeye devam edebilir.

Sorun devam ederse nasıl ilerlemeliyim?
Son yapılan değişikliği geri alın, hata loglarını kontrol edin ve eklenti/tema çakışmasını izole edin. Gerekirse küçük adımlarla yeniden test edin.

Yazar Hakkında

Benzer Yazılar

Bir Cevap Yaz

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

0/30 karakter