Funkcijų įrankiai
Funkcijų įrankiai leidžia jūsų DI agentams telefoninių skambučių metu iškviesti išorines API. Naudokite juos klientų duomenims ieškoti, prieinamumui tikrinti, susitikimams rezervuoti arba bet kokiam veiksmui, kurį palaiko jūsų vidinė sistema, atlikti.
Kaip tai veikia
- Apibrėžiate įrankius naudodami schemą (kokius argumentus įrankis priima)
- Pateikiate
endpointkonfigūraciją (kur ThunderPhone iškviečia jūsų API) arba jos nenurodote, kad įrankio iškvietimus gautumėte per savo organizacijos webhook - Skambučio metu DI pagal pokalbį nusprendžia, kada naudoti įrankį
- ThunderPhone iškviečia jūsų endpoint su įrankio argumentais
- Jūsų API atsakymas grąžinamas DI, kad pokalbis būtų tęsiamas
Įrankio schema
Kiekvienas įrankis naudoja šią struktūrą:
{
"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"
}
}
}
Funkcijos apibrėžimas
| Laukas | Tipas | Privalomas | Aprašymas |
|---|---|---|---|
name | string | Taip | Unikalus įrankio identifikatorius |
description | string | Taip | DI nurodo, kada naudoti šį įrankį |
parameters | object | Taip | Įrankio argumentų JSON Schema |
Endpoint konfigūracija
| Laukas | Tipas | Privalomas | Aprašymas |
|---|---|---|---|
url | string | Taip | Jūsų API endpoint URL |
method | string | Ne | HTTP metodas (numatytoji reikšmė: POST) |
headers | object | Ne | Įtraukiamos pasirinktinės antraštės |
Du iškvietimo būdai
Kokią užklausą gauna jūsų serveris, priklauso nuo to, ar įrankis turi
endpoint:
Įrankis su endpoint | Įrankis be endpoint | |
|---|---|---|
| Kur siunčiama užklausa | Tiesiogiai į endpoint.url | Jūsų organizacijos senasis webhook URL |
| Turinys | Tik įrankio argumentai | telephony.tool / web.tool paketas |
| Antraštės | Jūsų endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| Pasirašymo raktas | Organizacijos webhook paslaptis | Organizacijos webhook paslaptis |
Abu būdai yra blokuojantys — DI sakinio viduryje laukia
rezultato — taikant 20 s skirtąjį laiką. Užtikrinkite, kad tvarkytuvės veiktų sparčiai. Galite naudoti abu būdus:
skambučio, kurio organizacija turi webhook URL, metu įrankiai su endpoint yra
iškviečiami tiesiogiai, o kiti grįžta prie webhook.
Tiesioginiai galinių punktų iškvietimai
Kai AI iškviečia įrankį, turintį endpoint, ThunderPhone siunčia
užklausą į jūsų URL:
Užklausos antraštės
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-key
Pasirinktinės antraštės iš jūsų endpoint.headers visada įtraukiamos
nekeičiant, kartu su dviem ThunderPhone vardų srities antraštėmis:
X-ThunderPhone-Signature— tikslių užklausos turinio baitų HMAC-SHA256, naudojant jūsų organizacijos webhook slaptąjį raktąX-ThunderPhone-Call-ID— dabartinio skambučio ID
Content-Type: application/json nustatoma, nebent ją pakeičia jūsų endpoint.headers
— pasirinktinė Content-Type turi pirmenybę.
Užklausos turinys
Naudojant POST / PUT / PATCH, turinyje pateikiami tik įrankio
argumentai (be apvalkalo), kanoniškai serializuoti (surikiuoti raktai,
glausti skirtukai):
{"date":"2025-01-02","service":"consultation"}
Naudojant GET / DELETE, argumentai siunčiami kaip užklausos parametrai,
o turinys yra tuščias — tuomet parašas apskaičiuojamas pagal tuščią
baitų eilutę. Žr.
Webhook parašų tikrinimas.
Atsakymas
Grąžinkite JSON atsakymą su įrankio rezultatu:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}
Atsakymas suformatuojamas ir pateikiamas AI, kad jis galėtų tęsti
pokalbį. Ne JSON atsakymai įvyniojami kaip {"data": "<text>"};
laiko limitų viršijimai ir ryšio klaidos pateikiami AI kaip klaidos,
todėl agentas gali atsiprašyti ir tęsti, užuot sustojęs.
Siuntimas webhook režimu
Įrankiai be endpoint siunčiami į jūsų organizacijos senojo
webhook URL kaip pasirašyta telephony.tool (telefono skambučiams) arba
web.tool (žiniatinklio skambučiams) užklausa. Kitaip nei
audito pranešimai, pristatomi į webhook galinius punktus
po vykdymo, ši užklausa yra vykdymas — jūsų HTTP atsakymas yra
įrankio rezultatas.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}
web.tool pateikia origin_domain vietoje from_number /
to_number. Atsakykite su įrankio rezultatu JSON formatu — taikoma ta
pati atsakymo sutartis kaip ir tiesioginiams galinių punktų iškvietimams.
Užklausa pasirašoma naudojant organizacijos webhook slaptąjį raktą pagal
neapdorotą turinį, kaip ir kiekvienas kitas webhook.
Parašo tikrinimas
Tiesioginiai įrankių iškvietimai pasirašomi taip pat kaip ir žiniatinklio kabliukai:
- HMAC-SHA256, apskaičiuotas pagal tikslius užklausos pagrindinio teksto baitus (kanoninis JSON — surikiuoti raktai, be papildomų tarpų)
- Naudojant jūsų organizacijos žiniatinklio kabliuko slaptąjį raktą
GET/DELETEįrankiai pasirašo tuščią baitų eilutę
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 });
});
Išsamūs pavyzdžiai, įskaitant tuščio pagrindinio teksto atvejį ir pastabą dėl slaptojo rakto nebuvimo, pateikti skiltyje Tikrinkite žiniatinklio kabliukų parašus.
Pavyzdys: visas rezervavimo procesas
Toliau pateikiamas įrankių rinkinys, skirtas visai vizitų rezervavimo sistemai:
{
"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" }
}
}
]
}
Geriausia praktika
Rašykite aiškius aprašus
Laukas description padeda DI suprasti, kada naudoti įrankį. Tiksliai nurodykite, ką jis daro ir kada jį tikslinga naudoti.
Tinkamai tvarkykite klaidas
Grąžinkite DI suprantamus klaidų pranešimus: {"error": "No slots available for that date"}, o ne bendrines 500 klaidas.
Atsakymai turi būti glausti
Grąžinkite tik tai, ko DI reikia pokalbiui tęsti. Didelės duomenų apkrovos lėtina atsako laiką.
Apdairiai naudokite privalomus laukus
Pažymėkite laukus kaip required tik tada, kai tai iš tiesų būtina. Prieš iškviesdamas įrankį, DI paprašys naudotojo pateikti privalomą informaciją.
Susiję
Platformos valdomi įrankiai, skirti HubSpot, Salesforce, Slack, Google Calendar, Google Sheets ir Cal.com — galinio taško nereikia.
Prijunkite MCP serverį ir leiskite agentui iškviesti jo įrankius.
Pakartotinai naudojamos REST integracijos, kurias galite prijungti prie agentų.
Viena patikros pagalbinė priemonė žiniatinklio kabliukams ir įrankių iškvietimams.