Fonksiyon Araçları
Yapay zeka ajanlarınıza konuşma sırasında harici API
İşlev araçları, yapay zeka ajanlarınızın telefon görüşmeleri sırasında harici API'leri çağırmasına olanak tanır. Bunları müşteri verilerini aramak, uygunluk durumunu kontrol etmek, randevu oluşturmak veya arka ucunuzun desteklediği herhangi bir işlemi gerçekleştirmek için kullanın.
Nasıl Çalışır
- Araçları bir şemayla tanımlarsınız (aracın kabul ettiği argümanlar)
- Bir
endpointyapılandırması sağlarsınız (ThunderPhone'un API'nizi çağırdığı yer) veya araç çağrılarını kuruluş webhook'unuzda almak için bunu boş bırakırsınız - Görüşme sırasında yapay zeka, konuşmaya göre bir aracın ne zaman kullanılacağına karar verir
- ThunderPhone, araç argümanlarıyla endpoint'inizi çağırır
- Konuşmayı sürdürmek için API yanıtınız yapay zekaya geri iletilir
Araç Şeması
Her araç şu yapıyı izler:
{
"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
}Araç Yapılandırması
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
timeout | sayı | Hayır | Saniye cinsinden maksimum yürütme süresi (varsayılan: 20, maksimum: 180) |
İşlev Tanımı
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
name | dize | Evet | Araç için benzersiz tanımlayıcı |
description | dize | Evet | Yapay zekaya bu aracın ne zaman kullanılacağını açıklar |
parameters | nesne | Evet | Araç argümanları için JSON Şeması |
Endpoint Yapılandırması
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
url | dize | Evet | API endpoint URL'niz |
method | dize | Hayır | HTTP yöntemi (varsayılan: POST) |
headers | nesne | Hayır | Eklenecek özel başlıklar |
İki çağırma yolu
Sunucunuzun aldığı istek, aracın bir endpoint içerip içermediğine bağlıdır:
endpoint içeren araç | endpoint içermeyen araç | |
|---|---|---|
| İsteğin gittiği yer | Doğrudan endpoint.url adresine | Kuruluşunuzun eski webhook URL'si |
| Gövde | Yalın araç argümanları | telephony.tool / web.tool zarfı |
| Başlıklar | endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| İmzalama anahtarı | Kuruluş webhook gizli anahtarı | Kuruluş webhook gizli anahtarı |
Her iki yol da bloklayıcıdır — yapay zeka, cümlenin ortasında sonucu
bekler. Varsayılan zaman aşımı 20 sn'dir; daha uzun bir yürütmeye izin
vermek için aracın üst düzey timeout değerini ayarlayın; platformun
maksimum değeri 180 sn'dir. İşleyicileri hızlı tutun. Karışık kullanım
uygundur: webhook URL'si olan bir kuruluşta yapılan görüşmede, endpoint
içeren araçlar doğrudan çağrılır ve diğerleri webhook'a geri döner.
Doğrudan uç nokta çağrıları
Yapay zeka, endpoint içeren bir aracı çağırdığında ThunderPhone,
URL'nize bir istek gönderir:
İstek Başlıkları
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-keyendpoint.headers içindeki özel başlıklar her zaman olduğu gibi
aynen eklenir; ayrıca ThunderPhone ad alanına ait iki başlık bulunur:
X-ThunderPhone-Signature— Tam istek gövdesi baytlarının, kuruluş webhook gizli anahtarınız kullanılarak oluşturulmuş HMAC-SHA256 değeriX-ThunderPhone-Call-ID— Geçerli çağrı kimliği
endpoint.headers bunu geçersiz kılmadığı sürece
Content-Type: application/json ayarlanır — özel bir Content-Type
önceliklidir.
İstek Gövdesi
POST / PUT / PATCH için gövde, kanonik olarak serileştirilmiş
(sıralanmış anahtarlar, sıkıştırılmış ayırıcılar) yalnızca araç
bağımsız değişkenlerini içerir (sarmalayıcı yoktur):
{"date":"2025-01-02","service":"consultation"}GET / DELETE için bağımsız değişkenler sorgu parametreleri
olarak gönderilir ve gövde boştur — imza bu durumda boş bayt dizisi
üzerinden hesaplanır. Bkz.
Webhook imzalarını doğrulama.
Yanıt
Araç sonucunu içeren bir JSON yanıtı döndürün:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}Yanıt biçimlendirilir ve konuşmaya devam etmesi için yapay zekaya
iletilir. JSON olmayan yanıtlar {"data": "<text>"} olarak sarmalanır;
zaman aşımları ve bağlantı hataları yapay zekaya hata olarak bildirilir,
böylece ajan özür dileyip takılmak yerine devam edebilir.
Webhook modu dağıtımı
endpoint içermeyen araçlar, kuruluşunuzun eski webhook URL'sine
imzalı telephony.tool (telefon çağrıları) veya web.tool
(web çağrıları) isteği olarak gönderilir. Araç çalıştırıldıktan sonra
webhook uç noktalarına iletilen denetim bildirimlerinden
farklı olarak bu istek çalıştırmanın kendisidir — HTTP yanıtınız
araç sonucudur.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}web.tool, from_number / to_number yerine origin_domain taşır.
Araç sonucunu JSON olarak yanıtlayın — doğrudan uç nokta çağrılarıyla
aynı yanıt sözleşmesi geçerlidir. İstek, diğer tüm webhook'larda olduğu
gibi ham gövde üzerinden kuruluş webhook gizli anahtarıyla imzalanır.
İmza Doğrulama
Doğrudan araç çağrıları, web kancalarıyla aynı şekilde imzalanır:
- Tam istek gövdesi baytları üzerinde HMAC-SHA256 (kanonik JSON — sıralanmış anahtarlar, ek boşluk olmadan)
- Kuruluşunuzun web kancası gizli anahtarıyla anahtarlanır
GET/DELETEaraçları boş bayt dizisini imzalar
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 });
});Boş gövde durumu ve gizli anahtar olmamasıyla ilgili uyarı dahil tüm örnekler Web kancası imzalarını doğrulama bölümünde yer alır.
Örnek: Eksiksiz Randevu Akışı
Eksiksiz bir randevu rezervasyon sistemi için araç kümesi aşağıdadır:
{
"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" }
}
}
]
}En İyi Uygulamalar
Açık açıklamalar yazın
description alanı, yapay zekanın aracı ne zaman kullanacağını anlamasına yardımcı olur. Aracın ne yaptığını ve ne zaman uygun olduğunu açıkça belirtin.
Hataları zarif şekilde ele alın
Genel 500 hataları yerine yapay zekanın anlayabileceği hata mesajları döndürün: {"error": "No slots available for that date"}.
Yanıtları kısa tutun
Yalnızca yapay zekanın konuşmayı sürdürmek için ihtiyaç duyduğu bilgileri döndürün. Büyük yükler yanıt sürelerini yavaşlatır.
Zorunlu alanları dikkatli kullanın
Alanları yalnızca gerçekten gerektiğinde required olarak işaretleyin. Yapay zeka, aracı çağırmadan önce kullanıcıdan zorunlu bilgileri ister.
İlgili
HubSpot, Salesforce, Slack, Google Calendar, Google Sheets ve Cal.com için platform tarafından yönetilen araçlar — uç nokta gerekmez.
Bir MCP sunucusu bağlayın ve ajanın araçlarını çağırmasına izin verin.
Ajanlara bağlayabileceğiniz yeniden kullanılabilir REST entegrasyonları.
Webhook'lar ve araç çağrıları için tek bir doğrulama yardımcısı.