Tema
Bahasa
·5 mnt baca

Pemanggilan fungsi dengan API LLM: loop kerja lengkap

Cara kerja pemanggilan fungsi (penggunaan tool) pada API yang kompatibel dengan OpenAI: loop Python lengkap yang kami jalankan pada GPT-6 Luna, DeepSeek V4.1 Flash, dan Claude Haiku 5.5, memaksa pemanggilan dengan tool_choice, serta format Anthropic Messages.

Pemanggilan fungsi dengan API LLM: loop kerja lengkap

Function calling (juga disebut tool calling atau penggunaan tool) adalah cara memberi model akses ke kode Anda. Anda mendeskripsikan fungsi seperti "mencari pesanan" atau "menghitung tarif pengiriman". Model menentukan fungsi mana yang akan dipanggil dan dengan argumen apa; kode Anda menjalankannya dan mengirimkan kembali hasilnya. Setiap agent, mulai dari bot dukungan toko hingga Claude Code, dibangun berdasarkan loop ini.

Di GetVibe API, function calling bekerja melalui endpoint standar /v1/chat/completions dalam format OpenAI dan melalui /v1/messages dalam format Anthropic. Di bawah ini adalah loop lengkap yang kami jalankan pada tiga model dari tiga pembuat yang berbeda.

Cara kerja loop

  1. Anda mengirim messages beserta daftar tools. Setiap tool memiliki nama, deskripsi, dan JSON Schema untuk parameternya.
  2. Alih-alih teks, model mengembalikan tool_calls: fungsi yang harus dipanggil dan argumennya. finish_reason bernilai tool_calls.
  3. Kode Anda menjalankan fungsi-fungsi tersebut dan menambahkan satu message dengan role tool untuk setiap pemanggilan, dengan membawa tool_call_id yang sama.
  4. Anda mengirim ulang history tersebut. Model kemudian meminta pemanggilan tambahan atau menjawab pengguna dalam bentuk teks.

Model tidak pernah menjalankan apa pun sendiri. Model hanya meminta pemanggilan. Apa yang benar-benar dijalankan dan dengan izin apa ditentukan oleh kode Anda.

Contoh lengkap: asisten dukungan toko

Dua fungsi: status pesanan dan tarif pengiriman. Pengguna menanyakan keduanya sekaligus, dan model memanggil kedua fungsi dalam satu turn.

import json
import os
from openai import OpenAI

client = OpenAI(base_url="https://getvibeapi.com/v1", api_key=os.environ["GETVIBE_API_KEY"])
MODEL = "gpt-6-luna"

def get_order_status(order_id: str) -> dict:
    # pencarian di database atau CRM Anda dilakukan di sini
    return {"order_id": order_id, "status": "out for delivery", "eta": "2026-10-24"}

def get_shipping_quote(zip_code: str) -> dict:
    return {"zip_code": zip_code, "price_usd": 7.5, "days": 2}

TOOLS = [
    {"type": "function", "function": {
        "name": "get_order_status",
        "description": "Look up an order by its ID",
        "parameters": {"type": "object",
                       "properties": {"order_id": {"type": "string", "description": "Order ID, e.g. A-1042"}},
                       "required": ["order_id"]}}},
    {"type": "function", "function": {
        "name": "get_shipping_quote",
        "description": "Courier shipping price and delivery time to a US ZIP code",
        "parameters": {"type": "object",
                       "properties": {"zip_code": {"type": "string"}},
                       "required": ["zip_code"]}}},
]
FUNCTIONS = {"get_order_status": get_order_status, "get_shipping_quote": get_shipping_quote}

messages = [
    {"role": "system", "content": "Anda adalah asisten dukungan toko. Jawab dengan singkat."},
    {"role": "user", "content": "Di mana pesanan saya A-1042? Dan berapa biaya pengiriman ke 94110?"},
]

for _ in range(5):  # batasi jumlah putaran
    resp = client.chat.completions.create(model=MODEL, messages=messages, tools=TOOLS)
    msg = resp.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    messages.append(msg.model_dump(exclude_none=True))
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = FUNCTIONS[call.function.name](**args)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

Kami menjalankan kode ini tanpa perubahan pada gpt-6-luna, deepseek-v4.1-flash, dan claude-haiku-5.5, dengan hanya mengubah MODEL. Pada putaran pertama, ketiganya memanggil kedua fungsi: get_order_status dengan A-1042 dan get_shipping_quote dengan 94110. Pada putaran kedua, ketiganya menjawab dalam bentuk teks dengan status pengiriman, ETA, harga 7.50, dan waktu pengiriman dua hari.

