Proteksi Kuota AI per Pengguna
Mekanisme pembatasan penggunaan fitur berbiaya tinggi (LLM API) yang dicatat secara persisten pada level akun pengguna.
Membaca sekitar 2 menit
Mekanisme pembatasan penggunaan fitur berbiaya tinggi (LLM API) yang dicatat secara persisten pada level akun pengguna.
Memeriksa sisa kuota sebelum memanggil API Groq dan hanya menambah penghitung pemakaian ketika respons JSON dari AI berhasil divalidasi.
Kuota tidak boleh dipotong saat AI mengalami timeout atau mengembalikan format rusak, agar pengguna tidak dirugikan oleh kegagalan sistem eksternal.
Masalahnya dulu
Setiap kali fitur AI Trip Planner dijalankan, server melakukan panggilan ke layanan LLM eksternal dengan prompt yang cukup besar dan batas output hingga 4.000 token. Tanpa pembatasan yang jelas, satu pengguna atau bot bisa melakukan spam tombol generate berkali-kali hingga menghabiskan kuota rate-limit maupun biaya API aplikasi.
Penjaga kuota di tabel users dengan pemotongan bersyarat
Melalui migrasi khusus pada tabel users, setiap akun dibekali dua kolom bertipe unsignedInteger: trip_plan_quota (default 2) dan trip_plan_generated_count (default 0). Pengecekan kuota ditempatkan di baris paling awal metode generate() sebelum query database destinasi atau request HTTP ke Groq dieksekusi. Sementara itu, penambahan nilai trip_plan_generated_count baru dijalankan di bagian paling akhir setelah respons AI dipastikan valid.
Periksa kuota sedini mungkin untuk menghemat sumber daya server, tetapi potong kuota paling akhir hanya ketika pengguna benar-benar menerima hasil yang valid.
Implementasi di ngodingan ini
Pengecekan batas kuota di awal dan pencatatan pemakaian atomik menggunakan increment() setelah validasi JSON di TripPlannerController:
$user = $request->user();
if ($user) {
$quota = (int) ($user->trip_plan_quota ?? 2);
$generated = (int) ($user->trip_plan_generated_count ?? 0);
if ($generated >= $quota) {
return back()->with('ai_error', 'Kuota generate trip kamu sudah habis.');
}
}
// ... proses inferensi Groq AI & validasi struktur JSON itinerary ...
// Increment quota counter hanya jika generate berhasil & valid
if ($user) {
$user->increment('trip_plan_generated_count');
}Jebakan dan detail yang harus dijaga
- Memisahkan kolom batas maksimal (trip_plan_quota) dan jumlah pemakaian (trip_plan_generated_count) jauh lebih fleksibel daripada hanya menyimpan satu kolom sisa kuota: kita tetap punya histori berapa kali seorang user pernah memakai AI dan bisa menaikkan kuota user tertentu tanpa kehilangan jejak pemakaiannya.
- Jika API AI sedang mengalami gangguan (HTTP failed, timeout, atau format JSON rusak), eksekusi langsung berhenti dan kembali ke halaman form membawa pesan ai_error tanpa menyentuh baris $user->increment(), sehingga jatah pengguna tetap aman.
- Hasil itinerary yang sudah berhasil dibuat disimpan ke dalam session(['trip_itinerary' => $itinerary]) sehingga pengguna bebas me-refresh halaman hasil atau mencetaknya ke PDF tanpa memicu panggilan AI ulang yang memotong kuota.