5. Pratinjau Agen — Momen "Aha!"
Sampai saat ini, Anda telah membangun sistem di mana Anda yang mengontrol alur. Anda menulis prompt, memanggil LLM, dan memproses responsnya. LLM memang powerful, tetapi masih hanya mengikuti instruksi Anda.
Bab ini memperkenalkan perubahan fundamental: bagaimana jika LLM yang memutuskan apa yang terjadi selanjutnya?
Mengapa Bab Ini Ada
Masalahnya: Jika Anda terus membangun chatbot hingga Bab 11 tanpa pratinjau ini, kemungkinan besar Anda akan berpikir "agen hanyalah chatbot yang lebih baik."
Kenyataannya: Agen secara fundamental berbeda. Mereka membuat keputusan yang mengontrol program Anda, bukan hanya menghasilkan teks.
Solusinya: Bab ini menunjukkan ke mana kita akan pergi, sehingga ketika Anda membangun pipeline dan manajemen state di bab-bab berikutnya, Anda akan memahami mengapa setiap bagian penting.
Apa yang Akan Anda Pelajari (Dan Apa yang Tidak)
Bab ini (Bab 5):
- Pratinjau 15 menit tentang pemikiran agentik
- Bagaimana output LLM dapat memicu jalur kode yang berbeda
- Perbedaan konseptual antara routing dan loop agen
Bab-bab selanjutnya (Mulai Bab 12):
- Sistem agen nyata dengan alat, loop, dan koreksi diri
- Implementasi yang siap produksi
- Pola lanjutan seperti koordinasi multi-agen
Mengapa ada jarak? Sebelum membangun agen, Anda memerlukan fondasi: rekayasa prompt (Bab 4), pipeline eksekusi (Bab 6), output terstruktur (Bab 7), manajemen state (Bab 8), dan integrasi pengetahuan (Bab 9-11).
Catatan tentang pendekatan pembelajaran: Bab ini fokus pada konsep, bukan detail implementasi. Teknik desain dan pengembangan sebenarnya akan datang di Bab 12 dan seterusnya. Jangan khawatir jika Anda belum tahu cara mengimplementasikan semua yang Anda lihat di sini—itu memang disengaja. Memahami apa itu agen secara konseptual sudah cukup untuk saat ini.
Mari kita mulai.
5.1) Dari Chatbot ke Pengambil Keputusan
Konsep: Alih-alih menjawab pertanyaan, LLM memutuskan alat mana yang akan digunakan
Di Bab 3 dan 4, Anda membangun sistem chat di mana LLM menghasilkan respons teks. Alurnya sederhana:
- Pengguna mengajukan pertanyaan
- LLM menghasilkan jawaban
- Anda menampilkan jawaban
Ini adalah rantai statis: alurnya sudah ditentukan sebelumnya. Satu-satunya tugas LLM adalah menghasilkan teks.
Sekarang mari kita ubah jenis permintaannya. Pengguna bertanya: "Berapa 847 × 923?"
Chatbot Anda dari Bab 3 akan mencoba menjawab ini, tetapi LLM sebenarnya tidak menghitung—mereka memprediksi token yang terlihat masuk akal. Untuk "2 + 2", jawaban "4" muncul begitu sering dalam data pelatihan sehingga LLM mendapatkannya dengan benar. Tetapi untuk "847 × 923"—perhitungan yang belum pernah dilihat LLM—ia akan menghasilkan sesuatu yang terlihat seperti angka tetapi kemungkinan salah.
Yang sebenarnya Anda inginkan:
- LLM mengenali: "Ini adalah masalah matematika"
- LLM memutuskan: "Gunakan alat kalkulator, bukan prediksi token saya"
- Python mengeksekusi: 847 × 923 = 781,781
- Sistem mengembalikan: Jawaban yang benar
Tugas LLM bukan menghitung—tetapi merutekan ke alat yang bisa.
Inilah insight kuncinya: LLM tidak perlu menyelesaikan matematika—ia perlu memutuskan untuk menggunakan kalkulator.
Ini adalah pergeseran dari chatbot ke pengambil keputusan. LLM memeriksa permintaan dan merutekannya ke alat yang sesuai. Ia membuat keputusan tentang alur program, bukan hanya menghasilkan teks.
Mari kita visualisasikan perbedaan ini:
Dalam rantai statis, LLM mencoba menjawab semuanya secara langsung. Dalam sistem routing dinamis, LLM merutekan permintaan ke alat yang tepat.
Visual: Bandingkan "Rantai Linear" (Statis) vs. "Router" (Dinamis)
Berikut cara rantai statis menangani permintaan pengguna apa pun:
LLM mencoba menjawab semuanya secara langsung. Baik Anda bertanya "Apa ibu kota Prancis?" atau "Berapa 15% dari 240?", LLM menghasilkan respons teks. Ia mungkin mendapatkan ibu kota dengan benar (ia telah melihat "Paris" berkali-kali dalam data pelatihan), tetapi kemungkinan akan salah menghitung persentase.
Masalahnya: LLM menggunakan pendekatan yang sama untuk semua pertanyaan—prediksi token—bahkan ketika alat yang lebih baik tersedia.
Sekarang mari kita perkenalkan sistem yang dapat menangani berbagai jenis permintaan secara berbeda:
- Pertanyaan faktual: "Apa ibu kota Prancis?" → Gunakan alat pencarian
- Masalah matematika: "Berapa 15% dari 240?" → Gunakan kalkulator
- Percakapan: "Apa kabar?" → LLM merespons langsung
Berikut router dinamis yang memungkinkan ini:
LLM memeriksa input dan memilih jalur berdasarkan jenis permintaan. Ini adalah logika routing, dan LLM bertindak sebagai router.
Perbedaan kunci: Alih-alih selalu menghasilkan teks, LLM sekarang memutuskan bagaimana menangani setiap permintaan—dengan merutekannya ke alat yang sesuai.
Kesimpulan Utama: Dari Menghasilkan Jawaban ke Memilih Tindakan
Ini adalah pergeseran fundamental dalam sistem agentik:
Penggunaan LLM tradisional: Anda mengajukan pertanyaan, LLM menulis jawaban.
Penggunaan LLM agentik: Anda mengajukan pertanyaan, LLM memutuskan apa yang harus dilakukan, dan kode Anda mengeksekusi keputusan tersebut.
Output LLM bukan lagi hanya teks untuk pengguna—tetapi instruksi untuk program Anda.
Pikirkan seperti ini: dalam chatbot tradisional, LLM adalah karyawan yang menjawab pertanyaan pelanggan. Dalam sistem agentik, LLM adalah manajer yang memutuskan departemen mana yang harus menangani setiap permintaan.
Kemampuan pengambilan keputusan ini adalah esensi dari sistem agentik. LLM tidak hanya merespons—ia mengontrol apa yang dilakukan program Anda selanjutnya. Berdasarkan input, ia dapat memicu kalkulator, memanggil API pencarian, atau merespons langsung. Perilaku program berubah berdasarkan keputusan LLM.
Tetapi bagaimana kita benar-benar mengimplementasikan ini? Mari kita lihat kode minimal yang membuatnya bekerja.
5.2) Eksekusi Minimal
Pemicu: Prompt sistem yang memaksa output terstruktur
Untuk membuat LLM bertindak sebagai router, kita perlu membatasi outputnya. Alih-alih menghasilkan jawaban lengkap, kita ingin ia menghasilkan keputusan terstruktur—objek JSON yang memberi tahu kode kita apa yang harus dilakukan dan data apa yang harus digunakan.
Berikut prompt sistem yang melakukan ini:
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
import json
llm = ChatOpenAI(model="gpt-4o-mini")
system_prompt = """Kamu adalah asisten routing. Analisis permintaan pengguna dan respons dengan JSON.
Format output:
{
"action": "CALC" | "SEARCH" | "CHAT",
"input": "input yang dibersihkan untuk alat"
}
Contoh:
Pengguna: "Hitung 15 kali 7"
Output: {"action": "CALC", "input": "15 * 7"}
Pengguna: "Apa ibu kota Jepang?"
Output: {"action": "SEARCH", "input": "ibu kota Jepang"}
Pengguna: "Halo!"
Output: {"action": "CHAT", "input": "Halo!"}
Ekstrak informasi penting dan format untuk alat yang sesuai.
Hanya output JSON yang valid, tidak ada yang lain."""
def get_routing_decision(user_input: str) -> dict:
messages = [
SystemMessage(content=system_prompt),
HumanMessage(content=user_input)
]
response = llm.invoke(messages)
# Parse respons JSON
try:
decision = json.loads(response.content.strip())
return decision
except json.JSONDecodeError:
# Fallback jika LLM tidak menghasilkan JSON yang valid
return {"action": "CHAT", "input": user_input}
# Test dengan input BERBEDA dari contoh
print(get_routing_decision("Berapa 25 * 48?"))
# Output: {'action': 'CALC', 'input': '25 * 48'}
print(get_routing_decision("Siapa yang menulis Hamlet?"))
# Output: {'action': 'SEARCH', 'input': 'penulis Hamlet'}
print(get_routing_decision("Apa kabar hari ini?"))
# Output: {'action': 'CHAT', 'input': 'Apa kabar hari ini?'}Prompt ini sengaja dibuat restriktif. Kita tidak meminta LLM untuk kreatif—kita meminta ia untuk mengklasifikasikan input dan mengekstrak informasi yang relevan dalam format terstruktur.
Perhatikan apa yang terjadi di sini:
- LLM membaca pertanyaan pengguna
- Ia menentukan intent (perhitungan, pencarian faktual, percakapan)
- Ia mengekstrak dan membersihkan informasi penting
- Ia menghasilkan objek JSON dengan action dan input yang dibersihkan
- Kode kita menerima data terstruktur ini dan merutekan sesuai
LLM tidak menjawab pertanyaan—ia memutuskan apa yang harus menjawab pertanyaan.
Jembatan: Menghubungkan Keputusan LLM ke Eksekusi Alat
Sekarang kita perlu menghubungkan keputusan LLM ke eksekusi alat yang sebenarnya. Berikut jembatan minimalnya:
def safe_calculator(expression: str) -> float:
try:
# Gunakan eval dengan namespace terbatas untuk keamanan
# Catatan: eval() memiliki risiko keamanan.
# Dalam produksi, gunakan library parsing matematika seperti sympy atau evaluasi berbasis ast.
result = eval(expression, {"__builtins__": {}}, {})
return float(result)
except:
raise ValueError(f"Tidak dapat menghitung: {expression}")
def search(query: str) -> str:
"""Fungsi pencarian placeholder"""
# Dalam kenyataannya, ini akan memanggil API pencarian
# Sekarang menerima query yang dibersihkan seperti "penulis Hamlet"
return f"Hasil pencarian untuk: {query}"
def route_and_execute(user_input: str) -> str:
"""Dapatkan keputusan LLM dan eksekusi alat yang sesuai"""
decision = get_routing_decision(user_input)
action = decision["action"]
tool_input = decision["input"] # Input yang dibersihkan LLM
if action == "CALC":
try:
result = safe_calculator(tool_input)
return f"Hasil perhitungan: {result}"
except ValueError as e:
return f"Tidak dapat melakukan perhitungan: {e}"
elif action == "SEARCH":
result = search(tool_input)
return result
else: # CHAT
# Untuk query percakapan, biarkan LLM merespons langsung
response = llm.invoke([HumanMessage(content=tool_input)])
return response.content
# Test alur lengkap
print(route_and_execute("Berapa 25 * 48?"))
# LLM mengekstrak "25 * 48" → kalkulator menerima input bersih
# Output: Hasil perhitungan: 1200.0
print(route_and_execute("Siapa yang menulis Hamlet?"))
# LLM memformat ulang ke "penulis Hamlet" → query pencarian lebih baik
# Output: Hasil pencarian untuk: penulis Hamlet
print(route_and_execute("Apa kabar hari ini?"))
# Output: Saya baik-baik saja, terima kasih sudah bertanya!Ini adalah pola routing minimal dalam bentuk paling sederhana:
- Keputusan LLM: Dapatkan keputusan routing dari LLM
- Eksekusi Kode: Kode Python memeriksa keputusan
- Pemanggilan Alat: Fungsi yang sesuai dipanggil
- Pengembalian Hasil: Output diformat dan dikembalikan
Insight kritis: Output LLM bukan lagi teks untuk pengguna—tetapi data terstruktur yang mengontrol perilaku program Anda. Field action memberi tahu kode Anda jalur mana yang harus diambil, dan field input menyediakan data yang dibersihkan untuk alat tersebut. Respons JSON ini menjadi logika yang dapat dieksekusi.
Ini secara fundamental berbeda dari chatbot. Dalam chatbot, output LLM langsung ke pengguna. Di sini, output LLM pergi ke kode Anda, yang kemudian memutuskan apa yang akan dieksekusi.
Apa yang kita bangun di bagian ini adalah router—pendahulu dari agen penuh. Ini mendemonstrasikan prinsip fundamental (LLM mengontrol alur), tetapi tidak memiliki iterasi dan koreksi diri yang mendefinisikan loop agen sejati.
Sistem routing sederhana ini memiliki keterbatasan besar: ia tidak dapat mengoreksi kesalahannya sendiri. Mari kita jelajahi mengapa itu penting dan apa yang akan datang selanjutnya.
5.3) Memahami Terminologi: Router vs Agen
Apa yang baru saja kita bangun adalah router. Tetapi bagaimana perbandingannya dengan agen penuh? Mari kita tetapkan definisi yang jelas:
Router (apa yang baru saja kita bangun)
- Membuat satu keputusan klasifikasi per permintaan
- Memilih alat/jalur mana yang akan dieksekusi
- Mengeksekusi sekali dan mengembalikan
- Tidak ada iterasi, tidak ada state, tidak ada koreksi diri
- Contoh: Pengklasifikasi email, detektor intent, pemilih alat
Asisten pemanggilan alat (Bab 13)
- LLM dapat memanggil alat secara langsung melalui API pemanggilan fungsi
- Masih biasanya single-turn (satu permintaan → satu respons)
- Lebih canggih daripada routing, tetapi tidak harus iteratif
- Contoh: "Cari cuaca dan ringkas" dalam satu panggilan
Agen (loop penuh) (Bab 14-17)
- Beriterasi melalui siklus pikirkan → bertindak → amati
- Membawa state antar iterasi
- Dapat merevisi keputusan berdasarkan hasil
- Mengimplementasikan koreksi diri
- Contoh: Asisten debugging yang mencoba perbaikan hingga kode bekerja
Sistem agentik (istilah umum)
- Sistem apa pun di mana output LLM memengaruhi alur kontrol
- Termasuk router, asisten pemanggilan alat, dan agen penuh
- "Agentik" menggambarkan properti; "agen" menggambarkan arsitektur spesifik
- Contoh: Semua yang disebutkan di atas menunjukkan perilaku agentik
Apa yang kita bangun di 5.2 adalah router—ia membuat satu keputusan dan mengeksekusinya. Ini bekerja dengan baik untuk tugas klasifikasi yang sederhana, tetapi tidak dapat menangani situasi yang memerlukan beberapa langkah, verifikasi, atau koreksi jalur. Jika keputusan awal tidak optimal atau jika tugas ternyata lebih kompleks dari yang diharapkan, router tidak memiliki mekanisme untuk beradaptasi.
Agen menyelesaikan keterbatasan ini dengan memperkenalkan iterasi. Mereka dapat mengamati hasil dari suatu tindakan, mempertimbangkan kembali pendekatan mereka, dan mencoba lagi. Ini membuat mereka cocok untuk tugas multi-langkah yang kompleks di mana jalur ke solusi tidak jelas dari awal.
Di Bab 14-17, Anda akan belajar cara membangun loop agen iteratif ini.
Catatan: Baru-baru ini, model reasoning seperti o1 dan o3 dapat menangani beberapa tugas multi-langkah secara internal, mengurangi kebutuhan untuk loop eksplisit dalam skenario tertentu. Kita akan mengeksplorasi kapan menggunakan loop vs. model reasoning saat Anda membangun agen nyata di Bagian IV.
Apa yang harus Anda pahami sekarang:
- Sistem agentik dimulai dengan alur kontrol: Output LLM menentukan apa yang dilakukan kode Anda selanjutnya
- Routing adalah bentuk paling sederhana: Satu keputusan, satu alat, satu hasil—apa yang kita bangun di 5.2
- Agen nyata memerlukan loop: Untuk menangani tugas multi-langkah, verifikasi, dan pemulihan kesalahan (Bab 14-17)
- Koreksi diri adalah perbedaan kunci: Agen dapat mengamati hasil dan menyesuaikan pendekatan mereka
Apa yang belum kita bahas (dan tidak akan sampai bab-bab selanjutnya):
- Cara menyusun pipeline eksekusi (Bab 6)
- Cara menangani output terstruktur (Bab 7)
- Cara mengelola memori percakapan (Bab 8)
- Cara mendefinisikan alat dengan benar (Bab 12)
- Cara mengimplementasikan loop agen dengan koreksi diri (Bab 14-17)
- Cara membuat agen siap produksi (Bab 18-26)
Bab ini tentang pergeseran konseptual—memahami apa yang membuat sistem menunjukkan perilaku agentik. Detail implementasi akan datang kemudian.
Di bab berikutnya, kita akan terus membangun fondasi praktis: menyusun pipeline eksekusi dengan LangChain Expression Language (LCEL). Ini adalah blok bangunan yang akan Anda gunakan ketika kita mengimplementasikan agen nyata di Bagian IV.
Momen "aha!" selesai. Anda sekarang memahami bahwa sistem agentik adalah sistem di mana LLM memutuskan, dan kode Anda mengeksekusi. Semua yang lain—alat, loop, manajemen state—adalah tentang membuat siklus keputusan-eksekusi tersebut lebih robust dan capable.
Mari kita lanjutkan membangun fondasi.