Hal penting dalam kode ini

  • Tambahkan message tool-call dari model ke history secara lengkap. Tanpanya, message tool Anda menjawab pemanggilan yang tidak dapat dilihat model, dan banyak model akan memanggil fungsi yang sama lagi, sehingga loop terus berputar.
  • Satu message tool untuk setiap pemanggilan, dengan tool_call_id yang sesuai. Model dapat meminta beberapa pemanggilan sekaligus, seperti yang terjadi di sini.
  • Argumen diterima sebagai string. arguments adalah JSON di dalam sebuah string. Parse dan validasikan, karena model dapat memberikan nilai yang salah.
  • Batasi jumlah putaran. Tanpa batas, bug dalam suatu fungsi dapat mengubah loop menjadi loop tanpa akhir, sekaligus menghasilkan tagihan token tanpa akhir.

tool_choice: kapan pemanggilan wajib dilakukan

Secara default, model menentukan apakah akan memanggil tool atau menjawab dalam bentuk teks ("auto"). tool_choice mengubah perilaku tersebut:

  • "none" — jangan pernah memanggil tool;
  • "required" — panggil setidaknya satu tool;
  • {"type": "function", "function": {"name": "..."}} — panggil fungsi tertentu ini.

Bentuk terakhir berguna untuk ekstraksi data. Schema parameter fungsi menjadi bentuk jawaban:

curl https://getvibeapi.com/v1/chat/completions \
  -H "Authorization: Bearer $GETVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4.1-flash",
    "messages": [{"role": "user", "content": "Jane Doe, [email protected], ingin demo pada hari Kamis"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "save_lead",
        "description": "Save a sales lead to the CRM",
        "parameters": {
          "type": "object",
          "properties": {"name": {"type": "string"}, "email": {"type": "string"}, "request": {"type": "string"}},
          "required": ["name", "email", "request"]
        }
      }
    }],
    "tool_choice": {"type": "function", "function": {"name": "save_lead"}}
  }'

Responsnya adalah pemanggilan save_lead dengan name "Jane Doe", email "[email protected]", dan request "Ingin demo pada hari Kamis".

Satu catatan: beberapa model Claude, termasuk Claude Sonnet 5.5 dan Claude Opus 5.5, tidak menerima tool choice yang dipaksakan. GetVibe mengubah permintaan tersebut menjadi auto dengan tools yang sama, sehingga Anda mendapatkan jawaban alih-alih error, tetapi model kemudian menentukan sendiri apakah akan melakukan pemanggilan. Untuk JSON strict dari model-model tersebut, gunakan structured outputs.

Format Anthropic: /v1/messages

Dengan Anthropic SDK, tools terlihat sedikit berbeda: schema parameter ditempatkan di input_schema, dan pemanggilan dikembalikan sebagai content block tool_use.

curl https://getvibeapi.com/v1/messages \
  -H "x-api-key: $GETVIBE_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku-5.5",
    "max_tokens": 512,
    "tools": [{
      "name": "get_order_status",
      "description": "Look up an order by its ID",
      "input_schema": {"type": "object", "properties": {"order_id": {"type": "string"}}, "required": ["order_id"]}
    }],
    "messages": [{"role": "user", "content": "Di mana pesanan A-1042?"}]
  }'

Respons memiliki stop_reason tool_use dan block tool_use yang memanggil get_order_status dengan order_id A-1042. Anda mengirimkan hasilnya kembali sebagai block tool_result dalam user message berikutnya, dengan tool_use_id yang sama.

Model mana yang digunakan untuk tools

  • Bot bervolume tinggi dan tools sederhana — DeepSeek V4.1 Flash ($0.0112 input · $0.0445 output per 1 juta token) atau Claude Haiku 5.5 ($0.0267 input · $0.1334 output per 1 juta token).
  • Agent dengan banyak tools dan rencana panjang — GPT-6 Luna ($0.0055 input · $0.0274 output per 1 juta token) atau Claude Sonnet 5.5.

Loop agent mengirim ulang prefix panjang yang sama pada setiap putaran, jadi prompt caching sangat penting di sini. Detail lebih lanjut tentang field request tersedia di dokumentasi tool calling.

API pemanggilan fungsipemanggilan tool LLMcontoh pemanggilan fungsi OpenAItool_choicepenggunaan tool Anthropictool untuk agen LLM

Coba GetVibe API secara gratis

GPT, Claude, Gemini, dan lainnya melalui satu API yang kompatibel dengan OpenAI. Bayar dalam USD dengan kartu atau kripto.

Artikel terkait

Pemanggilan fungsi dengan API LLM: loop kerja lengkap | GetVibe API