Open in
Fonksiyon Araçları
Yapay zeka ajanlarınıza, konuşma sırasında harici API
Fonksiyon 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 sorgulamak, 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 bağımsız değişkenler)
- 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ı ne zaman kullanacağına karar verir
- ThunderPhone, araç bağımsız değişkenleriyle endpoint'inizi çağırır
- API yanıtınız, konuşmayı sürdürmesi için yapay zekaya geri iletilir
| Özellik | Çalıştığı yer | Kurulum |
|---|---|---|
| Yerleşik araçlar | ThunderPhone | İstem talimatları; bazı araçlar ayrıca bir ajan ayarı gerektirir |
| Uygulama bağlantıları | ThunderPhone ve bağlı sağlayıcı | Hesabı bağlayın ve onaylanmış eylemleri ekleyin |
| API bağlantıları ve fonksiyon araçları | HTTP API'niz | Endpoint'i ve şemayı tanımlayın veya fonksiyon çağrılarını webhook üzerinden alın |
| MCP sunucuları | Uzak bir MCP sunucusu | Sunucuyu ekleyin, araçlarını keşfedin ve ajana ekleyin |
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) |
Fonksiyon 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ı ne zaman kullanacağını açıklar |
parameters | nesne | Evet | Araç bağımsız değişkenleri 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 üst bilgiler |
İki çağırma yolu
Sunucunuzun aldığı istek, aracın bir
endpoint değerine sahip olup olmamasına bağlıdır:
endpoint olan araç | endpoint olmayan araç | |
|---|---|---|
| İsteğin gönderildiği yer | Doğrudan endpoint.url | Kuruluşunuzun eski webhook URL'si |
| Gövde | Seçilen istek biçimi (varsayılan olarak yalın bağımsız değişkenler) | telephony.tool / web.tool zarfı |
| Başlıklar | endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature-V2 + 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 s değeridir; daha uzun bir yürütmeye izin vermek için aracın üst düzey
timeout değerini platformun 180 s olan
maksimumuna kadar ayarlayın. İşleyicileri hızlı tutun. Karma kullanım uygundur:
kuruluşunda webhook URL'si bulunan bir 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 bir endpoint içeren 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-V2: t=1767225600,v1=5f2c...
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-keyendpoint.headers içindeki özel üstbilgiler her zaman olduğu gibi
aynen eklenir. Buna ek olarak şu ThunderPhone ad alanındaki üstbilgiler de eklenir:
X-ThunderPhone-Signature-V2— yöntemi, yolu, sorguyu ve gövdeyi kapsayan, organizasyon webhook gizli anahtarınızla anahtarlanmış zaman damgalı HMAC-SHA256. Bunu doğrulayın ve 5 dakikadan eski istekleri reddedin; bkz. Webhook imzalarını doğrulamaX-ThunderPhone-Signature— tam istek gövdesi baytlarının eski HMAC-SHA256 değeri; aynı anahtarı kullanır ve mevcut doğrulayıcılar için gönderilmeye devam ederX-ThunderPhone-Call-ID— Geçerli arama kimliği
endpoint.headers bunu geçersiz kılmadığı sürece
Content-Type: application/json ayarlanır — özel bir Content-Type
önceliklidir.
İstek biçimi
Her API bağlantısının bir request_format ayarı vardır. İçe aktarılan bir aracın o platform için oluşturulmuş bir uç noktayı çağırmayı sürdürmesi gerektiğinde vapi veya retell seçin. Yeni ve mevcut bağlantılar varsayılan olarak standard kullanır.
POST / PUT / PATCH için ThunderPhone, seçilen zarfı standart biçimde serileştirir (anahtarlar sıralanır, ayırıcılar sıkıştırılır). Her iki imza da tam olarak bu baytları kapsar.
Standard
standard, sarmalayıcı olmadan yalnızca araç bağımsız değişkenlerini gönderir. Bu varsayılandır ve ThunderPhone'un orijinal istek gövdesini bayt bayt korur:
{"date":"2025-01-02","service":"consultation"}Vapi
vapi, Vapi'nin özel araçlar için belgelediği biçimde Vapi'nin tool-calls sunucu mesajını gönderir. call.id, ThunderPhone arama kimliğidir. Araç çağrısı id değeri çağrıya özeldir ve uç noktanın sonucuyla eşleştirmek için yeniden kullanılır. Arama, function.arguments bir JSON nesnesi olacak şekilde hem toolCallList hem de toolWithToolCallList içinde görünür:
{
"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" }
}
}
}
]
}
}assistant, artifact ve tam call nesnesi gibi yalnızca Vapi'ye özgü alanlar gönderilmez.
Eşleşen araç çağrısı kimliğiyle Vapi'nin yanıt zarfını döndürün:
{
"results": [
{
"toolCallId": "call_00112233445566778899aabbccddeeff",
"result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
}
]
}ThunderPhone, AI'a sarmalayıcısı kaldırılmış result dizesini verir. Ayrıca, zaten JSON değeri döndüren uç noktalarla uyumluluk için JSON değeri de kabul eder. result yerine bir error değeri, AI'a araç hatası olarak döndürülür. Uç nokta hatalı biçimlendirilmiş veya eşleşmeyen bir Vapi zarfı döndürürse ThunderPhone bir uyarı günlüğe kaydeder ve aramayı başarısız kılmak yerine standart yanıt ayrıştırmasına geri döner.
Retell
retell, bir Retell özel işlevi için belgelenen isteği gönderir:
{
"name": "search_appointments",
"call": { "call_id": "987654321" },
"args": { "date": "2025-01-02", "service": "consultation" }
}call nesnesi yalnızca call_id içerir. ThunderPhone, gönderim sırasında güvenilir biçimde sağlayamadığı agent_id, transcript, transcript_object, metadata veya dinamik değişkenler gibi Retell'e özgü alanları içermez. Retell herhangi bir yanıt gövdesini kabul eder; ThunderPhone bunu standart yanıt işleme yöntemiyle iletir.
GET / DELETE için bağımsız değişkenler sorgu parametreleri olarak gönderilir ve request_format ne olursa olsun gövde boştur. V2 imzası, gönderildiği şekliyle sorgu dizesini kapsar; eski imza boş bayt dizesi ü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 görüşmeye devam etmesi için yapay zekaya
sağlanır. JSON olmayan yanıtlar {"data": "<text>"} olarak sarmalanır;
zaman aşımları ve bağlantı hataları yapay zekaya hata olarak bildirilir,
böylece yapay zeka ajanı takılıp kalmak yerine özür dileyip devam edebilir.
Webhook modu yönlendirmesi
endpoint içermeyen araçlar, kuruluşunuzun eski webhook URL'sine
imzalı bir telephony.tool (telefon çağrıları) veya web.tool
(web çağrıları) isteği olarak yönlendirilir. Yürütmeden sonra webhook
uç noktalarına gönderilen denetim bildirimlerinden
farklı olarak, bu istek yürütmenin 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 içerir. Araç sonucuyla JSON olarak yanıt verin — doğrudan endpoint çağrılarıyla aynı yanıt sözleşmesi geçerlidir. İstek, diğer tüm webhook'lar gibi her iki imza başlığıyla kuruluş webhook gizli anahtarı kullanılarak imzalanır.
İmza Doğrulama
Doğrudan araç çağrıları, kuruluşunuzun webhook gizli anahtarıyla webhooks'larla aynı şekilde imzalanır:
X-ThunderPhone-Signature-V2, gönderildiği şekliyle zaman damgasını, yöntemi, yolu ve sorguyu ve gövdenin tam baytlarını imzalar. Zaman damgası saatinizden 5 dakikadan fazla farklı olan istekleri reddedin.X-ThunderPhone-Signature(eski),GET/DELETEiçin boş bayt dizisi olmak üzere yalnızca gövde baytlarını imzalar. Değiştirilmeden gönderilmeye devam eder.
SDK yardımcıları, 5 dakikalık süre penceresi dahil olmak üzere V2 başlığını kontrol eder:
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 });
});İmzalı dize, işlenmiş örnek, SDK olmadan kod, GET / DELETE durumu ve gizli anahtar yoksa geçerli olan uyarı dahil tam tarifler Webhook imzalarını doğrulama bölümündedir.
Örnek: Eksiksiz Randevu Akışı
Eksiksiz bir randevu rezervasyon sistemi için araç seti 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 bir şekilde yönetin
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
Bir uç nokta tanımlamadan platform tarafından yönetilen arama işlemlerini istemde belirtin.
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ı.