Naar inhoud
lightbulb Welkom op de nieuwe kennisbank | We hebben de docs volledig vernieuwd met meer dan 160 features. Bekijk wat nieuw isarrow_forward

Function calling met de Gemini API

Leer hoe je tools en functies definieert die Gemini kan aanroepen om externe data op te halen of acties uit te voeren in je applicatie, met de actuele google-genai SDK.

Wat is function calling

Function calling (ook wel "tool use") is het mechanisme waarmee een taalmodel externe functies kan aanroepen om informatie op te halen of acties uit te voeren die buiten zijn training vallen. Het model voert die functies niet zelf uit: het geeft aan welke functie met welke argumenten aangeroepen moet worden. Jouw code voert de functie uit en stuurt het resultaat terug.

Dit maakt Gemini geschikt voor live data opvragen (weer, beurskoersen, databases), acties uitvoeren (e-mail versturen, agenda-items aanmaken), externe APIs aanroepen en bedrijfslogica integreren.

info

Welke SDK gebruik je?

De codevoorbeelden hieronder gebruiken de actuele google-genai SDK (from google import genai). De oudere google.generativeai-bibliotheek wordt niet meer aanbevolen voor nieuwe projecten. Installeren doe je met pip install google-genai. Als modelnaam gebruiken we gemini-3.5-flash (de aanbevolen Flash-variant in juni 2026); gemini-2.5-flash werkt ook nog en is goedkoper.

De function calling cyclus

De cyclus bestaat uit zes stappen:

  1. Definieer je tools als JSON Schema of als Python-functie.
  2. Stuur de prompt plus tools naar Gemini.
  3. Gemini geeft een functionCall-response terug.
  4. Jouw code voert de bijbehorende functie uit.
  5. Stuur het function-resultaat terug naar Gemini.
  6. Gemini formuleert het eindantwoord voor de gebruiker.

Client en functie definiëren

Je maakt eerst een client aan. Die leest de API-sleutel standaard uit de omgevingsvariabele GEMINI_API_KEY. Een functie declareer je als JSON Schema met een duidelijke naam, beschrijving en parameters.

import os
from google import genai
from google.genai import types

client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])

get_weather = {
    "name": "get_weather",
    "description": "Haalt de huidige weersomstandigheden op voor een opgegeven stad.",
    "parameters": {
        "type": "object",
        "properties": {
            "city": {
                "type": "string",
                "description": "De naam van de stad, bijvoorbeeld Amsterdam",
            },
            "unit": {
                "type": "string",
                "enum": ["celsius", "fahrenheit"],
                "description": "De temperatuureenheid",
            },
        },
        "required": ["city"],
    },
}

tools = types.Tool(function_declarations=[get_weather])
config = types.GenerateContentConfig(tools=[tools])

De cyclus handmatig uitvoeren

Hieronder zie je de volledige heen-en-weer-cyclus. Je leest de function_call uit het antwoord, voert je eigen functie uit en stuurt het resultaat terug met types.Part.from_function_response.

contents = [
    types.Content(role="user", parts=[types.Part(text="Wat is het weer in Amsterdam?")])
]

response = client.models.generate_content(
    model="gemini-3.5-flash",
    contents=contents,
    config=config,
)

part = response.candidates[0].content.parts[0]

if part.function_call:
    fc = part.function_call
    print(f"Functie: {fc.name}")
    print(f"Argumenten: {dict(fc.args)}")

    weather_data = {"temperature": 15, "condition": "bewolkt", "humidity": 75}

    function_response_part = types.Part.from_function_response(
        name=fc.name,
        response={"result": weather_data},
    )

    contents.append(response.candidates[0].content)
    contents.append(types.Content(role="user", parts=[function_response_part]))

    final_response = client.models.generate_content(
        model="gemini-3.5-flash",
        contents=contents,
        config=config,
    )
    print(final_response.text)
warning

Bewaar de volledige modelbeurt

Voeg altijd response.candidates[0].content (de beurt met de functionCall) terug toe aan contents voordat je het function_response-deel toevoegt. Bij Gemini 3-modellen bevat die beurt een interne thought-signature die nodig is om de aanroep correct te koppelen. Laat je hem weg, dan kan het model de functie-uitkomst niet goed verwerken.

Meerdere tools definiëren

Je kunt meerdere functies in één tool-lijst aanbieden. Gemini kiest zelf welke (en hoeveel) het aanroept.

def get_product_price(product_id: str) -> dict:
    prices = {"P001": 29.99, "P002": 49.99, "P003": 19.99}
    return {"product_id": product_id, "price": prices.get(product_id, 0)}

def check_stock(product_id: str) -> dict:
    stock = {"P001": 5, "P002": 0, "P003": 23}
    return {"product_id": product_id, "in_stock": stock.get(product_id, 0) > 0}

product_tools = types.Tool(function_declarations=[
    {
        "name": "get_product_price",
        "description": "Geeft de prijs van een product op basis van het product-ID.",
        "parameters": {
            "type": "object",
            "properties": {
                "product_id": {"type": "string", "description": "Het product-ID"}
            },
            "required": ["product_id"],
        },
    },
    {
        "name": "check_stock",
        "description": "Controleert of een product op voorraad is.",
        "parameters": {
            "type": "object",
            "properties": {
                "product_id": {"type": "string", "description": "Het product-ID"}
            },
            "required": ["product_id"],
        },
    },
])
lightbulb

