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

- 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.
Kurulum Öncesi Hazırlık
Entegrasyona başlamadan önce şu kontrolleri yapın:- OpenAI hesabınızda billing aktif mi? Trial limiti bittiyse API 429 dönmeye başlar.
- Hangi modeli kullanacaksınız?
gpt-4o-mini,gpt-4o,gpt-4.1,gpt-3.5-turboarasında maliyet ve hız farkı belirgindir. - API anahtarı yalnızca
.enviçinde saklanmalı. Repoya commit edilmiş bir anahtar varsa hemen revoke edin. - Laravel sürümünüz 10 veya üzeri mi?
php artisan --versionile doğrulayın. - 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 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 SummaryService, ClassificationService gibi alt sınıflara bölmek bakımı kolaylaştırır.
Hata Yönetimi ve Yeniden Deneme Mantığı

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ış.
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 |
- Her serviste
max_tokensmutlaka 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.
\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:.envdosyası repoda değil,.env.exampleiç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/catchile 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ğemax_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.
- Laravel OpenAI API entegrasyonu: Laravel ile OpenAI API Entegrasyonu Neden Bu Kadar Yaygınlaştı?
- Kurulum Öncesi Hazırlık
- openai-php/laravel Paketini Kurmak ve Yapılandırmak
- İlk Servis Sınıfı: Chat Completion Örneği
- Hata Yönetimi ve Yeniden Deneme Mantığı
- Maliyet Kontrolü, Token Limiti ve Loglama
- Güvenlik ve Yayın Öncesi Kontrol Listesi
- Yaygın Hatalar ve Çözüm Adımları
- Sonuç
- Sıkça Sorulan Sorular
- Laravel OpenAI API entegrasyonu için pratik kontrol listesi
- SSS: Laravel ile OpenAI API Entegrasyonu
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.
Bir Cevap Yaz
E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir.