Il tuo chatbot risponde con testo, ma non fa mai nulla: non prenota un volo, non cerca un prodotto, non aggiorna un database. Finché i tuoi modelli AI si limitano a generare parole, restano spettatori. Il function calling con Gemini API trasforma il tuo modello in un agente operativo: capisce quando chiamare una funzione, quali parametri passare e come elaborare il risultato. Noi, di Meteora Web, lo usiamo per automatizzare flussi di lavoro reali (prenotazioni, ordini, query CRM). In questa guida ti mostriamo come farlo funzionare, con codice che puoi copiare e adattare subito.
Perché usare il function calling con Gemini invece di generare testo libero?
Un modello AI che risponde solo in linguaggio naturale non può agire. Puoi chiedergli "cerca il biglietto più economico per Roma" ma lui ti risponderà con un testo generico, non con una prenotazione. Con il function calling, Gemini restituisce una richiesta strutturata: vuole chiamare search_flights(destinazione='Roma', budget=150). Tu esegui la chiamata e restituisci il risultato al modello. È come dare al modello un telefono: può fare cose.
Sponsored Protocol
I vantaggi sono concreti:
- Affidabilità: le funzioni producono dati reali, non allucinazioni.
- Integrazione: il modello si collega a database, API esterne, ERP.
- Cost control: paghi solo le chiamate API necessarie, senza giri a vuoto di prompt lunghi.
Come dichiarare le funzioni in Gemini API?
Le funzioni vengono descritte con uno schema JSON, simile a OpenAPI. Gemini usa queste definizioni per capire esistenza, parametri e tipo di ritorno. Ecco un esempio in Python:
from google import genai
from google.genai import types
client = genai.Client(api_key="YOUR_API_KEY")
# Definizione della funzione
search_tools = types.Tool(
function_declarations=[
types.FunctionDeclaration(
name="search_hotel",
description="Cerca hotel disponibili in una città per date specifiche",
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"city": types.Schema(type=types.Type.STRING, description="Nome della città, es. 'Palermo'"),
"checkin": types.Schema(type=types.Type.STRING, description="Data check-in formato YYYY-MM-DD"),
"checkout": types.Schema(type=types.Type.STRING, description="Data check-out formato YYYY-MM-DD"),
"max_price": types.Schema(type=types.Type.NUMBER, description="Prezzo massimo per notte in euro")
},
required=["city", "checkin", "checkout"]
)
)
]
)
Attenzione: i nomi delle funzioni devono essere unici e descrittivi. I parametri obbligatori vanno elencati in required. Se ometti, Gemini potrebbe non passarli.
Sponsored Protocol
Come gestire la risposta del modello e chiamare effettivamente le funzioni?
Il flusso è un loop a due passi:
Sponsored Protocol
- Invia il prompt + la lista di strumenti. Gemini risponde con una richiesta di chiamata funzione (
function_call) oppure con testo. - Se c'è un
function_call, esegui la funzione reale (es. query SQL, chiamata REST API) e restituisci il risultato comefunction_response. - Il modello riceve la risposta e produce il testo finale.
Ecco il codice Python che implementa il loop per la funzione search_hotel:
# Funzione reale che interroga un database (simulato)
def search_hotel(city, checkin, checkout, max_price=None):
# Qui fai una vera chiamata al tuo DB o API esterna
mock_results = [
{"name": "Hotel Sole e Mare", "price": 120, "city": city},
{"name": "B&B Centrale", "price": 85, "city": city}
]
if max_price:
mock_results = [h for h in mock_results if h["price"] <= max_price]
return mock_results
# Loop function calling
model = "gemini-2.0-flash" # o gemini-1.5-pro secondo disponibilità
tools = [search_tools]
messages = [
types.Content(role="user", parts=[types.Part(text="Trova hotel economici a Palermo dal 01-06-2026 al 05-06-2026")])
]
while True:
response = client.models.generate_content(
model=model,
contents=messages,
config=types.GenerateContentConfig(tools=tools)
)
if response.candidates[0].content.parts[0].function_call:
fc = response.candidates[0].content.parts[0].function_call
# Esegui la funzione
if fc.name == "search_hotel":
result = search_hotel(**fc.args)
# Prepariamo il response
function_resp = types.Part(
function_response=types.FunctionResponse(
name=fc.name,
response={"hotels": result}
)
)
messages.append(response.candidates[0].content)
messages.append(types.Content(role="function", parts=[function_resp]))
else:
# Risposta testuale finale
final_text = response.text
break
print(final_text)
Attenzione agli errori: la funzione reale può fallire (API down, timeout). In quel caso, restituisci un function_response con un campo error e lascia che il modello gestisca l'eccezione (es. "Mi dispiace, il servizio non risponde").
Esempio pratico: un agente che cerca hotel e prenota
Un caso reale: il cliente chiede "Vorrei prenotare una stanza all'Hotel Sole e Mare a Palermo dal 1 al 5 giugno per 2 adulti". Il modello deve prima cercare le disponibilità, poi effettuare la prenotazione. Dichiareremo due funzioni: search_hotel (già vista) e book_hotel.
# Aggiungiamo book_hotel alla lista
book_tool = types.Tool(
function_declarations=[
types.FunctionDeclaration(
name="book_hotel",
description="Effettua una prenotazione in un hotel specifico",
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"hotel_name": types.Schema(type=types.Type.STRING),
"checkin": types.Schema(type=types.Type.STRING),
"checkout": types.Schema(type=types.Type.STRING),
"guests": types.Schema(type=types.Type.INTEGER)
},
required=["hotel_name", "checkin", "checkout", "guests"]
)
)
]
)
# Aggiungiamo book_tool alla lista tools
all_tools = [search_tools, book_tool]
Nel loop, quando il modello chiama book_hotel, esegui la funzione e restituisci un ID di conferma. L'agente così diventa uno strumento composito: decide autonomamente la sequenza delle azioni.
Attenzione: imposta un limite massimo di iterazioni (es. 5) per evitare loop infiniti se il modello continua a chiamare funzioni.
Come evitare errori comuni nel tool use?
Abbiamo visto progetti arrivarci con questi errori ricorrenti:
- Timeout e retry: se la funzione reale impiega più di 30 secondi, Gemini potrebbe interrompere. Metti un timeout e restituisci un errore gestibile.
- Parametri mancanti: spesso il modello omette parametri opzionali. Definisci valori di default nella funzione reale.
- Sicurezza: non esporre mai API key o dati sensibili nelle definizioni delle funzioni. Gemini leggerà testualmente la descrizione.
- Logging: registra ogni chiamata a funzione e la risposta, per debugging e auditing.
- Costi: ogni turno di function calling consuma token di input/output. Tieni traccia con
response.usage_metadata.
Noi consigliamo di testare con un set di prompt di esempio prima di mettere in produzione. Usa il playground di Google AI Studio per validare gli schemi.
Cosa fare adesso
1. Scarica la chiave API da Google AI Studio (o Google Cloud Vertex AI) e abilita il modello Gemini 2.0 Flash (supporta function calling da subito).
2. Scrivi la tua prima funzione — inizia con una chiamata a un database finto o a un'API pubblica (es. meteo, cambio valuta).
3. Implementa il loop come nell'esempio sopra. Fai attenzione a gestire il caso di nessun function_call.
4. Aggiungi log e limiti di iterazioni per sicurezza.
5. Leggi la documentazione ufficiale di Google su Function Calling Gemini API per dettagli su modelli supportati e limiti.
Se vuoi una panoramica completa su Gemini API per sviluppatori, consulta la nostra Guida Pillar. Lì trovi contesto, confronti e casi d'uso più ampi.