Schrijf scherpe beschrijvingen

Gemini gebruikt het description-veld van elke functie en parameter om te beslissen wanneer en hoe een functie aangeroepen wordt. Vage beschrijvingen leiden tot verkeerde of overbodige aanroepen. Beschrijf concreet wat de functie doet en geef bij elke parameter een voorbeeld, bijvoorbeeld een datumnotatie als 2026-07-29.

Automatische functie-uitvoering

Geef je gewone Python-functies door als tools (in plaats van JSON Schema), dan voert de SDK de aanroepen automatisch voor je uit en handelt de hele cyclus zelf af. De SDK leidt het schema af uit de type-hints en de docstring, dus schrijf die zorgvuldig.

def get_weather_impl(city: str, unit: str = "celsius") -> dict:
    """Haalt het huidige weer op voor een stad.

    Args:
        city: De naam van de stad, bijvoorbeeld Rotterdam.
        unit: De temperatuureenheid, celsius of fahrenheit.

    Returns:
        Een dict met temperatuur en conditie.
    """
    return {"temperature": 15, "condition": "bewolkt", "city": city}

config = types.GenerateContentConfig(tools=[get_weather_impl])

response = client.models.generate_content(
    model="gemini-3.5-flash",
    contents="Wat is het weer in Rotterdam en Utrecht?",
    config=config,
)
print(response.text)

Wil je de automatische modus uitzetten en de cyclus zelf beheren, geef dan automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True) mee in de config.

Tool-keuze afdwingen

Met een ToolConfig stuur je af of het model wel of geen tool mag kiezen. Dit gebeurt via function_calling_config.

config = types.GenerateContentConfig(
    tools=[tools],
    tool_config=types.ToolConfig(
        function_calling_config=types.FunctionCallingConfig(
            mode="ANY",
            allowed_function_names=["get_weather"],
        )
    ),
)

De beschikbare modi:

  • AUTO: het model beslist zelf of het een tool aanroept (standaard).
  • ANY: het model roept altijd een tool aan; met allowed_function_names beperk je de keuze.
  • VALIDATED: het model kiest tussen een geldige functie-aanroep of tekst (standaard bij sommige tool-combinaties).
  • NONE: het model roept nooit een tool aan.

Praktijkvoorbeeld: orderstatus opvragen

Een veelvoorkomend patroon is een supportbot die een orderstatus uit je eigen database haalt. Je definieert één functie, laat de SDK die automatisch uitvoeren, en valideert het ID voordat je de database raadpleegt.

def get_order_status(order_id: str) -> dict:
    """Geeft de status van een bestelling op basis van het order-ID.

    Args:
        order_id: Het order-ID in de vorm ORD-12345.
    """
    if not order_id.startswith("ORD-"):
        return {"error": "Ongeldig order-ID. Verwacht formaat: ORD-12345."}
    fake_db = {"ORD-12345": "verzonden", "ORD-67890": "in behandeling"}
    return {"order_id": order_id, "status": fake_db.get(order_id, "niet gevonden")}

config = types.GenerateContentConfig(tools=[get_order_status])

response = client.models.generate_content(
    model="gemini-3.5-flash",
    contents="Kun je de status van bestelling ORD-12345 opzoeken?",
    config=config,
)
print(response.text)

Doordat de functie zelf het ID valideert en bij twijfel een nette foutmelding teruggeeft, blijft de bot voorspelbaar, ook als de gebruiker een onzinnig ID noemt.

Kan Gemini meerdere functies tegelijk aanroepen?

Ja. Gemini kan in één antwoord meerdere functionCall-parts teruggeven (parallel function calling). Voer alle aanroepen uit en stuur alle bijbehorende function_response-parts samen terug in de volgende beurt.

Hoe voorkom ik dat Gemini een functie met onjuiste argumenten aanroept?

Definieer parameter-types en beschrijvingen nauwkeurig en markeer verplichte velden met required. Valideer de argumenten daarnaast altijd in je eigen implementatie voordat je iets uitvoert, want het model kan ondanks het schema af en toe afwijken.

Kan ik ook functies met bijwerkingen laten aanroepen, zoals schrijven of verwijderen?

Ja, maar bouw een bevestigingsstap in voor destructieve acties. Laat Gemini de actie voorstellen, toon de gebruiker exact wat er gaat gebeuren, en voer pas uit na expliciete bevestiging. Gebruik desnoods de mode NONE zodra je in de bevestigingsfase zit.

Wat als mijn functie een fout geeft?

Stuur de fout terug als function_response met een error-veld in plaats van een resultaat. Gemini kan die fout dan verwerken, de gebruiker informeren of een alternatieve aanpak voorstellen.

Werkt de oude google.generativeai code nog?

Die oudere bibliotheek wordt niet meer aanbevolen voor nieuwe projecten. Stap over op de google-genai SDK (from google import genai). De belangrijkste verschillen: je werkt met een client, roept client.models.generate_content aan en geeft tools mee via types.GenerateContentConfig.

Welk model kan ik het beste gebruiken voor function calling?

Voor agentische taken en function calling is gemini-3.5-flash in juni 2026 een sterke en snelle keuze. Heb je minder zware taken of wil je kosten besparen, dan voldoet gemini-2.5-flash of gemini-2.5-flash-lite ook. De API-aanroepen zelf blijven identiek; alleen de modelnaam verschilt.