# Tool calling dan output JSON dengan model open-weight

> Function calling dengan model open-weight dalam format OpenAI: tools, tool_choice, loop panggil-dan-jawab, dan response_format untuk output JSON yang valid.

- URL: https://llmwithcrypto.com/id/docs/tool-calling/
- Terakhir diperbarui: 2026-10-23
- Penerbit: LLMwithCrypto (https://llmwithcrypto.com)

Model dapat meminta kode Anda menjalankan sebuah fungsi, lalu menggunakan hasilnya dalam jawabannya; atau ia dapat membalas dengan objek JSON yang langsung dibaca program Anda. Keduanya memakai format request OpenAI, dan keduanya bergantung pada model yang Anda pilih.

**Jawaban singkat — Bagaimana cara kerja tool calling di LLMwithCrypto?**

Kirim fungsi Anda di `tools`, dalam format OpenAI. Saat model membutuhkan salah satunya, **LLMwithCrypto** mengembalikan `finish_reason: "tool_calls"` dengan nama fungsi dan argumen JSON; kode Anda menjalankannya dan mengirim hasilnya kembali sebagai pesan `tool`. Untuk balasan terstruktur, `response_format: {"type": "json_object"}` meminta JSON yang valid. Keduanya berfungsi pada model yang mendukungnya, sesuai dokumentasi per 23 Oktober 2026.

## Model mana yang mendukung tools dan JSON?

Streaming berfungsi di setiap model; tool calling dan output JSON mengikuti apa yang didukung masing-masing model.

Uji skema Anda sendiri pada model yang akan Anda pakai sebelum Anda bergantung padanya. Model yang tidak mendukung tools akan menjawab dalam teks biasa alih-alih memanggil fungsi; model yang tidak mendukung mode JSON mengembalikan error `400` untuk `response_format`.

## Apa itu loop?

1. **Jelaskan fungsi-fungsinya** — Setiap tool memiliki name, description yang dibaca model untuk memutuskan kapan memakainya, dan parameters sebagai JSON Schema.
2. **Kirim percakapan beserta tools** — Model menjawab dalam teks, atau berhenti dengan finish_reason: "tool_calls" dan satu atau lebih panggilan di message.tool_calls.
3. **Jalankan setiap panggilan** — Parse function.arguments (string JSON), jalankan fungsi Anda, dan jangan pernah percaya argumennya begitu saja: validasi seperti input pengguna lainnya.
4. **Kirim hasilnya kembali** — Tambahkan pesan assistant, lalu satu pesan tool per panggilan dengan tool_call_id dan hasilnya sebagai teks. Panggil API lagi; ulangi sampai model menjawab dalam teks.

*Python: loop tool lengkap dengan gpt-oss-120b*

```python
import json
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://llmwithcrypto.com/api/v1",
    api_key=os.environ["LLMWITHCRYPTO_API_KEY"],
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order_status",
            "description": "Return the delivery status of an order.",
            "parameters": {
                "type": "object",
                "properties": {"order_id": {"type": "string"}},
                "required": ["order_id"],
            },
        },
    }
]


def get_order_status(order_id):
    return {"order_id": order_id, "status": "shipped", "eta": "2026-10-25"}


messages = [{"role": "user", "content": "Where is my order A-1042?"}]
while True:
    resp = client.chat.completions.create(model="gpt-oss-120b", messages=messages, tools=tools, max_tokens=300)
    msg = resp.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_order_status(**args)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

```

## Seperti apa panggilan tool dalam responsnya?

Pesan assistant tidak berisi teks, ada array `tool_calls`, dan pilihan berakhir dengan `finish_reason: "tool_calls"`. Argumennya datang sebagai string JSON, bukan objek. id dan jumlah di bawah ini hanya ilustrasi.

*Respons yang meminta pemanggilan fungsi (ilustrasi)*

```json
{
  "id": "chatcmpl-3c9d27e1",
  "object": "chat.completion",
  "created": 1792742400,
  "model": "gpt-oss-120b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_7f31",
            "type": "function",
            "function": {
              "name": "get_order_status",
              "arguments": "{\"order_id\": \"A-1042\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 118,
    "completion_tokens": 22,
    "total_tokens": 140
  }
}

```

## Bagaimana cara mengatur kapan tools digunakan?

- **`"tool_choice": "auto"`** (default saat `tools` diatur): model yang memutuskan.
- **`"tool_choice": "none"`**: model menjawab dalam teks meskipun tools terdaftar.
- **`"tool_choice": "required"`**: model harus memanggil setidaknya satu tool.
- **`{"type": "function", "function": {"name": "get_order_status"}}`**: model harus memanggil tool yang itu.

Setiap definisi tool dikirim sebagai input pada tiap panggilan, jadi deskripsi yang panjang dan banyak tool menambah token input. Jaga deskripsi tetap singkat dan kirim hanya tools yang dibutuhkan suatu langkah.

## Bagaimana cara mendapatkan JSON yang valid?

Atur `response_format` ke `{"type": "json_object"}` dan jelaskan key yang diharapkan di system message: mode JSON menjamin balasannya bisa di-parse, bukan bahwa balasan itu punya key yang Anda inginkan. Jaga `temperature` tetap rendah untuk output yang stabil dan periksa objek hasil parse di kode Anda sebelum memakainya.

*Node.js: balasan JSON dengan response_format*

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

const resp = await client.chat.completions.create({
  model: 'gpt-oss-120b',
  messages: [
    { role: 'system', content: 'Reply with a JSON object {"sentiment": "positive" | "negative" | "neutral", "reason": string}.' },
    { role: 'user', content: 'The delivery was late but support fixed it in an hour.' },
  ],
  response_format: { type: 'json_object' },
  temperature: 0.2,
  max_tokens: 150,
});
const result = JSON.parse(resp.choices[0].message.content);
console.log(result.sentiment, '-', result.reason);

```

## Tools dan JSON: pertanyaan umum

### Apakah panggilan tool dikenai biaya tambahan?

Tidak ada biaya tersendiri. Definisi tool, panggilan, dan hasil yang Anda kirim kembali semuanya adalah token, ditagih seperti token lainnya. Anda membayar per token dari saldo Anda: token input dan output dihitung oleh tokenizer model itu sendiri dan ditagih sesuai harga model tersebut per 1M token. Panggilan yang berakhir dengan error tidak dikenai biaya.

### Apakah model bisa memanggil beberapa tool sekaligus?

Beberapa model mengembalikan lebih dari satu panggilan di `tool_calls`. Jalankan semuanya dan kirim satu pesan `tool` per panggilan sebelum request berikutnya.

### Apakah API menjalankan fungsi saya?

Tidak. Model hanya menyebutkan fungsi mana yang harus dipanggil dan dengan argumen apa; kode Anda yang menjalankannya. Tidak ada yang dieksekusi di sisi kami, dan tidak ada bagian dari pertukaran itu yang disimpan: Kami tidak menyimpan prompt Anda atau jawaban model: setelah respons terkirim, teksnya hilang. Setiap panggilan meninggalkan satu baris log berisi waktu, akun, model, dan jumlah token, yang dihapus setelah 30 hari.

---

LLMwithCrypto: LLMwithCrypto adalah LLM API yang kompatibel dengan OpenAI untuk model open-weight — DeepSeek V4 Pro, DeepSeek V4.1 Flash, DeepSeek R1, Qwen3.5 397B A17B, Qwen3 235B A22B Instruct, gpt-oss-120b, gpt-oss-20b, GLM-4.7, Llama 3.3 70B Instruct, Gemma 4 31B, Mistral Large 3, Mistral Small 4 — dibayar per token dari saldo kripto prabayar, 5% di bawah harga median host publik. Tanpa KYC: tanpa ID, tanpa selfie, tanpa dokumen. Prompt dan output tidak disimpan.
