Nástroje funkcií
Funkčné nástroje umožňujú vašim agentom AI počas telefonátov vyvolávať externé API. Použite ich na vyhľadávanie údajov o zákazníkoch, kontrolu dostupnosti, rezerváciu termínov alebo vykonanie ľubovoľnej akcie, ktorú váš backend podporuje.
Ako to funguje
- Definujete nástroje so schémou (aké argumenty nástroj prijíma)
- Poskytnete konfiguráciu
endpoint(kam ThunderPhone volá vaše API) — alebo ju vynecháte, aby ste volania nástrojov prijímali na webhooku svojej organizácie - Počas hovoru sa AI podľa konverzácie rozhodne, kedy použiť nástroj
- ThunderPhone zavolá váš endpoint s argumentmi nástroja
- Odpoveď vášho API sa odošle späť AI, aby mohla pokračovať v konverzácii
Schéma nástroja
Každý nástroj má túto štruktúru:
{
"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"
}
}
}
Definícia funkcie
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
name | reťazec | Áno | Jedinečný identifikátor nástroja |
description | reťazec | Áno | Vysvetľuje AI, kedy má tento nástroj použiť |
parameters | objekt | Áno | Schéma JSON pre argumenty nástroja |
Konfigurácia endpointu
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
url | reťazec | Áno | URL endpointu vášho API |
method | reťazec | Nie | Metóda HTTP (predvolené: POST) |
headers | objekt | Nie | Vlastné hlavičky, ktoré sa majú zahrnúť |
Dve cesty vyvolania
To, akú požiadavku váš server prijme, závisí od toho, či má nástroj
endpoint:
Nástroj s endpoint | Nástroj bez endpoint | |
|---|---|---|
| Kam požiadavka smeruje | Priamo na endpoint.url | Na staršiu URL webhooku vašej organizácie |
| Telo | Samotné argumenty nástroja | Obálka telephony.tool / web.tool |
| Hlavičky | Vaše endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| Podpisovací kľúč | Tajný kľúč webhooku organizácie | Tajný kľúč webhooku organizácie |
Obe cesty sú blokujúce — AI uprostred vety čaká na
výsledok — s časovým limitom 20 s. Obslužné rutiny udržiavajte rýchle. Kombinovanie je v poriadku:
pri hovore, ktorého organizácia má URL webhooku, sa nástroje s endpoint
volajú priamo a ostatné sa vrátia k webhooku.
Priame volania endpointov
Keď AI vyvolá nástroj, ktorý má endpoint, ThunderPhone odošle
požiadavku na vašu URL:
Hlavičky požiadavky
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
Vlastné hlavičky z vášho endpoint.headers sú vždy zahrnuté
doslovne spolu s dvoma hlavičkami v mennom priestore ThunderPhone:
X-ThunderPhone-Signature— HMAC-SHA256 presných bajtov tela požiadavky s kľúčom vo forme vášho tajného kľúča webhooku organizácieX-ThunderPhone-Call-ID— ID aktuálneho hovoru
Content-Type: application/json sa nastaví, pokiaľ ho váš endpoint.headers
neprepíše — vlastný Content-Type má prednosť.
Telo požiadavky
Pre POST / PUT / PATCH telo obsahuje iba argumenty nástroja
(bez obalu), serializované kanonicky (zoradené kľúče, kompaktné
oddeľovače):
{"date":"2025-01-02","service":"consultation"}
Pre GET / DELETE sa argumenty odosielajú ako parametre dotazu
a telo je prázdne — podpis sa potom vypočíta nad prázdnym
bajtovým reťazcom. Pozrite si
Overenie podpisov webhookov.
Odpoveď
Vráťte odpoveď JSON s výsledkom nástroja:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}
Odpoveď sa naformátuje a poskytne AI na pokračovanie
konverzácie. Odpovede, ktoré nie sú vo formáte JSON, sa zabalia ako {"data": "<text>"};
časové limity a zlyhania pripojenia sa AI hlásia ako chyby, takže
sa agent môže ospravedlniť a pokračovať namiesto zaseknutia.
Odosielanie v režime webhooku
Nástroje bez endpoint sa odosielajú na staršiu URL webhooku vašej
organizácie ako podpísaná požiadavka telephony.tool (telefonické hovory) alebo web.tool
(webové hovory). Na rozdiel od notifikácií auditu,
ktoré sa doručujú na endpointy webhookov po vykonaní, táto požiadavka je
vykonaním — vaša odpoveď HTTP je výsledkom nástroja.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}
web.tool obsahuje origin_domain namiesto from_number /
to_number. Odpovedzte výsledkom nástroja vo formáte JSON — platí rovnaký
kontrakt odpovede ako pri priamych volaniach endpointov. Požiadavka je podpísaná
tajným kľúčom webhooku organizácie nad nespracovaným telom, rovnako ako každý iný webhook.
Overovanie podpisu
Priame volania nástrojov sa podpisujú rovnako ako webhooky:
- HMAC-SHA256 nad presnými bajtmi tela požiadavky (kanonický JSON — zoradené kľúče, bez nadbytočných medzier)
- S použitím webhookového tajného kľúča vašej organizácie
- Nástroje
GET/DELETEpodpisujú prázdny bajtový reťazec
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 });
});
Úplné postupy — vrátane prípadu s prázdnym telom a upozornenia pri chýbajúcom tajnom kľúči — nájdete v časti Overenie podpisov webhookov.
Príklad: Kompletný proces rezervácie
Tu je súprava nástrojov pre kompletný systém rezervácie termínov:
{
"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" }
}
}
]
}
Odporúčané postupy
Píšte jasné popisy
Pole description pomáha AI pochopiť, kedy má nástroj použiť. Jasne uveďte, čo nástroj robí a kedy je vhodné ho použiť.
Správne spracúvajte chyby
Vrátťe chybové hlásenia, ktorým AI rozumie: {"error": "No slots available for that date"} namiesto všeobecných chýb 500.
Odpovede udržiavajte stručné
Vrátťe len to, čo AI potrebuje na pokračovanie v konverzácii. Veľké dátové objemy spomaľujú čas odozvy.
Povinné polia používajte uvážlivo
Polia označte ako required len vtedy, keď je to skutočne nevyhnutné. AI pred volaním nástroja požiada používateľa o povinné informácie.
Súvisiace
Nástroje spravované platformou pre HubSpot, Salesforce, Slack, Kalendár Google, Tabuľky Google a Cal.com — bez potreby koncového bodu.
Pripojte server MCP a umožnite agentovi volať jeho nástroje.
Opakovane použiteľné integrácie REST, ktoré môžete pripojiť k agentom.
Jeden pomocník na overovanie webhookov a volaní nástrojov.