Open in
Nástroje funkcí
Poskytněte svým AI agentům nástroje funkcí, které během konverzace volají externí API — načítají data zákazníků, rezervují schůzky, aktualizují záznamy — s typovanými parametry.
Funkční nástroje umožňují vašim AI agentům během telefonních hovorů volat externí API. Použijte je k vyhledávání údajů o zákaznících, kontrole dostupnosti, rezervaci schůzek nebo provádění jakékoli akce, kterou váš backend podporuje.
Jak to funguje
- Definujete nástroje pomocí schématu (jaké argumenty nástroj přijímá)
- Poskytnete konfiguraci
endpoint(kam ThunderPhone volá vaše API) — nebo ji vynecháte a volání nástrojů budete přijímat na webhooku vaší organizace - Během hovoru AI podle konverzace rozhodne, kdy nástroj použít
- ThunderPhone zavolá váš endpoint s argumenty nástroje
- Odpověď vašeho API se předá zpět AI, aby mohla pokračovat v konverzaci
| Možnost | Kde se spouští | Nastavení |
|---|---|---|
| Vestavěné nástroje | ThunderPhone | Pokyny v promptu; některé nástroje také vyžadují nastavení agenta |
| Připojení aplikací | ThunderPhone a připojený poskytovatel | Připojte účet a přiřaďte schválené akce |
| Připojení API a funkční nástroje | Vaše HTTP API | Definujte endpoint a schéma nebo přijímejte volání funkcí přes webhook |
| Servery MCP | Vzdálený server MCP | Přidejte server, zjistěte jeho nástroje a přiřaďte jej agentovi |
Schéma nástroje
Každý nástroj má tuto strukturu:
{
"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
}Konfigurace nástroje
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
timeout | číslo | Ne | Maximální doba provádění v sekundách (výchozí: 20, maximum: 180) |
Definice funkce
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
name | řetězec | Ano | Jedinečný identifikátor nástroje |
description | řetězec | Ano | Vysvětluje AI, kdy má tento nástroj použít |
parameters | objekt | Ano | Schéma JSON pro argumenty nástroje |
Konfigurace endpointu
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
url | řetězec | Ano | Adresa URL endpointu vašeho API |
method | řetězec | Ne | Metoda HTTP (výchozí: POST) |
headers | objekt | Ne | Vlastní hlavičky k zahrnutí |
Dvě cesty volání
To, jaký požadavek váš server obdrží, závisí na tom, zda nástroj obsahuje
endpoint:
Nástroj s endpoint | Nástroj bez endpoint | |
|---|---|---|
| Kam požadavek směřuje | Přímo na endpoint.url | Na starší URL webhooku vaší organizace |
| Tělo | Vybraný formát požadavku (ve výchozím nastavení pouze argumenty) | Obálka telephony.tool / web.tool |
| Hlavičky | Vaše endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature |
| Podpisový klíč | Tajný klíč webhooku organizace | Tajný klíč webhooku organizace |
Obě cesty jsou blokující — AI uprostřed věty čeká na výsledek.
Výchozí časový limit je 20 s; nastavte timeout na nejvyšší úrovni
nástroje, chcete-li povolit delší provádění, až do maximální hodnoty platformy
180 s. Udržujte obslužné rutiny rychlé. Kombinace je možná:
při hovoru, jehož organizace má adresu URL webhooku, se nástroje s endpoint
volají přímo a ostatní se vrátí k webhooku.
Přímá volání endpointů
Když AI vyvolá nástroj, který má endpoint, ThunderPhone odešle
požadavek na vaši adresu URL:
Hlavičky požadavku
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-keyVlastní hlavičky z endpoint.headers jsou vždy zahrnuty
doslovně spolu s těmito hlavičkami v oboru názvů ThunderPhone:
X-ThunderPhone-Signature-V2— HMAC-SHA256 s časovým razítkem pro metodu, cestu, dotaz a tělo, podepsaný vaším tajemstvím webhooku organizace. Ověřte jej a odmítněte požadavky starší než 5 minut; viz Ověření podpisů webhookůX-ThunderPhone-Signature— starší HMAC-SHA256 přes přesné bajty těla požadavku, se stejným klíčem, stále odesílaný pro existující ověřovačeX-ThunderPhone-Call-ID— ID aktuálního hovoru
Content-Type: application/json je nastaveno, pokud jej nepřepíšete v
endpoint.headers — vlastní Content-Type má přednost.
Formát požadavku
Každé připojení API má nastavení request_format. Zvolte vapi nebo
retell, pokud má importovaný nástroj nadále volat endpoint vytvořený pro
danou platformu. Nová i stávající připojení ve výchozím nastavení používají standard.
Pro POST / PUT / PATCH ThunderPhone serializuje vybranou
obálku kanonicky (seřazené klíče, kompaktní oddělovače). Oba podpisy
pokrývají tyto přesné bajty.
Standard
standard odesílá pouze argumenty nástroje bez obálky. Toto je výchozí nastavení a zachovává původní tělo požadavku ThunderPhone bajt po bajtu:
{"date":"2025-01-02","service":"consultation"}Vapi
vapi odesílá serverovou zprávu tool-calls platformy Vapi
ve formátu dokumentovaném platformou Vapi. call.id je ID hovoru ThunderPhone. ID
volání nástroje id je pro dané vyvolání jedinečné a znovu se používá ke spárování
výsledku endpointu. Volání se zobrazí v toolCallList i
toolWithToolCallList, přičemž function.arguments je objekt 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" }
}
}
}
]
}
}Pole určená pouze pro Vapi, například assistant, artifact a celý objekt
call, se neodesílají.
Vraťte obálku odpovědi Vapi s odpovídajícím ID volání nástroje:
{
"results": [
{
"toolCallId": "call_00112233445566778899aabbccddeeff",
"result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
}
]
}ThunderPhone poskytne AI rozbalený řetězec result. Z důvodu kompatibility
také přijímá hodnotu JSON z endpointů, které ji již vracejí. Položka
error místo result je AI vrácena jako chyba nástroje. Pokud endpoint
vrátí neplatnou nebo neshodující se obálku Vapi, ThunderPhone zaznamená
varování a místo selhání hovoru použije standardní zpracování odpovědi.
Retell
retell odesílá požadavek dokumentovaný pro vlastní
funkci Retell:
{
"name": "search_appointments",
"call": { "call_id": "987654321" },
"args": { "date": "2025-01-02", "service": "consultation" }
}Objekt call obsahuje pouze call_id. ThunderPhone nezahrnuje
specifická pole Retell, která při odeslání nemůže poctivě poskytnout, například
agent_id, transcript, transcript_object, metadata nebo dynamické
proměnné. Retell přijímá jakékoli tělo odpovědi; ThunderPhone jej předá
pomocí standardního zpracování odpovědi.
Pro GET / DELETE se argumenty odesílají jako parametry dotazu
a tělo je prázdné bez ohledu na request_format. Podpis V2
pokrývá řetězec dotazu v odeslané podobě; starší podpis se vypočítává z
prázdného bajtového řetězce. Viz
Ověření podpisů webhooků.
Odpověď
Vraťte odpověď JSON s výsledkem nástroje:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}Odpověď je naformátována a poskytnuta AI, aby mohla pokračovat
v konverzaci. Odpovědi jiné než JSON jsou zabaleny jako {"data": "<text>"};
časové limity a selhání připojení jsou AI nahlášeny jako chyby, takže
se agent může omluvit a pokračovat místo toho, aby se zasekl.
Odesílání v režimu webhooku
Nástroje bez endpoint jsou odesílány na adresu staršího webhooku
vaší organizace jako podepsaný požadavek telephony.tool (telefonní
hovory) nebo web.tool (webové hovory). Na rozdíl od oznámení auditu,
která jsou doručována na endpointy webhooků po provedení, tento požadavek je
provedením — vaše odpověď HTTP je výsledkem nástroje.
{
"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 namísto from_number /
to_number. Odpovězte výsledkem nástroje ve formátu JSON — se stejným kontraktem odpovědi jako při přímých voláních endpointu. Požadavek je podepsán tajným klíčem webhooku organizace a obsahuje obě hlavičky podpisu, stejně jako každý jiný webhook.
Ověření podpisu
Přímá volání nástrojů jsou podepisována stejným způsobem jako webhooky, pomocí tajného klíče webhooku vaší organizace:
X-ThunderPhone-Signature-V2podepisuje časové razítko, metodu, cestu a dotaz tak, jak byly odeslány, a přesné bajty těla. Odmítněte požadavky, jejichž časové razítko se od vašeho času liší o více než 5 minut.X-ThunderPhone-Signature(starší verze) podepisuje pouze bajty těla, proGET/DELETEprázdný bajtový řetězec. Stále se odesílá beze změny.
Pomocné funkce SDK ověřují hlavičku V2 včetně 5minutového okna:
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 });
});Úplné postupy — podepisovaný řetězec, praktický příklad, kód bez SDK, případ GET / DELETE a upozornění pro případ chybějícího tajného klíče — naleznete v části Ověření podpisů webhooků.
Příklad: Kompletní proces rezervace
Zde je sada nástrojů pro kompletní systém rezervace termínů:
{
"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" }
}
}
]
}Osvědčené postupy
Pište jasné popisy
Pole description pomáhá AI pochopit, kdy nástroj použít. Konkrétně popište, co dělá a kdy je vhodné jej použít.
Zpracovávejte chyby správně
Vracejte chybové zprávy, kterým AI rozumí: {"error": "No slots available for that date"} namísto obecných chyb 500.
Udržujte odpovědi stručné
Vracejte pouze to, co AI potřebuje k pokračování v konverzaci. Velké datové objemy zpomalují dobu odezvy.
Používejte povinná pole uvážlivě
Označte pole jako required pouze tehdy, když je to skutečně nutné. AI před voláním nástroje požádá uživatele o povinné informace.
Související
Vyvolávejte akce hovorů spravované platformou bez definování endpointu.
Nástroje spravované platformou pro HubSpot, Salesforce, Slack, Google Calendar, Google Sheets a Cal.com — endpoint není potřeba.
Připojte server MCP a nechte agenta volat jeho nástroje.
Opakovaně použitelné integrace REST, které můžete připojit k agentům.
Jeden pomocný nástroj pro ověřování webhooků a volání nástrojů.