Strumenti funzione
Fornisci ai tuoi agenti AI strumenti funzione che chiamano API esterne durante la conversazione — recuperano dati dei clienti, fissano appuntamenti, aggiornano record — con parametri tipizzati.
Gli strumenti funzione consentono ai tuoi agenti vocali AI di invocare API esterne durante le chiamate telefoniche. Usali per cercare dati dei clienti, verificare la disponibilità, prenotare appuntamenti o eseguire qualsiasi azione supportata dal tuo backend.
Come funziona
- Definisci gli strumenti con uno schema (gli argomenti accettati dallo strumento)
- Fornisci una configurazione
endpoint(dove ThunderPhone chiama la tua API) — oppure non specificarla per ricevere le chiamate agli strumenti sul webhook della tua organizzazione - Durante una chiamata, l'AI decide quando usare uno strumento in base alla conversazione
- ThunderPhone chiama il tuo endpoint con gli argomenti dello strumento
- La risposta della tua API viene restituita all'AI per continuare la conversazione
Schema dello strumento
Ogni strumento segue questa struttura:
{
"type": "function",
"function": {
"name": "search_appointments",
"description": "Find available appointment slots for a given date",
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Date in YYYY-MM-DD format"
},
"service": {
"type": "string",
"description": "Type of service (e.g., 'consultation', 'follow-up')"
}
},
"required": ["date"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/search",
"method": "POST",
"headers": {
"X-Api-Key": "your-api-key"
}
},
"timeout": 120
}Configurazione dello strumento
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
timeout | numero | No | Tempo massimo di esecuzione in secondi (predefinito: 20, massimo: 180) |
Definizione della funzione
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
name | stringa | Sì | Identificatore univoco dello strumento |
description | stringa | Sì | Spiega all'AI quando usare questo strumento |
parameters | oggetto | Sì | JSON Schema per gli argomenti dello strumento |
Configurazione dell'endpoint
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
url | stringa | Sì | URL dell'endpoint della tua API |
method | stringa | No | Metodo HTTP (predefinito: POST) |
headers | oggetto | No | Intestazioni personalizzate da includere |
Due percorsi di invocazione
La richiesta ricevuta dal tuo server dipende dal fatto che lo strumento disponga di un
endpoint:
Strumento con endpoint | Strumento senza endpoint | |
|---|---|---|
| Destinazione della richiesta | Direttamente a endpoint.url | URL webhook legacy della tua organizzazione |
| Corpo | Argomenti dello strumento senza wrapper | Wrapper telephony.tool / web.tool |
| Intestazioni | I tuoi endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| Chiave di firma | Segreto webhook dell'organizzazione | Segreto webhook dell'organizzazione |
Entrambi i percorsi sono bloccanti: l'AI attende il risultato a metà
frase. Il timeout predefinito è 20 s; imposta il valore timeout
di primo livello dello strumento per consentire un'esecuzione più lunga, fino al
massimo della piattaforma di 180 s. Mantieni gli handler veloci. È possibile usare una combinazione:
in una chiamata la cui organizzazione ha un URL webhook, gli strumenti con un
endpoint vengono chiamati direttamente e gli altri usano il webhook come fallback.
Chiamate dirette agli endpoint
Quando l'IA invoca uno strumento con un endpoint, ThunderPhone invia
una richiesta al tuo URL:
Intestazioni della richiesta
POST /appointments/search HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-keyLe intestazioni personalizzate da endpoint.headers sono sempre incluse
testualmente, oltre a due intestazioni nello spazio dei nomi ThunderPhone:
X-ThunderPhone-Signature— HMAC-SHA256 dei byte esatti del corpo della richiesta, con chiave il tuo segreto webhook dell'organizzazioneX-ThunderPhone-Call-ID— L'ID della chiamata corrente
Content-Type: application/json viene impostato a meno che endpoint.headers
non lo sovrascriva — un Content-Type personalizzato ha la precedenza.
Corpo della richiesta
Per POST / PUT / PATCH, il corpo contiene solo gli argomenti dello
strumento (senza wrapper), serializzati canonicamente (chiavi ordinate,
separatori compatti):
{"date":"2025-01-02","service":"consultation"}Per GET / DELETE, gli argomenti vengono inviati come parametri di query
e il corpo è vuoto — la firma viene quindi calcolata sulla stringa di byte
vuota. Consulta
Verifica le firme webhook.
Risposta
Restituisci una risposta JSON con il risultato dello strumento:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}La risposta viene formattata e fornita all'IA per continuare la
conversazione. Le risposte non JSON vengono racchiuse in {"data": "<text>"};
i timeout e gli errori di connessione vengono segnalati all'IA come errori,
così l'agente può scusarsi e proseguire anziché bloccarsi.
Instradamento in modalità webhook
Gli strumenti senza un endpoint vengono instradati all'URL webhook legacy
della tua organizzazione come richiesta firmata telephony.tool (chiamate
telefoniche) o web.tool (chiamate web). A differenza delle
notifiche di audit consegnate agli endpoint webhook dopo
l'esecuzione, questa richiesta è l'esecuzione — la tua risposta HTTP è il
risultato dello strumento.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}web.tool include origin_domain invece di from_number /
to_number. Rispondi con il risultato dello strumento in JSON — lo stesso
contratto di risposta delle chiamate dirette agli endpoint. La richiesta è
firmata con il segreto webhook dell'organizzazione sul corpo non elaborato,
come ogni altro webhook.
Verifica della firma
Le chiamate dirette agli strumenti vengono firmate allo stesso modo dei webhook:
- HMAC-SHA256 sugli esatti byte del corpo della richiesta (il JSON canonico — chiavi ordinate, nessuno spazio aggiuntivo)
- Con la tua chiave segreta webhook dell'organizzazione
- Gli strumenti
GET/DELETEfirmano la stringa di byte vuota
import hmac
import hashlib
def verify_tool_call(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
@app.post("/appointments/search")
async def search_appointments(request: Request):
body = await request.body()
signature = request.headers.get("X-ThunderPhone-Signature", "")
if not verify_tool_call(body, signature, WEBHOOK_SECRET):
raise HTTPException(status_code=401)
data = json.loads(body)
date = data["date"]
# Look up availability
slots = await get_available_slots(date)
return {"available_slots": slots}app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-thunderphone-signature'] || '';
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!signature ||
signature.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return res.status(401).send('Invalid signature');
}
const { date, service } = JSON.parse(req.body);
// Look up availability
const slots = getAvailableSlots(date, service);
res.json({ available_slots: slots });
});Le procedure complete — incluso il caso del corpo vuoto e l'avvertenza sull'assenza di una chiave segreta — sono disponibili in Verifica delle firme dei webhook.
Esempio: flusso di prenotazione completo
Ecco un insieme di strumenti per un sistema completo di prenotazione appuntamenti:
{
"tools": [
{
"type": "function",
"function": {
"name": "search_appointments",
"description": "Find available appointment slots",
"parameters": {
"type": "object",
"properties": {
"date": { "type": "string", "description": "YYYY-MM-DD" },
"service": { "type": "string" }
},
"required": ["date"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/search",
"method": "POST",
"headers": { "X-Api-Key": "key" }
}
},
{
"type": "function",
"function": {
"name": "book_appointment",
"description": "Book an appointment at a specific time",
"parameters": {
"type": "object",
"properties": {
"date": { "type": "string", "description": "YYYY-MM-DD" },
"time": { "type": "string", "description": "HH:MM format" },
"customer_name": { "type": "string" },
"customer_phone": { "type": "string" }
},
"required": ["date", "time", "customer_name"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/book",
"method": "POST",
"headers": { "X-Api-Key": "key" }
}
},
{
"type": "function",
"function": {
"name": "cancel_appointment",
"description": "Cancel an existing appointment",
"parameters": {
"type": "object",
"properties": {
"confirmation_number": { "type": "string" }
},
"required": ["confirmation_number"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/cancel",
"method": "POST",
"headers": { "X-Api-Key": "key" }
}
}
]
}Best practice
Scrivi descrizioni chiare
Il campo description aiuta l'IA a capire quando usare lo strumento. Specifica chiaramente cosa fa e quando è appropriato usarlo.
Gestisci gli errori in modo efficace
Restituisci messaggi di errore comprensibili per l'IA: {"error": "No slots available for that date"} invece di errori 500 generici.
Mantieni concise le risposte
Restituisci solo ciò di cui l'IA ha bisogno per continuare la conversazione. I payload di grandi dimensioni rallentano i tempi di risposta.
Usa con criterio i campi obbligatori
Contrassegna i campi come required solo quando è davvero necessario. L'IA chiederà all'utente le informazioni obbligatorie prima di chiamare lo strumento.
Correlati
Strumenti gestiti dalla piattaforma per HubSpot, Salesforce, Slack, Google Calendar, Google Sheets e Cal.com — nessun endpoint richiesto.
Collega un server MCP e consenti all'agente di chiamare i suoi strumenti.
Integrazioni REST riutilizzabili che puoi collegare agli agenti.
Un unico strumento di verifica per webhook e chiamate agli strumenti.