Pengantar: Mengapa Pencarian Tradisional Mulai Usang?
Pernahkah Anda mencari sesuatu di sebuah website menggunakan kata kunci tertentu, namun tidak mendapatkan hasil apa-apa hanya karena Anda menggunakan sinonim atau ada sedikit salah ketik (typo)? Di era modern ini, ekspektasi pengguna terhadap fitur pencarian telah berubah drastis. Berkat Google dan ChatGPT, pengguna berharap sistem dapat 'memahami' maksud mereka, bukan sekadar mencocokkan teks secara kaku.
Sebagai developer Laravel, kita sering kali mengandalkan klausa LIKE pada database SQL atau menggunakan Laravel Scout dengan driver Meilisearch/Algolia. Meskipun sangat cepat, pendekatan ini masih berbasis keyword-matching. Jika teks persisnya tidak ada, hasilnya nihil. Di sinilah Artificial Intelligence (AI) masuk untuk mengubah permainan.
Selamat datang di Part 1 dari seri tutorial 3 bagian ini! Kita akan belajar bagaimana menyulap fitur pencarian Laravel biasa menjadi sistem cerdas yang bisa memahami konteks dan bahkan diajak 'ngobrol'.
Studi Kasus: Platform E-Learning "LaraCourse"
Agar tutorial ini berkesinambungan hingga Part 3 nanti, kita akan membangun sebuah studi kasus. Mari kita bayangkan kita sedang mengembangkan LaraCourse, sebuah platform e-learning yang berisi ratusan kursus seputar teknologi, programming, dan desain.
Pengguna sering kali mencari dengan bahasa sehari-hari, seperti "cara bikin web responsif". Jika judul kursus kita adalah "Mastering Frontend Development dengan Tailwind CSS", pencarian tradisional pasti akan gagal menemukannya. Mari kita mulai dengan menyiapkan fondasinya.
1. Persiapan Database dan Model
Pertama, kita siapkan migration untuk tabel courses. Perhatikan bahwa kita menambahkan satu kolom khusus bernama embedding. Kolom ini nantinya akan menyimpan representasi data AI dari teks kita.
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('courses', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->string('category');
// Kolom JSON untuk menyimpan vector embeddings dari OpenAI
$table->json('embedding')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('courses');
}
};
Selanjutnya, kita atur model Course.php agar kolom embedding di-cast sebagai array.
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Course extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description',
'category',
'embedding'
];
protected $casts = [
'embedding' => 'array', // Cast JSON ke array PHP
];
}
2. Implementasi Pencarian Tradisional (The Old Way)
Sebagai perbandingan, mari kita lihat bagaimana pencarian tradisional biasanya diimplementasikan di controller Laravel.
namespace App\Http\Controllers;
use App\Models\Course;
use Illuminate\Http\Request;
class CourseSearchController extends Controller
{
public function search(Request $request)
{
$query = $request->input('q');
// Pendekatan tradisional: Keyword matching
$courses = Course::where('title', 'like', "%{$query}%")
->orWhere('description', 'like', "%{$query}%")
->get();
return response()->json($courses);
}
}
Limitasi kode di atas: Jika user mengetik "belajar database", namun deskripsi kita menggunakan kata "MySQL" dan "PostgreSQL" tanpa menyebut kata "database" secara eksplisit, query SQL di atas tidak akan mengembalikan hasil apa-apa. Inilah masalah utama yang akan kita pecahkan dengan AI.
Mengenal Konsep Vector dan Embeddings
Komputer dan AI tidak membaca teks seperti manusia. Mereka memahami angka. Embeddings adalah cara AI menerjemahkan teks (kata, kalimat, atau bahkan paragraf) menjadi deretan angka (array/vector). Teks yang memiliki makna atau konteks yang mirip akan memiliki deretan angka yang berdekatan posisinya di dalam ruang multidimensi.
Dengan kata lain, AI tahu bahwa kata "Kucing" dan "Anjing" lebih dekat maknanya dibandingkan "Kucing" dan "Knalpot". Kita akan menggunakan API dari OpenAI untuk mengubah data kursus kita menjadi deretan angka ini.
3. Instalasi dan Setup OpenAI di Laravel
Kita akan menggunakan package resmi komunitas untuk OpenAI di Laravel. Jalankan perintah berikut di terminal Anda:
composer require openai-php/laravel
php artisan vendor:publish --provider="OpenAI\Laravel\ServiceProvider"
Setelah itu, tambahkan API Key OpenAI Anda ke dalam file .env:
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4. Membuat Command untuk Generate Embeddings
Sekarang, kita butuh sebuah mekanisme untuk membaca semua data kursus di database kita, mengirim teksnya ke OpenAI, dan menyimpan balasan vector-nya kembali ke kolom embedding. Cara terbaik untuk ini adalah menggunakan Artisan Command.
Buat command baru dengan menjalankan: php artisan make:command GenerateCourseEmbeddings
Lalu, modifikasi file command tersebut seperti di bawah ini:
namespace App\Console\Commands;
use App\Models\Course;
use Illuminate\Console\Command;
use OpenAI\Laravel\Facades\OpenAI;
class GenerateCourseEmbeddings extends Command
{
protected $signature = 'courses:generate-embeddings';
protected $description = 'Generate OpenAI embeddings untuk semua data kursus';
public function handle()
{
$this->info('Memulai proses generasi embeddings...');
// Kita gunakan chunk agar tidak membebani memory jika data ribuan
Course::whereNull('embedding')->chunk(100, function ($courses) {
foreach ($courses as $course) {
// Gabungkan teks yang ingin kita jadikan acuan konteks
$textToEmbed = "Judul: {$course->title}. Kategori: {$course->category}. Deskripsi: {$course->description}";
try {
// Memanggil OpenAI Embeddings API
$response = OpenAI::embeddings()->create([
'model' => 'text-embedding-3-small',
'input' => $textToEmbed,
]);
// Ambil hasil vector array-nya
$embeddingVector = $response->embeddings[0]->embedding;
// Simpan ke database
$course->update([
'embedding' => $embeddingVector
]);
$this->info("Berhasil generate embedding untuk kursus ID: {$course->id}");
} catch (\Exception $e) {
$this->error("Gagal pada kursus ID {$course->id}: " . $e->getMessage());
}
}
});
$this->info('Proses generate embeddings selesai!');
}
}
Dengan command di atas, Laravel akan mengambil data kursus yang belum memiliki embedding, merangkai judul dan deskripsinya menjadi satu kalimat utuh, lalu mengirimkannya ke model text-embedding-3-small dari OpenAI. Hasilnya berupa array berisi ribuan angka desimal (float) yang kemudian disimpan ke database kita.
Kesimpulan dan Teaser Part 2
Di Part 1 ini, kita telah berhasil merancang struktur database, memahami kelemahan pencarian SQL tradisional, dan mengintegrasikan Laravel dengan OpenAI untuk mengubah teks kita menjadi data Vector (Embeddings).
Namun, data berupa deretan angka desimal tersebut belum bisa dicari menggunakan query SQL biasa. Lalu, bagaimana cara kita mencari kursus yang paling relevan dengan pertanyaan user menggunakan data angka tersebut?
Di Part 2 mendatang, kita akan membahas teknik Vector Search (Cosine Similarity) di Laravel. Kita akan mengubah input pencarian dari user menjadi vector, mencocokkannya dengan database kita, dan menampilkan hasil pencarian super cerdas yang tidak terikat pada ejaan kata kunci. Siapkan diri Anda, karena fitur search di aplikasi Laravel Anda tidak akan pernah sama lagi!
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!