Instrumente de funcții
Oferiți agenților dumneavoastră AI instrumente de funcții care apelează API-uri externe în timpul conversației — preiau datele clienților, programează întâlniri, actualizează înregistrări — cu parametri tipizați.
Instrumentele de funcție le permit agenților dvs. AI să invoce API-uri externe în timpul apelurilor telefonice. Folosiți-le pentru a căuta date despre clienți, a verifica disponibilitatea, a programa întâlniri sau a efectua orice acțiune acceptată de backend-ul dvs.
Cum funcționează
- Definiți instrumente cu o schemă (ce argumente acceptă instrumentul)
- Furnizați o configurație
endpoint(unde ThunderPhone apelează API-ul dvs.) — sau omiteți-o pentru a primi apelurile instrumentelor în webhook-ul organizației dvs. - În timpul unui apel, AI-ul decide când să folosească un instrument pe baza conversației
- ThunderPhone apelează endpoint-ul dvs. cu argumentele instrumentului
- Răspunsul API-ului dvs. este transmis înapoi AI-ului pentru a continua conversația
Schema instrumentului
Fiecare instrument urmează această structură:
{
"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
}Configurarea instrumentului
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
timeout | număr | Nu | Timpul maxim de execuție în secunde (implicit: 20, maxim: 180) |
Definiția funcției
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
name | șir | Da | Identificator unic pentru instrument |
description | șir | Da | Explică AI-ului când să utilizeze acest instrument |
parameters | obiect | Da | Schemă JSON pentru argumentele instrumentului |
Configurarea endpoint-ului
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
url | șir | Da | URL-ul endpoint-ului API-ului dvs. |
method | șir | Nu | Metoda HTTP (implicit: POST) |
headers | obiect | Nu | Antete personalizate de inclus |
Două căi de invocare
Solicitarea pe care o primește serverul dvs. depinde de existența unui
endpoint pentru instrument:
Instrument cu endpoint | Instrument fără endpoint | |
|---|---|---|
| Unde ajunge solicitarea | Direct la endpoint.url | URL-ul webhook moștenit al organizației dvs. |
| Corp | Argumente simple ale instrumentului | Plic telephony.tool / web.tool |
| Antete | endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| Cheie de semnare | Secretul webhook al organizației | Secretul webhook al organizației |
Ambele căi sunt blocante — AI-ul așteaptă rezultatul în mijlocul
propoziției. Timpul de expirare implicit este de 20 s; setați
timeout la nivelul superior al instrumentului pentru a permite o execuție mai lungă, până la
maximul platformei de 180 s. Păstrați handler-ele rapide. Puteți utiliza o combinație:
într-un apel al cărui organizație are un URL webhook, instrumentele cu un endpoint sunt
apelate direct, iar restul revin la webhook.
Apeluri directe către endpoint
Când AI-ul invocă un instrument care are un endpoint, ThunderPhone trimite
o solicitare către URL-ul dumneavoastră:
Antete de solicitare
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-keyAntetele personalizate din endpoint.headers sunt întotdeauna incluse
literal, împreună cu două antete din spațiul de nume ThunderPhone:
X-ThunderPhone-Signature— HMAC-SHA256 al octeților exacți ai corpului solicitării, utilizând ca cheie secretul webhook al organizațieiX-ThunderPhone-Call-ID— ID-ul apelului curent
Content-Type: application/json este setat dacă endpoint.headers nu îl
suprascrie — un Content-Type personalizat are prioritate.
Corpul solicitării
Pentru POST / PUT / PATCH, corpul conține doar argumentele
instrumentului (fără înveliș), serializate canonic (chei sortate, separatori
compacți):
{"date":"2025-01-02","service":"consultation"}Pentru GET / DELETE, argumentele sunt trimise ca parametri de interogare
iar corpul este gol — semnătura este calculată apoi peste șirul gol de
octeți. Consultați
Verificarea semnăturilor webhook.
Răspuns
Returnați un răspuns JSON cu rezultatul instrumentului:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}Răspunsul este formatat și furnizat AI-ului pentru a continua
conversația. Răspunsurile care nu sunt JSON sunt împachetate ca {"data": "<text>"};
expirările și eșecurile de conexiune sunt raportate AI-ului ca erori, astfel încât
agentul să își poată cere scuze și să continue, în loc să se blocheze.
Distribuire în modul webhook
Instrumentele fără un endpoint sunt distribuite către URL-ul webhook vechi al
organizației dumneavoastră ca solicitare semnată telephony.tool (apeluri telefonice) sau web.tool
(apeluri web). Spre deosebire de notificările de audit
livrate către endpointurile webhook după execuție, această solicitare este
execuția — răspunsul dumneavoastră HTTP reprezintă rezultatul instrumentului.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}web.tool conține origin_domain în loc de from_number /
to_number. Răspundeți cu rezultatul instrumentului ca JSON — același contract
de răspuns ca pentru apelurile directe către endpoint. Solicitarea este semnată cu secretul
webhook al organizației peste corpul brut, la fel ca orice alt webhook.
Verificarea semnăturii
Apelurile directe ale instrumentelor sunt semnate la fel ca webhookurile:
- HMAC-SHA256 peste octeții exacți ai corpului cererii (JSON-ul canonic — chei sortate, fără spații suplimentare)
- Cu cheia secretului webhook al organizației dumneavoastră
- Instrumentele
GET/DELETEsemnează șirul de octeți gol
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 });
});Rețetele complete — inclusiv cazul cu corp gol și precizarea privind absența unui secret — sunt disponibile în Verificați semnăturile webhookurilor.
Exemplu: flux complet de programare
Iată un set de instrumente pentru un sistem complet de programare a întâlnirilor:
{
"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" }
}
}
]
}Practici recomandate
Scrieți descrieri clare
Câmpul description ajută IA să înțeleagă când să utilizeze instrumentul. Specificați clar ce face și când este potrivit să fie utilizat.
Gestionați erorile corect
Returnați mesaje de eroare pe care IA le poate înțelege: {"error": "No slots available for that date"} în locul unor erori 500 generice.
Păstrați răspunsurile concise
Returnați doar informațiile de care IA are nevoie pentru a continua conversația. Încărcăturile mari încetinesc timpii de răspuns.
Utilizați câmpurile obligatorii cu discernământ
Marcați câmpurile ca required doar atunci când este cu adevărat necesar. IA va cere utilizatorului informațiile obligatorii înainte de a apela instrumentul.
Asociate
Instrumente gestionate de platformă pentru HubSpot, Salesforce, Slack, Google Calendar, Google Sheets și Cal.com — nu este necesar niciun endpoint.
Atașați un server MCP și permiteți agentului să îi apeleze instrumentele.
Integrări REST reutilizabile pe care le puteți atașa agenților.
Un singur instrument auxiliar de verificare pentru webhookuri și apeluri de instrumente.