Il function calling (o tool calling) è il meccanismo che permette a un modello di chat di Azure OpenAI di interfacciarsi con codice, API e dati esterni in modo strutturato. Invece di rispondere solo con testo libero, il modello può indicare all’applicazione quale funzione invocare e con quali argomenti, restando però sempre dentro un contratto definito da voi.

Il ciclo di vita di una tool call

Il pattern si articola in quattro fasi, ed è fondamentale interiorizzarne il flusso per l’esame.

  1. Definizione degli strumenti. Nella richiesta di chat completions si passa un array tools, dove ogni tool è di tipo function e descrive nome, descrizione e uno schema JSON dei parametri (con type, properties, required). La qualità di descrizione e schema guida direttamente la scelta del modello.
  2. Proposta del modello. Se il modello ritiene utile uno strumento, la risposta non contiene content testuale ma un oggetto tool_calls con il nome della funzione e gli argomenti serializzati in JSON. Il campo finish_reason vale tool_calls.
  3. Esecuzione lato applicazione. L’app fa il parsing degli argomenti, li valida ed esegue la logica reale (query a un DB, chiamata REST, ecc.). Questa parte è interamente vostra responsabilità.
  4. Ritorno del risultato. Si aggiunge alla conversazione un messaggio con role: "tool" che riporta l’output della funzione e il tool_call_id corrispondente, poi si richiama il modello. Il modello incorpora il risultato e formula la risposta finale in linguaggio naturale.
"tool_calls": [{
  "id": "call_abc",
  "type": "function",
  "function": { "name": "get_weather", "arguments": "{\"city\":\"Milano\"}" }
}]

Controllo del comportamento

Il parametro tool_choice governa la selezione: auto (default) lascia decidere il modello, required obbliga a chiamare almeno uno strumento, none disabilita le tool call, e si può forzare una funzione specifica passandone il nome. Nei modelli e API più recenti si preferisce il termine tool rispetto al deprecato functions/function_call.

Function calling vs structured outputs

Sono meccanismi complementari ma distinti:

  • Il function calling serve quando il modello deve agire verso l’esterno, scegliendo se e quale strumento usare.
  • Gli structured outputs (e la più semplice JSON mode) servono quando volete che la risposta finale al vostro utente rispetti uno schema. Con response_format di tipo json_schema e strict: true il modello è vincolato a produrre JSON conforme, utile per estrazione dati e integrazione con sistemi a valle.
  • La JSON mode garantisce JSON sintatticamente valido ma non l’aderenza a uno schema; per quella serve structured outputs.

Regola pratica d’esame: se lo scenario è “chiama un servizio/recupera dati in tempo reale” → function calling; se è “restituisci un oggetto tipizzato prevedibile” → structured outputs.

Orchestrazione e scenari agent

Il loop tool call → esecuzione → ritorno è il mattone base degli agent. In scenari con più passaggi o più strumenti concatenati, l’orchestrazione può essere gestita manualmente oppure delegata a Azure AI Foundry Agent Service, che integra tool calling, knowledge retrieval e gestione dello stato della conversazione. Il modello può inoltre emettere parallel tool calls, cioè più chiamate nella stessa risposta, che vanno eseguite (idealmente in parallelo) e ritornate ciascuna con il proprio tool_call_id.

Trappole tipiche d’esame

  • Scenario: “il modello ha risposto con una tool call, l’operazione è quindi eseguita?” → No. Il modello propone solo la chiamata; è l’applicazione che deve eseguire la funzione e restituire il risultato con un messaggio role: "tool".
  • Scenario: gli argomenti generati contengono un valore fuori range o una query potenzialmente pericolosa → l’app deve validare gli argomenti e applicare i controlli di sicurezza/autorizzazione: il modello non offre garanzie sulla correttezza o sicurezza dei valori.
  • Scenario: serve solo un JSON aderente a uno schema per un output, senza chiamare servizi esterni → usare structured outputs (response_format con json_schema), non il function calling.
  • Scenario: il modello restituisce più tool_calls nella stessa risposta → sono parallel tool calls, da gestire esplicitamente eseguendole tutte e ritornando un messaggio tool per ciascun tool_call_id, altrimenti la conversazione risulta incoerente.
  • Scenario: il modello ignora uno strumento che dovrebbe usare → intervenire su descrizioni e schema JSON più chiari o forzare la selezione con tool_choice, non affidarsi solo al prompt di sistema.