SEJATIDIMEDIA Logo
Tersedia Sesi Konsultasi Gratis
SejatiDimedia Logo

Setup Integrasi OpenAI/Claude API di Laravel dari Nol

Artikel ini membahas cara membuat koneksi yang benar-benar jalan antara Laravel dan API AI (OpenAI atau Claude), mulai dari menyimpan API key dengan aman di .env, mendaftarkannya di config, membuat service class khusus, mencoba lewat route sederhana, sampai kesalahan umum yang perlu dihindari seperti hardcode key, lupa set timeout, atau tidak mengecek response yang gagal.

Timur Dian Radha Sejati

Timur Dian Radha Sejati

Founder SejatiDimedia•15 September 2026•5 menit baca
Silabus Seri Rekayasa

Laravel & AI Integration

Menghubungkan Laravel dengan model AI sekarang makin gampang, tapi bikin fiturnya stabil dan hemat resource itu cerita lain. Seri ini fokus ngebahas arsitektur praktis integrasi AI di Laravel: mulai dari manajemen queue untuk task berat, implementasi RAG sederhana, parsing structured output, sampai tips ngamanin API cost biar nggak boncos

Lihat Silabus Lengkap
Setup Integrasi OpenAI/Claude API di Laravel dari Nol

Di artikel sebelumnya, kita sudah bahas kenapa developer Laravel perlu peduli soal integrasi AI. Sekarang kita masuk ke praktiknya. Di artikel ini, kita akan buat koneksi yang benar-benar jalan antara aplikasi Laravel dan API AI (pakai OpenAI sebagai contoh utama, dengan catatan tambahan untuk Claude di bagian yang berbeda).

Setelah selesai baca artikel ini, kamu akan punya:

  • Setup
    PLAINTEXT Snippetplaintext
    1
    .env
    1 baris•4 chars
    UTF-8•Spaces: 4
    dan config untuk menyimpan API key dengan benar
  • Service class khusus untuk komunikasi ke API AI
  • Route/controller sederhana untuk testing
  • Error handling dasar biar aplikasi nggak rusak kalau API-nya gagal

Langsung saja kita mulai.

Langkah 1: Ambil API Key

Kamu butuh API key dari provider yang kamu pilih:

Simpan key ini dengan aman. Jangan pernah commit ke Git, jangan pernah hardcode langsung di kode.

Langkah 2: Simpan Key di .env

Buka file

PLAINTEXT Snippetplaintext
1
.env
1 baris•4 chars
UTF-8•Spaces: 4
dan tambahkan:

ENV Snippetenv
1
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
2
OPENAI_MODEL=gpt-4o-mini
2 baris•59 chars
UTF-8•Spaces: 4

Kalau kamu pakai Claude:

ENV Snippetenv
1
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxx
2
ANTHROPIC_MODEL=claude-sonnet-4-6
2 baris•75 chars
UTF-8•Spaces: 4

Langkah 3: Daftarkan di Config

Buka

PLAINTEXT Snippetplaintext
1
config/services.php
1 baris•19 chars
UTF-8•Spaces: 4
dan tambahkan entry baru:

script.phpphp
1
return [
2
// ... service lain yang sudah ada
3
 
4
'openai' => [
5
'key' => env('OPENAI_API_KEY'),
6
'model' => env('OPENAI_MODEL', 'gpt-4o-mini'),
7
],
8
];
8 baris•171 chars
UTF-8•Spaces: 4

Kenapa harus lewat sini, bukan langsung panggil

PLAINTEXT Snippetplaintext
1
env()
1 baris•5 chars
UTF-8•Spaces: 4
di kode? Karena
PLAINTEXT Snippetplaintext
1
env()
1 baris•5 chars
UTF-8•Spaces: 4
cuma bisa diandalkan saat proses loading config. Begitu kamu cache config di production (
PLAINTEXT Snippetplaintext
1
php artisan config:cache
1 baris•24 chars
UTF-8•Spaces: 4
), pemanggilan
PLAINTEXT Snippetplaintext
1
env()
1 baris•5 chars
UTF-8•Spaces: 4
langsung di tempat lain di aplikasi akan mengembalikan null. Selalu ambil data rahasia lewat
PLAINTEXT Snippetplaintext
1
config()
1 baris•8 chars
UTF-8•Spaces: 4
.

Langkah 4: Buat Service Class

Daripada manggil API langsung dari controller, bungkus dulu di dalam service class. Ini bikin kode lebih rapi dan gampang kalau suatu saat mau ganti provider.

Buat file

PLAINTEXT Snippetplaintext
1
app/Services/AiService.php
1 baris•26 chars
UTF-8•Spaces: 4
:

