Risposta rapida
Come funziona il tool calling su LLMwithCrypto?
Invia le tue funzioni in tools, nel formato OpenAI. Quando il modello ne vuole una, LLMwithCrypto restituisce finish_reason: "tool_calls" con il nome della funzione e gli argomenti JSON; il tuo codice la esegue e rimanda il risultato come messaggio tool. Per risposte strutturate, response_format: {"type": "json_object"} richiede JSON valido. Entrambi funzionano sui modelli che li supportano, come documentato il 23 ottobre 2026.
Quali modelli supportano tools e JSON?
Lo streaming funziona su ogni modello; il tool calling e l'output JSON seguono ciò che supporta il singolo modello.
Prova il tuo schema sul modello che pensi di usare prima di farci affidamento. Un modello che non supporta i tools risponde in testo semplice invece di chiamare la funzione; un modello che non supporta la modalità JSON restituisce un errore 400 per response_format.
Cos'è il ciclo?
Descrivi le funzioni
Ogni tool ha un
name, unadescriptionche il modello legge per decidere quando usarlo, eparameterscome JSON Schema.Invia la conversazione con i tools
Il modello o risponde in testo, oppure si ferma con
finish_reason: "tool_calls"e una o più chiamate inmessage.tool_calls.Esegui ogni chiamata
Fai il parsing di
function.arguments(una stringa JSON), esegui la tua funzione e non fidarti mai ciecamente degli argomenti: validali come qualsiasi input dell'utente.Rimanda i risultati
Aggiungi il messaggio dell'assistente, poi un messaggio
toolper ogni chiamata con il suotool_call_ide il risultato come testo. Richiama l'API; ripeti finché il modello non risponde in testo.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://llmwithcrypto.com/api/v1",
api_key=os.environ["LLMWITHCRYPTO_API_KEY"],
)
tools = [
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Return the delivery status of an order.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
},
}
]
def get_order_status(order_id):
return {"order_id": order_id, "status": "shipped", "eta": "2026-10-25"}
messages = [{"role": "user", "content": "Where is my order A-1042?"}]
while True:
resp = client.chat.completions.create(model="gpt-oss-120b", messages=messages, tools=tools, max_tokens=300)
msg = resp.choices[0].message
if not msg.tool_calls:
print(msg.content)
break
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_order_status(**args)
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
Come appare una chiamata a un tool nella risposta?
Il messaggio dell'assistente non ha testo, ha un array tool_calls, e la scelta termina con finish_reason: "tool_calls". Gli argomenti arrivano come stringa JSON, non come oggetto. Gli id e i conteggi qui sotto sono illustrativi.
{
"id": "chatcmpl-3c9d27e1",
"object": "chat.completion",
"created": 1792742400,
"model": "gpt-oss-120b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_7f31",
"type": "function",
"function": {
"name": "get_order_status",
"arguments": "{\"order_id\": \"A-1042\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 118,
"completion_tokens": 22,
"total_tokens": 140
}
}
Come controllo quando vengono usati i tools?
"tool_choice": "auto"(il default quandotoolsè impostato): decide il modello."tool_choice": "none": il modello risponde in testo anche se i tools sono elencati."tool_choice": "required": il modello deve chiamare almeno un tool.{"type": "function", "function": {"name": "get_order_status"}}: il modello deve chiamare proprio quello.
Ogni definizione di tool viene inviata come input a ogni chiamata, quindi descrizioni lunghe e molti tools aumentano i token di input. Tieni le descrizioni brevi e invia solo i tools che servono a un passaggio.
Come ottengo indietro JSON valido?
Imposta response_format su {"type": "json_object"} e descrivi le chiavi attese nel messaggio di sistema: la modalità JSON garantisce che la risposta si possa fare il parsing, non che abbia le chiavi che vuoi. Tieni temperature basso per un output stabile e controlla l'oggetto di cui hai fatto il parsing nel tuo codice prima di usarlo.
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://llmwithcrypto.com/api/v1',
apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});
const resp = await client.chat.completions.create({
model: 'gpt-oss-120b',
messages: [
{ role: 'system', content: 'Reply with a JSON object {"sentiment": "positive" | "negative" | "neutral", "reason": string}.' },
{ role: 'user', content: 'The delivery was late but support fixed it in an hour.' },
],
response_format: { type: 'json_object' },
temperature: 0.2,
max_tokens: 150,
});
const result = JSON.parse(resp.choices[0].message.content);
console.log(result.sentiment, '-', result.reason);
Tools e JSON: domande frequenti
Le chiamate ai tools costano di più?
Nessun costo aggiuntivo. Le definizioni dei tools, la chiamata e i risultati che rimandi sono tutti token, fatturati come gli altri. Paghi per token dal tuo saldo: i token di input e di output vengono contati dal tokenizer del modello stesso e addebitati al prezzo di quel modello per 1M di token. Una chiamata che termina con un errore non costa nulla.
Il modello può chiamare più tools contemporaneamente?
Alcuni modelli restituiscono più di una chiamata in tool_calls. Eseguile tutte e invia un messaggio tool per ogni chiamata prima della richiesta successiva.
L'API esegue le mie funzioni?
No. Il modello dice solo quale funzione chiamare e con quali argomenti; è il tuo codice a eseguirla. Nulla viene eseguito dalla nostra parte e nulla dello scambio viene memorizzato: Non conserviamo i tuoi prompt né le risposte del modello: una volta inviata una risposta, il suo testo non c'è più. Ogni chiamata lascia una riga di log con l'ora, l'account, il modello e i conteggi dei token, cancellata dopo 30 giorni.