Weergave
Tool Calling
Tool calling (ook bekend als function calling) geeft AI modellen de mogelijkheid om externe functies aan te roepen. Dit is nuttig voor:
- Realtime data ophalen (weer, stocks, etc.)
- Acties uitvoeren (emails versturen, database queries)
- Berekeningen uitvoeren
- Externe API's aanroepen
De tool calling flow
Tool calling is een multi-step conversatie:
- Request met tools - Stuur een request met tool definities
- Tool call ontvangen - Model retourneert welke tool het wil aanroepen
- Tool uitvoeren - Jouw code voert de tool uit
- Resultaat terugsturen - Stuur het resultaat als
toolmessage - Finale response - Model geeft antwoord met de tool output
Belangrijk
De server voert tools niet uit. Jouw applicatie is verantwoordelijk voor het uitvoeren van de tools en het terugsturen van de resultaten.
Tool definitie
Een tool wordt gedefinieerd met een JSON schema:
python
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Haal het huidige weer op voor een locatie",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Stad en land, bijv. Amsterdam, Nederland"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperatuur eenheid"
}
},
"required": ["location"]
}
}
}
]Tool definitie velden
| Veld | Type | Beschrijving |
|---|---|---|
type | string | Altijd "function" |
function.name | string | Naam van de functie |
function.description | string | Beschrijving wanneer de tool te gebruiken |
function.parameters | object | JSON Schema voor de parameters |
Basis voorbeeld
python
from vondr import VondrClient
import json
client = VondrClient()
# Definieer de tool
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Haal het huidige weer op voor een locatie",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "Stad naam"}
},
"required": ["location"]
}
}
}]
# Stuur request met tools
response = client.chat(
messages=[{"role": "user", "content": "Wat is het weer in Amsterdam?"}],
tools=tools
)
choice = response.choices[0]
# Check of het model een tool wil aanroepen
if choice.message.tool_calls:
tool_call = choice.message.tool_calls[0]
print(f"Model wil {tool_call.function.name} aanroepen")
print(f"Met argumenten: {tool_call.function.arguments}")Complete tool calling flow
Het volgende voorbeeld toont de volledige flow: request, tool uitvoering, en finale response.
python
from vondr import VondrClient
import json
client = VondrClient()
def get_weather(location: str) -> dict:
"""Jouw implementatie van de weather functie"""
# In productie zou je hier een echte API aanroepen
return {"temperature": 18, "condition": "bewolkt", "location": location}
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Haal het huidige weer op",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"]
}
}
}]
messages = [{"role": "user", "content": "Wat is het weer in Amsterdam?"}]
# Stap 1: Eerste request
response = client.chat(messages=messages, tools=tools)
choice = response.choices[0]
if choice.message.tool_calls:
tool_call = choice.message.tool_calls[0]
# Stap 2: Voer de tool uit
args = json.loads(tool_call.function.arguments)
result = get_weather(**args)
# Stap 3: Voeg assistant message en tool result toe aan history
messages.extend([
{
"role": "assistant",
"content": None,
"tool_calls": [{
"id": tool_call.id,
"type": "function",
"function": {
"name": tool_call.function.name,
"arguments": tool_call.function.arguments
}
}]
},
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
}
])
# Stap 4: Krijg finale response
final_response = client.chat(messages=messages, tools=tools)
print(final_response.choices[0].message.content)
# Output: "Het weer in Amsterdam is 18°C en bewolkt."Tool choice
Met tool_choice bepaal je hoe het model met tools omgaat:
python
# Auto (standaard) - Model kiest zelf of het tools gebruikt
response = client.chat(
messages=messages,
tools=tools,
tool_choice="auto"
)
# Required - Model moet een tool aanroepen
response = client.chat(
messages=messages,
tools=tools,
tool_choice="required"
)
# Specifieke tool forceren
response = client.chat(
messages=messages,
tools=tools,
tool_choice={"type": "function", "function": {"name": "get_weather"}}
)tool_choice opties
| Waarde | Beschrijving |
|---|---|
"auto" | Model kiest zelf of het een tool aanroept (standaard) |
"none" | Model mag geen tools aanroepen |
"required" | Model moet minimaal één tool aanroepen |
{"type": "function", "function": {"name": "..."}} | Forceer een specifieke tool |
Meerdere tools
Je kunt meerdere tools beschikbaar stellen:
python
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Haal het huidige weer op voor een locatie",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "Voer een wiskundige berekening uit",
"parameters": {
"type": "object",
"properties": {"expression": {"type": "string"}},
"required": ["expression"]
}
}
}
]
# Model kiest de juiste tool gebaseerd op de vraag
response = client.chat(
messages=[{"role": "user", "content": "Wat is 25 * 4?"}],
tools=tools
)
# Model zal de calculate tool kiezenResponse object
Bij een tool call bevat de response:
python
# Check of er tool calls zijn
if response.choices[0].message.tool_calls:
for tool_call in response.choices[0].message.tool_calls:
print(f"ID: {tool_call.id}")
print(f"Type: {tool_call.type}") # "function"
print(f"Naam: {tool_call.function.name}")
print(f"Argumenten: {tool_call.function.arguments}") # JSON string
# finish_reason is "tool_calls" bij een tool aanroep
print(response.choices[0].finish_reason) # "tool_calls"Tool call velden
| Veld | Type | Beschrijving |
|---|---|---|
id | string | Unieke identifier voor deze call |
type | string | Altijd "function" |
function.name | string | Naam van de aangeroepen tool |
function.arguments | string | JSON string met de argumenten |
Tool dispatcher patroon
Voor meerdere tools kun je een dispatcher gebruiken:
python
from vondr import VondrClient
import json
client = VondrClient()
# Registreer je tool functies
tool_functions = {
"get_weather": lambda location: {"temp": 18, "location": location},
"calculate": lambda expression: {"result": eval(expression)},
"search": lambda query: {"results": [f"Result for: {query}"]},
}
def execute_tool(name: str, arguments: dict):
"""Voer een tool uit op basis van naam."""
if name not in tool_functions:
return {"error": f"Onbekende tool: {name}"}
return tool_functions[name](**arguments)
# Na het ontvangen van een tool call
if choice.message.tool_calls:
for tool_call in choice.message.tool_calls:
args = json.loads(tool_call.function.arguments)
result = execute_tool(tool_call.function.name, args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})Best practices
1. Duidelijke beschrijvingen
Geef tools en parameters heldere beschrijvingen zodat het model weet wanneer ze te gebruiken:
python
{
"name": "search_products",
"description": "Zoek producten in de catalogus op basis van naam, categorie of prijs. Gebruik dit wanneer de gebruiker vraagt naar producten of wil winkelen.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Zoekterm voor productnaam of beschrijving"
},
"category": {
"type": "string",
"enum": ["elektronica", "kleding", "boeken"],
"description": "Productcategorie om in te zoeken"
},
"max_price": {
"type": "number",
"description": "Maximum prijs in euro's"
}
},
"required": ["query"]
}
}2. Valideer argumenten
Check altijd de argumenten voordat je de tool uitvoert:
python
def get_weather(location: str) -> dict:
if not location or len(location) < 2:
return {"error": "Ongeldige locatie"}
# Voer de tool uit...3. Geef duidelijke foutmeldingen
Retourneer nuttige foutmeldingen als tool output:
python
try:
result = execute_tool(name, args)
except ValueError as e:
result = {"error": f"Ongeldige invoer: {e}"}
except Exception as e:
result = {"error": f"Tool uitvoering mislukt: {e}"}4. Minimale tools
Gebruik alleen tools die relevant zijn voor de huidige taak. Te veel tools kan het model verwarren.
5. Idempotent waar mogelijk
Maak tools die veilig opnieuw uitgevoerd kunnen worden bij retries.
Foutafhandeling
python
import json
if choice.message.tool_calls:
tool_call = choice.message.tool_calls[0]
try:
args = json.loads(tool_call.function.arguments)
result = execute_tool(tool_call.function.name, args)
content = json.dumps(result)
except json.JSONDecodeError:
content = json.dumps({"error": "Ongeldige argumenten van model"})
except KeyError as e:
content = json.dumps({"error": f"Ontbrekend argument: {e}"})
except Exception as e:
content = json.dumps({"error": str(e)})
# Stuur resultaat (of fout) terug
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": content
})Asynchrone versie
python
from vondr import AsyncVondrClient
import json
client = AsyncVondrClient()
async def async_get_weather(location: str) -> dict:
# Async API call
return {"temperature": 18, "location": location}
response = await client.chat(
messages=[{"role": "user", "content": "Wat is het weer in Amsterdam?"}],
tools=tools
)
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
# Async tool uitvoering
result = await async_get_weather(**args)
messages.extend([
{
"role": "assistant",
"content": None,
"tool_calls": [{
"id": tool_call.id,
"type": "function",
"function": {
"name": tool_call.function.name,
"arguments": tool_call.function.arguments
}
}]
},
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
}
])
final_response = await client.chat(messages=messages, tools=tools)
print(final_response.choices[0].message.content)