ThunderPhone 2.0 yayında.Kendi başınıza kullanmaya başlayın; dakikada 2¢'den başlayan fiyatlarla.Duyuruyu okuyun

Function Tools

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

  1. Araçları bir şemayla tanımlarsınız (aracın kabul ettiği argümanlar)
  2. Bir endpoint yapı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
  3. Görüşme sırasında yapay zeka, konuşmaya göre bir aracın ne zaman kullanılacağına karar verir
  4. ThunderPhone, araç argümanlarıyla endpoint'inizi çağırır
  5. 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ı

AlanTürZorunluAçıklama
timeoutsayıHayırSaniye cinsinden maksimum yürütme süresi (varsayılan: 20, maksimum: 180)

İşlev Tanımı

AlanTürZorunluAçıklama
namedizeEvetAraç için benzersiz tanımlayıcı
descriptiondizeEvetYapay zekaya bu aracın ne zaman kullanılacağını açıklar
parametersnesneEvetAraç argümanları için JSON Şeması

Endpoint Yapılandırması

AlanTürZorunluAçıklama
urldizeEvetAPI endpoint URL'niz
methoddizeHayırHTTP yöntemi (varsayılan: POST)
headersnesneHayırEklenecek ö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 yerDoğrudan endpoint.url adresineKuruluşunuzun eski webhook URL'si
GövdeYalın araç argümanlarıtelephony.tool / web.tool zarfı
Başlıklarendpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-SignatureContent-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-key

endpoint.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ğeri
  • X-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 / DELETE araçları boş bayt dizisini imzalar
Python
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}
Node.js
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