Di episode #26 kita sudah membahas bahwa agent = model + loop + tool use. Kali ini kita bedah bagian paling krusial dari tool use: function calling — mekanisme yang membuat LLM bisa “memanggil” kode yang kamu tulis. Ini jembatan antara teks dan aksi nyata.
Intuisi programmer: model itu cuma pemilih fungsi
Cara paling mudah memahami function calling: LLM sebenarnya TIDAK menjalankan fungsi apa pun. Model hanya menghasilkan teks terstruktur berupa nama fungsi + argumen (dalam format JSON), lebih sering disebut tool_call. Yang benar-benar mengeksekusi fungsi itu adalah program kamu — runtime PHP/Python/Node yang sudah kamu tulis. Hasil eksekusi dikirim balik sebagai pesan baru, dan model menyusun jawaban akhir dari hasil itu.
Saya ingat analogi ini membantu sekali: model itu seperti ketua tim yang tidak punya akses keyboard. Dia bilang “panggil fungsi get_weather dengan kota Jakarta”, lalu programmer (kode kamu) yang mengetik dan mengeksekusinya. Hasil layar dikembalikan ke ketua tim, dan dia yang merangkum jawabannya.

Sekali jalan, bukan satu panggilan
Yang sering membuat saya kaget saat pertama kali mencoba: alur function calling butuh dua (atau lebih) request API. Request pertama: kirim pesan user + daftar definisi tool → model balas dengan tool_call. Request kedua: kirim pesan asli + tool_call dari model + tool result hasil eksekusi kamu → model balas jawaban final untuk user. Kalau hasil tool kurang dan model mau memanggil tool lain, siklusnya bisa berulang beberapa kali. Loop inilah yang di episode #26 kita sebut “perceive-reason-act” dalam bentuk paling sederhana.
Bagian yang kamu tulis: definisi tool
Definisi tool ditulis dalam format JSON Schema — deskripsi deklaratif tentang nama fungsi, parameter, tipe data, dan required field. Contoh paling sederhana:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Ambil cuaca kota saat ini",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Nama kota, misal Jakarta"
}
},
"required": ["city"]
}
}
}Dua hal yang saya pelajari keras setelah beberapa proyek:
- Field
descriptionadalah prompt engineering terselubung. Model membaca deskripsi itu untuk memutuskan kapan memanggil tool dan bagaimana mengisi argumen. Deskripsi buruk = tool dipanggil di konteks yang salah. Saya perlu menulis deskripsi sedetail “pakai HANYA untuk cuaca terkini, bukan ramalan”. - Schema bukan jaminan validasi. Model kadang mengembalikan argumen yang tidak lolos schema (khususnya di lama tanpa mode strict). Di sisi kamu tetap wajib ada validasi — untuk programmer PHP ini sama seperti selalu validasi input request, jangan percaya client.
Kode sisi kamu: eksekusi dengan hati-hati
Setelah menerima tool_call, kamu perlu mengeksekusinya. Ini pseudocode inti loop-nya (bahasa agnostic):
messages = [{"role": "user", "content": user_input}]
while True:
resp = client.chat(messages=messages, tools=TOOLS)
if not resp.tool_calls: # model selesai, tidak perlu tool
return resp.text # <- jawaban final untuk user
messages.append(resp.assistant_message) # simpan tool_call-nya
for call in resp.tool_calls:
result = execute(call.name, call.args) # KAMU yang eksekusi
messages.append(tool_result_message(call.id, result))Sintaks persisnya beda tiap provider, tapi polanya selalu sama: cek apakah respons berisi tool_calls; kalau ya, eksekusi, tambahkan hasil ke riwayat pesan, dan ulangi. Loop ini yang kemudian dibungkus framework seperti LangGraph atau smolagents — bahasanya di episode #29.
Empat jebakan yang saya temui langsung
- Keamanan eksekusi. Nama fungsi dari model datang sebagai string. Kalau kamu mengeksekusi dengan
eval()atau pemetaan sembrono, satu jailbreak berarti model bisa memanggil apa pun. Selalu petakan nama tool ke fungsi di whitelist eksplisit. - Loop tak berujung. Model yang kecanduan tool bisa memanggil terus tanpa hasil. Saya selalu pasang batas iterasi (mis. 5×) lalu paksa model menjawab dengan apa adanya.
- Hasil tool terlalu besar. Database row ratusan kilobait langsung menghabiskan context window. Ringkas atau potong hasil sebelum dikirim balik.
- Argumen salah tipe. Model iseng mengirim angka sebagai string. Validasi tipe di sisi kamu sebelum fungsi nyata dieksekusi.
Catatan penutup
Function calling terdengar sederhana, tapi ini komponen yang menentukan apakah agent kamu terasa "pintar" atau berantakan. Definisi tool yang jelas + eksekusi yang aman + loop yang dijaga = fondasi kokoh. Di episode berikutnya kita bahas MCP (Model Context Protocol) — standar yang membuat definisi tool ini bisa dipakai ulang antar aplikasi tanpa menulis integrasi satu per satu.
Sumber
- OpenAI — Function calling and other API updates (13 Juni 2023): openai.com
- OpenAI Docs — Function calling guide: platform.openai.com/docs
- Anthropic Docs — Tool use with Claude: docs.anthropic.com
- Mozilla Developer / MDN — JSON Schema (format definisi parameter): json-schema.org
Komentar Terbaru