Open in
Instrumente de funcții
Oferiți agenților dumneavoastră AI instrumente de funcții care apelează API-uri externe în timpul conversației — preiau date despre clienți, programează întâlniri, actualizează înregistrări — cu parametri tipizați.
Instrumentele de funcție le permit agenților dumneavoastră vocali cu 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 backendul dumneavoastră.
Cum funcționează
- Definiți instrumente cu o schemă (ce argumente acceptă instrumentul)
- Furnizați o configurație
endpoint(unde ThunderPhone apelează API-ul dumneavoastră) — sau omiteți-o pentru a primi apelurile instrumentelor pe webhookul organizației dumneavoastră - În timpul unui apel, AI-ul decide când să utilizeze un instrument pe baza conversației
- ThunderPhone apelează endpointul dumneavoastră cu argumentele instrumentului
- Răspunsul API-ului dumneavoastră este transmis înapoi AI-ului pentru a continua conversația
| Capacitate | Unde rulează | Configurare |
|---|---|---|
| Instrumente integrate | ThunderPhone | Instrucțiuni în prompt; unele instrumente necesită și o setare a agentului |
| Conexiuni de aplicații | ThunderPhone și furnizorul conectat | Conectați contul și atașați acțiunile aprobate |
| Conexiuni API și instrumente de funcție | API-ul dumneavoastră HTTP | Definiți endpointul și schema sau primiți apeluri de funcție printr-un webhook |
| Servere MCP | Un server MCP la distanță | Adăugați serverul, descoperiți instrumentele acestuia și atașați-l la agent |
Schema instrumentului
Fiecare instrument respectă 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 | number | Nu | Durata maximă de execuție în secunde (implicit: 20, maxim: 180) |
Definiția funcției
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
name | string | Da | Identificator unic pentru instrument |
description | string | Da | Explică AI-ului când să utilizeze acest instrument |
parameters | object | Da | Schemă JSON pentru argumentele instrumentului |
Configurarea endpointului
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
url | string | Da | URL-ul endpointului API-ului dumneavoastră |
method | string | Nu | Metodă HTTP (implicit: POST) |
headers | object | Nu | Anteturi personalizate de inclus |
Două căi de invocare
Solicitarea primită de serverul dumneavoastră depinde de existența unui
endpoint pentru instrument:
Instrument cu endpoint | Instrument fără endpoint | |
|---|---|---|
| Unde ajunge solicitarea | Direct la endpoint.url | La adresa URL webhook moștenită a organizației dumneavoastră |
| Corp | Formatul de solicitare selectat (argumente simple în mod implicit) | Anvelopa telephony.tool / web.tool |
| Antete | endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature-V2 + 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. Mențineți handlerele rapide. Puteți utiliza o combinație:
într-un apel al cărui organizație are un URL de webhook, instrumentele cu un endpoint sunt
apelate direct, iar celelalte 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-V2: t=1767225600,v1=5f2c...
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-keyAntetele personalizate din endpoint.headers sunt incluse întotdeauna
literal, împreună cu aceste antete din spațiul de nume ThunderPhone:
X-ThunderPhone-Signature-V2— HMAC-SHA256 cu marcaj temporal pentru metodă, cale, interogare și corp, utilizând secretul webhook al organizației. Verificați-o și respingeți cererile mai vechi de 5 minute; consultați Verificarea semnăturilor webhookX-ThunderPhone-Signature— HMAC-SHA256 moștenit al octeților exacți ai corpului cererii, cu aceeași cheie, încă trimis pentru validatoarele existenteX-ThunderPhone-Call-ID— ID-ul apelului curent
Content-Type: application/json este setat, cu excepția cazului în care
endpoint.headers îl suprascrie — un Content-Type personalizat are prioritate.
Formatul solicitării
Fiecare conexiune API are o setare request_format. Alegeți vapi sau
retell atunci când un instrument importat trebuie să continue să apeleze un endpoint creat pentru
acea platformă. Conexiunile noi și cele existente folosesc implicit standard.
Pentru POST / PUT / PATCH, ThunderPhone serializează canonic
anvelopa selectată (chei sortate, separatori compacți). Ambele semnături
acoperă exact acești octeți.
Standard
standard trimite doar argumentele instrumentului, fără un înveliș. Aceasta este opțiunea
implicită și păstrează corpul original al solicitării ThunderPhone octet cu octet:
{"date":"2025-01-02","service":"consultation"}Vapi
vapi trimite mesajul de server tool-calls al Vapi
în forma documentată de Vapi. call.id este ID-ul apelului ThunderPhone. ID-ul
id al apelului instrumentului este unic pentru invocare și este reutilizat pentru a corela
rezultatul endpointului. Apelul apare atât în toolCallList, cât și în
toolWithToolCallList, cu function.arguments ca obiect JSON:
{
"message": {
"type": "tool-calls",
"timestamp": 1725000000123,
"call": { "id": "987654321" },
"toolCallList": [
{
"id": "call_00112233445566778899aabbccddeeff",
"type": "function",
"function": {
"name": "search_appointments",
"arguments": { "date": "2025-01-02", "service": "consultation" }
}
}
],
"toolWithToolCallList": [
{
"type": "function",
"function": { "name": "search_appointments" },
"toolCall": {
"id": "call_00112233445566778899aabbccddeeff",
"type": "function",
"function": {
"name": "search_appointments",
"arguments": { "date": "2025-01-02", "service": "consultation" }
}
}
}
]
}
}Câmpurile exclusiv Vapi, precum assistant, artifact și obiectul complet call,
nu sunt trimise.
Returnați anvelopa de răspuns Vapi cu ID-ul corespunzător al apelului instrumentului:
{
"results": [
{
"toolCallId": "call_00112233445566778899aabbccddeeff",
"result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
}
]
}ThunderPhone oferă AI-ului șirul result neîmpachetat. Acceptă și o
valoare JSON pentru compatibilitate cu endpointurile care returnează deja una. Un
error în loc de result este transmis AI-ului ca eroare a instrumentului. Dacă
endpointul returnează o anvelopă Vapi incorectă sau necorespunzătoare, ThunderPhone înregistrează
un avertisment și revine la analiza standard a răspunsului, în loc să eșueze
apelul.
Retell
retell trimite solicitarea documentată pentru o funcție personalizată
Retell:
{
"name": "search_appointments",
"call": { "call_id": "987654321" },
"args": { "date": "2025-01-02", "service": "consultation" }
}Obiectul call include doar call_id. ThunderPhone nu include
câmpuri specifice Retell pe care nu le poate furniza corect la expediere, precum
agent_id, transcript, transcript_object, metadata sau variabile dinamice.
Retell acceptă orice corp de răspuns; ThunderPhone îl transmite
folosind gestionarea standard a răspunsurilor.
Pentru GET / DELETE, argumentele sunt trimise ca parametri de interogare
iar corpul este gol indiferent de request_format. Semnătura V2
acoperă șirul de interogare așa cum este trimis; semnătura veche este calculată pe
ș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 non-JSON sunt împachetate ca {"data": "<text>"};
expirările și erorile de conexiune sunt raportate AI-ului ca erori, astfel încât
agentul își poate cere scuze și poate continua, în loc să rămână blocat.
Distribuire în modul webhook
Instrumentele fără un endpoint sunt distribuite către URL-ul webhook legacy
al organizației dumneavoastră ca o 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 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. Cererea este semnată cu secretul webhook al organizației,
cu ambele antete de semnătură, la fel ca orice alt webhook.
Verificarea semnăturii
Apelurile directe de instrumente sunt semnate la fel ca webhookurile, folosind secretul webhook al organizației dumneavoastră:
X-ThunderPhone-Signature-V2semnează marcajul temporal, metoda, calea și interogarea așa cum sunt trimise, precum și octeții exacți ai corpului. Respingeți solicitările al căror marcaj temporal diferă cu mai mult de 5 minute de ceasul dumneavoastră.X-ThunderPhone-Signature(moștenit) semnează numai octeții corpului, șirul gol de octeți pentruGET/DELETE. Este trimis în continuare, nemodificat.
Funcțiile auxiliare SDK verifică antetul V2, inclusiv fereastra de 5 minute:
import json
from fastapi import FastAPI, HTTPException, Request
from thunderphone import verify_signature
app = FastAPI()
@app.post("/appointments/search")
async def search_appointments(request: Request):
body = await request.body()
query = request.scope.get("query_string", b"").decode("latin-1")
path = request.url.path + (f"?{query}" if query else "")
if not verify_signature(
request.headers.get("X-ThunderPhone-Signature-V2"),
secret=WEBHOOK_SECRET,
method=request.method,
path=path,
body=body,
):
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}import express from "express";
import { verifySignature } from "@thunderphone/sdk";
app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
const ok = verifySignature({
header: req.header('X-ThunderPhone-Signature-V2'),
secret: WEBHOOK_SECRET,
method: req.method,
path: req.originalUrl,
body: req.body,
});
if (!ok) 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 — șirul semnat, un exemplu detaliat, cod fără
SDK, cazul GET / DELETE și avertismentul privind absența unui secret — sunt în Verificați semnăturile webhookurilor.
Exemplu: flux complet de programare
Iată un set de instrumente pentru un sistem complet de programări:
{
"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ă AI-ul să înțeleagă când să utilizeze instrumentul. Specificați clar ce face și când este potrivit să fie utilizat.
Gestionați erorile cu eleganță
Returnați mesaje de eroare pe care AI-ul le poate înțelege: {"error": "No slots available for that date"} în locul erorilor 500 generice.
Mențineți răspunsurile concise
Returnați doar ceea ce AI-ul are nevoie pentru a continua conversația. Încărcăturile utile mari încetinesc timpii de răspuns.
Utilizați cu discernământ câmpurile obligatorii
Marcați câmpurile drept required numai atunci când este cu adevărat necesar. AI-ul va solicita utilizatorului informațiile obligatorii înainte de a apela instrumentul.
Resurse asociate
Inițiați acțiuni de apel gestionate de platformă fără a defini un endpoint.
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 utilitar de verificare pentru webhookuri și apeluri de instrumente.