AiService.phpphp
1
<?php
2
3
namespace App\Services;
4
5
use Illuminate\Support\Facades\Http;
6
use Illuminate\Support\Facades\Log;
7
8
class AiService
9
{
10
public function ask(string $prompt): ?string
11
{
12
$response = Http::withToken(config('services.openai.key'))
13
->timeout(30)
14
->post('https://api.openai.com/v1/chat/completions', [
15
'model' => config('services.openai.model'),
16
'messages' => [
17
['role' => 'user', 'content' => $prompt],
18
],
19
]);
20
21
if ($response->failed()) {
22
Log::error('AI API request failed', [
23
'status' => $response->status(),
24
'body' => $response->body(),
25
]);
26
27
return null;
28
}
29
30
return $response->json('choices.0.message.content');
31
}
32
}
32 baris•829 chars
UTF-8•Spaces: 4

Beberapa hal yang perlu diperhatikan di sini:

  • PLAINTEXT Snippetplaintext
    1
    timeout(30)
    1 baris•11 chars
    UTF-8•Spaces: 4
    mencegah request yang macet supaya nggak nge-hang aplikasi selamanya.
  • Kita cek
    PLAINTEXT Snippetplaintext
    1
    $response->failed()
    1 baris•19 chars
    UTF-8•Spaces: 4
    sebelum coba baca body-nya. Jangan pernah asumsikan pemanggilan API-nya pasti berhasil.
  • Error dicatat ke log biar bisa di-debug nanti, bukan cuma dibiarkan hilang begitu saja.

Langkah 5: Coba Pakai Route

Untuk testing cepat, tambahkan ini ke

PLAINTEXT Snippetplaintext
1
routes/web.php
1 baris•14 chars
UTF-8•Spaces: 4
:

di.phpphp
1
use App\Services\AiService;
2
 
3
Route::get('/test-ai', function (AiService $ai) {
4
$result = $ai->ask('Jelaskan apa itu service class di Laravel, dalam satu paragraf singkat.');
5
 
6
return $result ?? 'Ada yang salah saat memanggil API AI.';
7
});
7 baris•245 chars
UTF-8•Spaces: 4

Buka

PLAINTEXT Snippetplaintext
1
/test-ai
1 baris•8 chars
UTF-8•Spaces: 4
di browser. Kalau setup-nya benar, kamu akan lihat respons dari AI-nya.

Pakai Claude Sebagai Gantinya

Kalau kamu mau pakai Claude, format request-nya sedikit berbeda. API Anthropic pakai header

PLAINTEXT Snippetplaintext
1
x-api-key
1 baris•9 chars
UTF-8•Spaces: 4
dan struktur pesan yang sedikit berbeda:

script.phpphp
1
public function askClaude(string $prompt): ?string
2
{
3
$response = Http::withHeaders([
4
'x-api-key' => config('services.anthropic.key'),
5
'anthropic-version' => '2023-06-01',
6
])
7
->timeout(30)
8
->post('https://api.anthropic.com/v1/messages', [
9
'model' => config('services.anthropic.model'),
10
'max_tokens' => 1000,
11
'messages' => [
12
['role' => 'user', 'content' => $prompt],
13
],
14
]);
15
 
16
if ($response->failed()) {
17
Log::error('Claude API request failed', [
18
'status' => $response->status(),
19
'body' => $response->body(),
20
]);
21
 
22
return null;
23
}
24
 
25
return $response->json('content.0.text');
26
}
26 baris•752 chars
UTF-8•Spaces: 4

Jangan lupa tambahkan

PLAINTEXT Snippetplaintext
1
anthropic
1 baris•9 chars
UTF-8•Spaces: 4
di
PLAINTEXT Snippetplaintext
1
config/services.php
1 baris•19 chars
UTF-8•Spaces: 4
dengan cara yang sama seperti OpenAI tadi.

Kesalahan yang Sering Terjadi

1. Hardcode API key di kode Ini cara paling gampang bikin key-mu bocor kalau kodenya ternyata masuk ke repo publik. Selalu pakai

PLAINTEXT Snippetplaintext
1
.env
1 baris•4 chars
UTF-8•Spaces: 4
dan
PLAINTEXT Snippetplaintext
1
config()
1 baris•8 chars
UTF-8•Spaces: 4
.

2. Nggak set timeout Tanpa timeout, pemanggilan API AI yang lambat atau macet bisa bikin request nggantung tanpa batas. Selalu set timeout.

3. Manggil API langsung dari controller Ini oke buat testing cepat, tapi cepat berantakan begitu kamu butuh retry, logging, atau beberapa fitur AI sekaligus. Service class bikin kode rapi sejak awal.

