# Tool calling en JSON-output met open-weight modellen

> Function calling met open-weight modellen in het OpenAI-formaat: tools, tool_choice, de call-and-answer-loop en response_format voor geldige JSON-output.

- URL: https://llmwithcrypto.com/nl/docs/tool-calling/
- Laatst bijgewerkt: 2026-10-23
- Uitgever: LLMwithCrypto (https://llmwithcrypto.com)

Het model kan je code vragen om een functie uit te voeren en het resultaat vervolgens in zijn antwoord gebruiken; of het kan antwoorden met een JSON-object dat je programma direct leest. Beide gebruiken het OpenAI-aanvraagformaat, en beide hangen af van het model dat je kiest.

**Snel antwoord — Hoe werkt tool calling op LLMwithCrypto?**

Stuur je functies mee in `tools`, in het OpenAI-formaat. Als het model er een wil, geeft **LLMwithCrypto** `finish_reason: "tool_calls"` terug met de functienaam en JSON-argumenten; je code voert die uit en stuurt het resultaat terug als een `tool`-bericht. Voor gestructureerde antwoorden vraagt `response_format: {"type": "json_object"}` om geldige JSON. Beide werken op de modellen die ze ondersteunen, zoals gedocumenteerd op 23 oktober 2026.

## Welke modellen ondersteunen tools en JSON?

Streaming werkt op elk model; tool calling en JSON-output volgen wat elk model zelf ondersteunt.

Test je eigen schema op het model dat je van plan bent te gebruiken voordat je erop vertrouwt. Een model dat geen tools ondersteunt, antwoordt in platte tekst in plaats van de functie aan te roepen; een model dat geen JSON-modus ondersteunt, geeft een `400`-fout voor `response_format`.

## Wat is de loop?

1. **Beschrijf de functies** — Elke tool heeft een name, een description die het model leest om te beslissen wanneer het de tool gebruikt, en parameters als JSON Schema.
2. **Stuur het gesprek mee met tools** — Het model antwoordt ofwel in tekst, ofwel stopt met finish_reason: "tool_calls" en een of meer calls in message.tool_calls.
3. **Voer elke call uit** — Parseer function.arguments (een JSON-string), voer je functie uit en vertrouw de argumenten nooit blind: valideer ze zoals elke gebruikersinvoer.
4. **Stuur de resultaten terug** — Voeg het assistant-bericht toe en daarna één tool-bericht per call met zijn tool_call_id en het resultaat als tekst. Roep de API opnieuw aan; herhaal tot het model in tekst antwoordt.

*Python: een complete tool-loop met 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)})

```

## Hoe ziet een tool call eruit in het antwoord?

Het assistant-bericht heeft geen tekst, een `tool_calls`-array, en de keuze eindigt met `finish_reason: "tool_calls"`. De argumenten komen als een JSON-string, niet als een object. De ids en tellingen hieronder zijn illustratief.

*Antwoord dat om een functieaanroep vraagt (illustratief)*

```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
  }
}

```

## Hoe bepaal ik wanneer tools worden gebruikt?

- **`"tool_choice": "auto"`** (de standaard wanneer `tools` is ingesteld): het model beslist.
- **`"tool_choice": "none"`**: het model antwoordt in tekst ook al zijn er tools opgegeven.
- **`"tool_choice": "required"`**: het model moet minstens één tool aanroepen.
- **`{"type": "function", "function": {"name": "get_order_status"}}`**: het model moet precies die ene aanroepen.

Elke tooldefinitie wordt bij elke call als input meegestuurd, dus lange beschrijvingen en veel tools verhogen de input-tokens. Houd beschrijvingen kort en stuur alleen de tools mee die een stap nodig heeft.

## Hoe krijg ik geldige JSON terug?

Zet `response_format` op `{"type": "json_object"}` en beschrijf de verwachte keys in het system-bericht: JSON-modus garandeert dat het antwoord parseert, niet dat het de keys heeft die je wilt. Houd `temperature` laag voor stabiele output en controleer het geparseerde object in je code voordat je het gebruikt.

*Node.js: een JSON-antwoord met 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 en JSON: veelgestelde vragen

### Kosten tool calls extra?

Geen eigen toeslag. De tooldefinities, de call en de resultaten die je terugstuurt zijn allemaal tokens, net als elke andere. Je betaalt per token vanaf je saldo: input- en outputtokens worden geteld door de tokenizer van het model zelf en afgerekend tegen de prijs van dat model per 1M tokens. Een call die op een fout eindigt, kost niets.

### Kan het model meerdere tools tegelijk aanroepen?

Sommige modellen geven meer dan één call terug in `tool_calls`. Voer ze allemaal uit en stuur één `tool`-bericht per call voordat je het volgende verzoek doet.

### Voert de API mijn functies uit?

Nee. Het model zegt alleen welke functie met welke argumenten moet worden aangeroepen; je code voert die uit. Aan onze kant wordt niets uitgevoerd en niets van de uitwisseling opgeslagen: We bewaren je prompts en de antwoorden van het model niet: zodra een response is verstuurd, is de tekst weg. Elke call laat één logregel achter met de tijd, het account, het model en de tokentellingen, die na 30 dagen wordt verwijderd.

---

LLMwithCrypto: LLMwithCrypto is een OpenAI-compatibele LLM API voor open-weight modellen — 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 — betaald per token vanaf een prepaid crypto-saldo, tegen 5% onder de mediane prijs van de publieke hosts. Zonder KYC: geen ID, geen selfie, geen documenten. Prompts en outputs worden niet opgeslagen.
