API e SDKGuida
Function calling in Python con un'API compatibile con OpenAI
Invia i tool, leggi tool_calls e restituisci il risultato con role tool: un ciclo di function calling in due passaggi in Python con MiniMax-M2.7.

In questa pagina
Il function calling (tool calling) consente a un modello di chiedere al tuo codice di eseguire una funzione. Invii una lista tools con la richiesta, il modello risponde con tool_calls invece che con del testo, esegui tu stesso la funzione e rimandi il suo risultato in un messaggio con role: tool. Il modello scrive poi la risposta finale. Questa guida mostra l'intero ciclo in Python verso l'endpoint compatibile con OpenAI https:/ con MiniMax-M2.7 (id MiniMaxAI/, contesto 180K, fino a 8.192 token di output per risposta).
Il tool calling è indicato come supportato per ogni modello del catalogo (CheapTokens docs, verificato il 22 ottobre 2026). Ti serve una chiave API; se non hai ancora fatto una richiesta, inizia con la tua prima richiesta API.
Come funziona il function calling#
Il modello non esegue mai nulla. Produce solo una richiesta strutturata: "chiama get_weather con {\"city\": \"Paris\"}". Il tuo programma fa il lavoro vero e riporta il risultato. Questo crea un ciclo di due richieste:
- Richiesta 1. Invii il messaggio dell'utente più la lista
tools. Il modello risponde in testo oppure restituisce una o piùtool_calls. - Il tuo codice. Analizzi ogni chiamata, esegui la funzione corrispondente e raccogli il risultato.
- Richiesta 2. Invii di nuovo l'intera conversazione: i messaggi originali, il messaggio dell'assistente con
tool_callse un messaggiorole: toolper ogni chiamata. Il modello usa i risultati per scrivere la risposta finale.
Ogni richiesta reinvia tutta la cronologia, quindi i cicli di tool consumano più token di input rispetto a una singola domanda. Se l'argomento è nuovo per te, leggi cos'è un token.
Configura il client#
Installa l'SDK OpenAI (pip install openai) e metti la chiave in una variabile d'ambiente invece che nel codice sorgente:
export CHEAPTOKENS_API_KEY="your-key-here"La base URL è https:/. Prendi l'id del modello dalla documentazione CheapTokens: provider diversi chiamano lo stesso modello in modi diversi. Questa guida usa MiniMaxAI/.
Dichiara una funzione e invia la prima richiesta#
Una funzione è descritta nell'array tools. Ogni voce ha type: function e un oggetto function con name, description e parameters scritti come JSON Schema. La descrizione è ciò che il modello legge per decidere quando chiamare la funzione, quindi scrivila come una frase breve e concreta.
Qui sotto c'è uno script completo. La funzione meteo è uno stub con dati fittizi, così l'esempio non richiede servizi aggiuntivi:
import json
import os
from openai import OpenAI
client = OpenAI(
base_url='https://api.cheaptokens.dev/v1',
api_key=os.environ['CHEAPTOKENS_API_KEY'],
)
MODEL = 'MiniMaxAI/MiniMax-M2.7'
def get_weather(city: str) -> dict:
# Stub with fake data: replace with a real lookup
fake = {'Paris': 14, 'Tokyo': 19}
return {'city': city, 'temp_c': fake.get(city, 10)}
FUNCTIONS = {'get_weather': get_weather}
tools = [
{
'type': 'function',
'function': {
'name': 'get_weather',
'description': 'Get the current temperature in Celsius for a city.',
'parameters': {
'type': 'object',
'properties': {
'city': {'type': 'string', 'description': 'City name, for example Paris'},
},
'required': ['city'],
},
},
}
]
messages = [{'role': 'user', 'content': 'What is the weather in Paris right now?'}]
# Step 1: the model decides whether to call a function
first = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
message = first.choices[0].message
if not message.tool_calls:
print(message.content)
raise SystemExit
# Step 2: run every requested call and send the results back
messages.append(message)
for call in message.tool_calls:
args = json.loads(call.function.arguments)
result = FUNCTIONS[call.function.name](**args)
messages.append({
'role': 'tool',
'tool_call_id': call.id,
'content': json.dumps(result),
})
final = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
print(final.choices[0].message.content)Tre dettagli decidono se il ciclo funziona:
call.è una stringa JSON, non un dizionario. Analizzala confunction. arguments json.loads.- Ogni messaggio
role: tooldeve portare iltool_call_iddella chiamata a cui risponde, cioècall.id. - Il
contentdi un messaggio tool è una stringa. Usajson.dumpsper risultati strutturati.
Cosa dovresti vedere#
Se stampi i campi dopo la prima richiesta, appaiono così (l'id della chiamata cambia a ogni esecuzione):
finish_reason: tool_calls
call.id: call_abc123
call.function.name: get_weather
call.function.arguments: {"city": "Paris"}Lo script stampa poi la risposta finale, una frase semplice del tipo "Al momento ci sono 14 °C a Parigi." La formulazione cambia da un'esecuzione all'altra; il numero proviene dalla tua funzione.
Più chiamate e cicli più lunghi#
Un modello può restituire più di una chiamata in una singola risposta, per esempio quando chiedi il meteo in due città. Per questo l'esempio itera su message. e risponde a ogni chiamata con il suo id. La guida al function calling di OpenAI descrive lo stesso comportamento: con il valore predefinito tool_choice di auto il modello può chiamare zero, una o più funzioni (OpenAI docs, verificato il 22 ottobre 2026; la pagina non ha una data di ultimo aggiornamento e descrive la forma più recente della Responses API, mentre questa guida usa la forma Chat Completions dell'endpoint /).
Gli agenti ripetono i due passaggi finché il modello smette di chiedere tool. Avvolgi le richieste in un ciclo e imposta sempre un limite di passaggi:
for _ in range(5): # safety limit against endless loops
response = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
message = response.choices[0].message
if not message.tool_calls:
print(message.content)
break
messages.append(message)
for call in message.tool_calls:
args = json.loads(call.function.arguments)
result = FUNCTIONS[call.function.name](**args)
messages.append({'role': 'tool', 'tool_call_id': call.id, 'content': json.dumps(result)})Se vuoi che la risposta appaia token per token, combinalo con lo streaming in Python.
Perché MiniMax-M2.7 è adatto ai cicli di tool#
Un ciclo di tool invia molte richieste con una cronologia che cresce. Per questo pattern CheapTokens offre MiniMax-M2.7: contesto 180K, fino a 8.192 token di output per risposta, un unico prezzo a qualsiasi ora del giorno senza fasce di punta e un unico saldo per tutti i modelli. Contando insieme input e output, è più economico del prezzo di riferimento di OpenRouter (confronto prezzi CheapTokens, verificato il 31 ottobre 2026).
Prezzi attuali per 1M di token: input $0.05, output $0.15. Come carico di esempio (non una misurazione), il round trip a due richieste qui sopra con circa 2.700 token di input e 350 di output in totale costa $0.00019. L'elenco completo dei prezzi è nella pagina dei prezzi.
Per provare un altro modello, cambia solo l'id; l'elenco degli id è nella pagina dei modelli.
Se non funziona#
message.ètool_ calls None. Il modello ha risposto in testo. Rendi la funzionedescriptionpiù specifica e assicurati che la domanda richieda davvero la funzione.json.suJSONDecodeError arguments. Il modello ha prodotto JSON non valido. Avvolgijson.loadsintry/excepte rimanda il testo dell'errore come risultato del tool, così il modello può riprovare con argomenti corretti.- La seconda richiesta fallisce o il modello ignora il risultato. Verifica che ogni chiamata abbia esattamente un messaggio
role: toolcon untool_call_idcorrispondente e che il messaggio dell'assistente contool_callssia nella cronologia prima di questi. KeyErrorinFUNCTIONS[...]. Il modello ha indicato una funzione che non hai registrato. Restituisci una breve stringa di errore come risultato del tool invece di andare in crash.- La risposta è troncata. Controlla
finish_reason: il valorelengthsignifica che è stato raggiunto il limite di token di output. Vedi perché una risposta AI si interrompe a metà frase. - Errori 401 o di autenticazione. Verifica che la chiave sia in
CHEAPTOKENS_e che la base URL termini conAPI_ KEY /v1.
Prossimi passi#
Sostituisci lo stub con una funzione reale: una query al database, una chiamata di ricerca o una calcolatrice. Aggiungi altre voci a tools e a FUNCTIONS e mantieni breve ogni risultato delle funzioni, perché torna nella cronologia a ogni richiesta successiva. Per ottenere una chiave e fare la prima chiamata, apri la documentazione CheapTokens.



