Praktik Pengembangan II: Fitur Lanjutan Produk LLM
Chatbot biasa sudah bisa โ sekarang kita naik level. Di sesi ini kita tambahkan fitur yang benar-benar membedakan produkmu: structured output JSON, multi-prompt chaining, integrasi database, dan analisis file teks secara otomatis.
1. Empat Fitur yang Membedakan Produkmu
Di sesi sebelumnya kita buat chatbot yang bisa menjawab. Di sesi ini kita tambahkan lapisan fitur yang membuat produkmu terasa jauh lebih pintar dan berguna. Masing-masing fitur membuka kemungkinan produk yang berbeda:
๐งฉ
Structured Output
JSON Response
AI mengembalikan data terstruktur yang bisa langsung diolah oleh kode PHP/JS โ bukan hanya teks biasa
โ๏ธ
Prompt Chaining
Multi-Step AI
Memecah tugas kompleks menjadi beberapa panggilan API berurutan โ output satu menjadi input berikutnya
๐๏ธ
Integrasi Database
MySQL / SQLite
Simpan riwayat percakapan dan hasil analisis ke database agar bisa diakses kembali dan dianalisis
๐
Analisis File
TXT / CSV Upload
Pengguna upload file, kontennya dikirim ke LLM untuk dianalisis, dirangkum, atau diekstrak datanya
Kalau chatbot biasa itu seperti tukang fotokopi โ menerima dan mengembalikan teks โ maka fitur-fitur ini mengubahnya menjadi analis profesional. Ia bisa mengkategorikan data, memecah tugas rumit jadi langkah-langkah, mencatat semua hasil kerjanya di arsip, dan bahkan membaca dokumen yang kamu beri!
2. Structured Output: AI Mengembalikan JSON
Normalnya AI mengembalikan teks bebas. Tapi dengan instruksi yang tepat di prompt, kita bisa meminta AI mengembalikan JSON yang terstruktur โ sehingga hasilnya bisa langsung di-parse dan diproses oleh program kita, bukan hanya dibaca manusia.
Bayangkan kamu minta tolong teman merangkum berita. Teman biasa akan bilang: "Intinya, ekonomi lagi turun karena inflasi." Tapi teman yang terstruktur akan memberikan: {"topik": "ekonomi", "sentimen": "negatif", "kata_kunci": ["inflasi","turun"], "ringkasan": "..."}. Yang kedua jauh lebih mudah diolah oleh program komputer!
<?php// structured_output.php โ Minta AI kembalikan JSONrequire_once'api.php';
$teks = "Produk ini luar biasa! Pengiriman cepat, packing rapi,
dan kualitasnya melebihi ekspektasi saya. Sangat puas!";
$messages = [[
'role' => 'system',
'content' => 'Kamu adalah mesin analisis sentimen.
Kembalikan HANYA JSON valid tanpa teks tambahan:
{"sentimen":"positif/negatif/netral",
"skor":0-100,
"emosi_dominan":"string",
"kata_kunci":["arr"],
"alasan":"max 15 kata"}'
], [
'role' => 'user',
'content' => 'Analisis: ' . $teks
]];
// Temperature rendah agar output konsisten$raw = groq_chat($messages, 0.2, 256);
$result = json_decode($raw, true);
echo"Sentimen: " . $result['sentimen'] . "\n";
echo"Skor : " . $result['skor'] . "/100\n";
echo"Alasan : " . $result['alasan'];
?>
<?php// Cara aman parse JSON dari output AI$raw = groq_chat($messages, 0.2, 256);
// Bersihkan backtick jika AI "lupa" instruksi$clean = preg_replace('/```json|```/', '', $raw);
$clean = trim($clean);
$data = json_decode($clean, true);
if (json_last_error() !== JSON_ERROR_NONE) {
// Fallback: AI gagal hasilkan JSON valid$data = [
'sentimen' => 'tidak terdeteksi',
'skor' => 0,
'emosi_dominan' => '-',
'alasan' => $raw// tampilkan teks asli
];
}
// Simpan ke database atau kembalikan sebagai API response
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'data' => $data
]);
?>
/* Template System Prompt untuk Structured Output */// โ Tips: Selalu sertakan contoh format JSON-nya!$system = <<;
๐ฌ Lab: Analisis Sentimen Real-Time
Masukkan teks apa saja dan lihat AI mengembalikan JSON terstruktur yang langsung dirender menjadi kartu visual:
โ๏ธ Sentiment Analyzer
Structured JSON Output
โ
Skor: โ/100
Emosi
โ
Alasan
โ
3. Prompt Chaining: Pecah Tugas Kompleks
Untuk tugas yang terlalu kompleks bagi satu panggilan API, kita bisa "chain" beberapa panggilan berurutan. Output dari LLM pertama menjadi input untuk LLM kedua โ seperti jalur produksi pabrik.
Input
Teks Mentah
Artikel, review, atau dokumen panjang dari pengguna
LLM #1
Ekstrak Topik
โ Identifikasi 3 kata kunci topik utama
Output: "kopi, keberlanjutan, petani"
LLM #2
Hasilkan Ringkasan
โ Buat ringkasan berdasarkan topik + teks asli
Output: Ringkasan 2 kalimat yang tepat sasaran
<?php// chaining.php โ Multi-step LLM workflowrequire_once'api.php';
$teks = $_POST['teks'] ?? 'Kopi organik dari petani Gayo kini
mulai diminati pasar Eropa. Program sertifikasi membantu
petani mendapatkan harga yang lebih adil...';
// โโ STEP 1: Ekstrak topik utama โโ$step1 = groq_chat([[
'role' => 'system',
'content' => 'Ekstrak 3 kata topik utama dari teks.
Kembalikan HANYA 3 kata dipisah koma. Tanpa penjelasan.'
], [
'role' => 'user',
'content' => $teks
]], 0.2, 30); // temperature rendah, token sedikit// โโ STEP 2: Buat ringkasan berdasarkan topik โโ$step2 = groq_chat([[
'role' => 'system',
'content' => 'Buat ringkasan 2 kalimat menarik dalam Bahasa Indonesia.'
], [
'role' => 'user',
'content' => 'Topik: ' . $step1 . '. Teks: ' . $teks
]], 0.7, 150);
// Kembalikan kedua hasil ke frontend
header('Content-Type: application/json');
echo json_encode([
'topik' => $step1,
'ringkasan' => $step2
]);
?>
<?php// Advanced: 3-step chain untuk content pipelinerequire_once'api.php';
$artikel = $_POST['artikel'] ?? '';
// Step 1: Analisis & Ekstrak fakta kunci (JSON)$fakta_raw = groq_chat([[
'role' => 'system',
'content' => 'Ekstrak fakta kunci. JSON: {"fakta":["...","..."]}'
],['role'=>'user','content'=>$artikel]], 0.2, 200);
$fakta = json_decode($fakta_raw, true)['fakta'] ?? [];
// Step 2: Buat judul artikel yang menarik$judul = groq_chat([[
'role' => 'system',
'content' => 'Buat 3 pilihan judul artikel yang menarik. Satu per baris.'
],['role'=>'user','content'=>'Fakta: '.implode(', ',$fakta)]], 0.8, 100);
// Step 3: Tulis kesimpulan berdasarkan fakta + judul$kesimpulan = groq_chat([[
'role' => 'system',
'content' => 'Tulis 1 paragraf kesimpulan yang kuat dan inspiratif.'
],['role'=>'user','content'=>'Fakta: '.implode(', ',$fakta).' Judul terpilih: '.$judul]], 0.7, 200);
echo json_encode(['fakta'=>$fakta,'judul'=>$judul,'kesimpulan'=>$kesimpulan]);
?>
๐ฌ Lab: Multi-Step Chaining Real-Time
Masukkan teks dan lihat proses chaining dua langkah secara live โ topik diekstrak dulu, baru ringkasan dibuat:
โ๏ธ Chaining Lab
2-Step Pipeline
Step 1 โ Ekstraksi Topik
Menunggu...
โ
Step 2 โ Ringkasan
Menunggu...
4. Menyimpan History ke Database MySQL
Agar riwayat percakapan dan hasil analisis tidak hilang saat halaman ditutup, kita perlu menyimpannya ke database. Ini juga memungkinkan fitur seperti "lihat riwayat chat lama" atau "analisis pola pertanyaan pengguna".
-- Buat tabel di MySQL / phpMyAdminCREATE TABLE chat_sessions (
id INTAUTO_INCREMENT PRIMARY KEY,
session_id VARCHAR(64) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE chat_messages (
id INTAUTO_INCREMENT PRIMARY KEY,
session_id VARCHAR(64) NOT NULL,
role ENUM('user', 'assistant') NOT NULL,
content TEXTNOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_session (session_id)
);
-- Tabel untuk menyimpan hasil analisis JSONCREATE TABLE analysis_results (
id INTAUTO_INCREMENT PRIMARY KEY,
input_text TEXT,
result_json JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
<?php// db_chat.php โ Simpan & load history dari MySQL$pdo = newPDO(
'mysql:host=localhost;dbname=chatbot_db;charset=utf8mb4',
'root', '',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// Ambil atau buat session ID
session_start();
if (empty($_SESSION['chat_session'])) {
$_SESSION['chat_session'] = bin2hex(random_bytes(16));
}
$sid = $_SESSION['chat_session'];
// Fungsi simpan pesanfunctionsaveMessage($pdo, $sid, $role, $content) {
$stmt = $pdo->prepare(
'INSERT INTO chat_messages (session_id,role,content)
VALUES (?,?,?)'
);
$stmt->execute([$sid, $role, $content]);
}
// Simpan pesan user dan jawaban AIsaveMessage($pdo, $sid, 'user', $userMsg);
saveMessage($pdo, $sid, 'assistant', $aiReply);
?>
<?php// Load history dari database untuk melanjutkan percakapanfunctionloadHistory($pdo, $sid, $limit = 10): array {
$stmt = $pdo->prepare(
'SELECT role, content FROM chat_messages
WHERE session_id = ?
ORDER BY created_at DESC
LIMIT ?'
);
$stmt->execute([$sid, $limit]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Balik urutan (terlama dulu untuk LLM)returnarray_reverse($rows);
}
// Susun messages dengan history dari DB$history = loadHistory($pdo, $sid);
$messages = [['role'=>'system','content'=>$systemPrompt]];
foreach ($historyas$h) $messages[] = $h;
$messages[] = ['role'=>'user','content'=>$userMsg];
?>
5. Upload & Analisis File Teks dengan LLM
Fitur upload file memungkinkan pengguna memberikan dokumen panjang kepada AI untuk dianalisis. Kuncinya: baca isi file, kirim ke LLM, tampilkan hasilnya. Coba langsung di bawah ini โ drag & drop atau klik untuk upload file .txt:
๐
Drag & drop file .txt atau .csv di sini
atau klik untuk memilih file
๐ก Cara Kerja Analisis File di PHP
Di backend PHP: $isi = file_get_contents($_FILES['file']['tmp_name']); โ kemudian kirim $isi sebagai bagian dari pesan user ke API LLM. Batasi ukuran file (max 50KB) karena token punya batas. Untuk file CSV, parse dulu dengan fgetcsv() sebelum dikirim ke AI.
Uji Pemahaman โ Sesi 6
Pertanyaan 01
Untuk mendapatkan output JSON yang konsisten dari LLM, temperature yang direkomendasikan adalah...
Pertanyaan 02
Teknik "prompt chaining" paling tepat digunakan ketika...
Pertanyaan 03
Setelah json_decode() pada output AI, kamu perlu memeriksa json_last_error() karena...
Pertanyaan 04
Manfaat utama menyimpan riwayat percakapan ke database MySQL (bukan hanya di JavaScript) adalah...
Pertanyaan 05
Saat menganalisis file CSV yang diunggah pengguna menggunakan LLM, batasan ukuran file perlu diterapkan karena...