4. Nggak ngecek kegagalan Provider AI bisa saja mengembalikan error, kena rate limit, atau timeout. Selalu cek

PLAINTEXT Snippetplaintext
1
$response->failed()
1 baris•19 chars
UTF-8•Spaces: 4
sebelum baca body response-nya.

5. Commit

PLAINTEXT Snippetplaintext
1
.env
1 baris•4 chars
UTF-8•Spaces: 4
ke Git Pastikan
PLAINTEXT Snippetplaintext
1
.env
1 baris•4 chars
UTF-8•Spaces: 4
ada di
PLAINTEXT Snippetplaintext
1
.gitignore
1 baris•10 chars
UTF-8•Spaces: 4
. Kalau nggak sengaja ke-commit API key-nya, langsung ganti key itu lewat dashboard provider-nya.

Selanjutnya

Sekarang kita sudah punya koneksi dasar yang jalan ke API AI. Tapi manggil langsung dari route bukan cara yang tepat buat bikin fitur beneran. Di artikel selanjutnya, kita akan pakai fondasi ini untuk bikin chatbot sederhana, termasuk cara mengelola riwayat percakapan supaya AI-nya ingat konteks dari pesan-pesan sebelumnya.


Ini adalah Part 2 dari series "Laravel + AI Integration".

Topik Terkait:LaravelArchitecture
Timur Dian Radha Sejati

Timur Dian Radha Sejati

Penulis & Lead Engineer

Software engineer dan konsultan sistem di SejatiDimedia. Berfokus pada perancangan arsitektur berkinerja tinggi, refactoring backend skala enterprise, hingga pengembangan aplikasi mobile, web modern dan integrasi AI.

Punya Masalah Arsitektur atau Ingin Membangun Sistem yang Benar?

Kami siap membantu mengaudit kode, me-refactor arsitektur yang lemot, atau membangun aplikasi bisnis Anda dengan standar enterprise sejak awal.

EKSPLORASI LANJUTAN

Artikel Rekayasa Terkait

Lihat Semua
Streaming Respons AI di Laravel (SSE)
Backend, AI
5 menit baca

Streaming Respons AI di Laravel (SSE)

Sekarang, chatbot kita nunggu AI-nya selesai generate seluruh respons dulu baru ditampilkan di layar. Untuk jawaban pendek ini nggak masalah, tapi untuk respons yang panjang, user cuma bengong lihat loading kosong selama beberapa detik. Itu bukan pengalaman yang enak, dan ini salah satu alasan kenapa tool seperti ChatGPT nampilin teks muncul kata demi kata, bukan langsung semuanya sekaligus. Efek kata-demi-kata itu disebut streaming. Di artikel ini, kita akan implementasikan itu di Laravel pakai Server-Sent Events (SSE), yang setup-nya lebih sederhana dibanding WebSocket dan sudah cukup untuk kebanyakan use case chatbot.

Baca Artikel
Membangun Sistem RAG Sederhana dengan Laravel + Vector Database
Backend, AI
6 menit baca

Membangun Sistem RAG Sederhana dengan Laravel + Vector Database

Sejauh ini chatbot kita cuma bisa jawab berdasarkan apa yang sudah diketahui model AI-nya dari training. Coba tanya soal dokumentasi internal perusahaanmu, harga spesifik produkmu, atau catatan rapat minggu lalu, AI-nya nggak akan bisa jawab, karena memang nggak pernah dilatih dengan data itu. Di sinilah RAG berperan, singkatan dari Retrieval Augmented Generation. Daripada cuma mengandalkan data training model, kita ambil dulu potongan-potongan relevan dari dokumen kita sendiri, lalu kasih itu ke AI sebagai konteks sebelum kita ajukan pertanyaan. Di artikel ini, kita akan bangun versi sederhana dari ini pakai Laravel dan PostgreSQL dengan extension pgvector.

Baca Artikel
Menggunakan Prism PHP untuk Abstraksi Provider AI
Backend, AI
5 menit baca

Menggunakan Prism PHP untuk Abstraksi Provider AI

Artikel ini mengenalkan Prism PHP, package yang memberikan satu interface konsisten untuk banyak provider AI, alih-alih menulis kode custom per provider. Dibahas cara instalasi, penggunaan dasar, menulis ulang service class chatbot dari Part 3 pakai message chain milik Prism, membuat provider bisa dikonfigurasi lewat .env, fitur bawaan yang berguna seperti retry dan pelacakan usage, sampai kapan sebenarnya perlu pakai Prism dibanding manggil API langsung.

Baca Artikel