---
title: "Fonksiyon Araçları"
description: "Yapay zeka ajanlarınıza, konuşma sırasında harici API'leri çağıran — müşteri verilerini getiren, randevu oluşturan, kayıtları güncelleyen — tür tanımlı parametrelere sahip fonksiyon araçları sağlayın."
---

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

1. Araçları bir şemayla tanımlarsınız (aracın kabul ettiği bağımsız değişkenler)
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ı ne zaman kullanacağına karar verir
4. ThunderPhone, araç bağımsız değişkenleriyle endpoint'inizi çağırır
5. 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](/tr/guides/built-in-tools) | ThunderPhone | İstem talimatları; bazı araçlar ayrıca bir ajan ayarı gerektirir |
| [Uygulama bağlantıları](/tr/guides/connect-apps) | ThunderPhone ve bağlı sağlayıcı | Hesabı bağlayın ve onaylanmış eylemleri ekleyin |
| [API bağlantıları](/tr/guides/api-connections) 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ı](/tr/guides/mcp-servers) | Uzak bir MCP sunucusu | Sunucuyu ekleyin, araçlarını keşfedin ve ajana ekleyin |

---

## Araç Şeması

Her araç şu yapıyı izler:

```json
{
  "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 |

<Note>
  `endpoint` yapılandırması yapay zeka modeline **gönderilmez**; yalnızca ThunderPhone tarafından araç çağrısını yürütmek için kullanılır.
</Note>

---

## İ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](/api-reference/organizations#legacy-single-url-webhook) |
| 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ı

```http
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-key
```

`endpoint.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ğrulama](/tr/guides/verify-webhook-signatures)
- `X-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 eder
- `X-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.

<Warning>
  İmza, [`GET /v1/webhook`](/api-reference/organizations#legacy-single-url-webhook)
  kaynağındaki kuruluş düzeyindeki webhook gizli anahtarı kullanılarak oluşturulur.
  Kuruluşunuz eski webhook'u hiç yapılandırmadıysa gizli anahtar yoktur ve araç
  çağrıları **yalnızca** `X-ThunderPhone-Call-ID` taşır — eksik imzada kesin olarak
  başarısız olan bir işleyici bu çağrıları reddeder.
  Gizli anahtar almak için eski webhook'u yapılandırın veya kendi ortak gizli
  anahtarınızı `endpoint.headers` içine yerleştirin.
</Warning>

### İ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:

```json
{"date":"2025-01-02","service":"consultation"}
```

#### Vapi

`vapi`, Vapi'nin [özel araçlar](https://docs.vapi.ai/tools/custom-tools) 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:

```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" }
          }
        }
      }
    ]
  }
}
```

`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:

```json
{
  "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](https://docs.retellai.com/build/single-multi-prompt/custom-function) için belgelenen isteği gönderir:

```json
{
  "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](/tr/guides/verify-webhook-signatures).

### Yanıt

Araç sonucunu içeren bir JSON yanıtı döndürün:

```json
{
  "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](/tr/webhooks/events)
farklı olarak, bu istek yürütmenin **kendisidir** — HTTP yanıtınız araç
sonucudur.

```json
{
  "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.

<Note>
  Abone olunan [webhook uç noktaları](/tr/webhooks/endpoints) ayrıca her aracın
  yürütülmesinden **sonra bildirim** olarak, aracın yanıtı da dahil olmak üzere
  engellemeyen bir `telephony.tool` / `web.tool` bildirimi alır (aracı hangi yol
  çalıştırdıysa). Bu, denetim izleri için kullanışlıdır. Bkz.
  [olay kataloğu](/tr/webhooks/events).
</Note>

---

## İ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` / `DELETE` iç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:

<CodeGroup>
```python Python
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}
```

```javascript Node.js
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 });
});
```
</CodeGroup>

İ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](/tr/guides/verify-webhook-signatures) bölümündedir.

---

## Örnek: Eksiksiz Randevu Akışı

Eksiksiz bir randevu rezervasyon sistemi için araç seti aşağıdadır:

```json
{
  "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

<AccordionGroup>
  <Accordion title="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.
  </Accordion>

  <Accordion title="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"}`.
  </Accordion>

  <Accordion title="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.
  </Accordion>

  <Accordion title="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.
  </Accordion>
</AccordionGroup>

---

## İlgili

<CardGroup cols={2}>
  <Card title="Yerleşik araçlar" icon="wrench" href="/tr/guides/built-in-tools">
    Bir uç nokta tanımlamadan platform tarafından yönetilen arama işlemlerini istemde belirtin.
  </Card>
  <Card title="Uygulama bağlantıları" icon="plug" href="/tr/guides/connect-apps">
    HubSpot, Salesforce, Slack, Google
    Calendar, Google Sheets ve Cal.com için platform tarafından yönetilen araçlar — uç nokta gerekmez.
  </Card>
  <Card title="MCP sunucuları" icon="server" href="/tr/guides/mcp-servers">
    Bir MCP sunucusu bağlayın ve ajanın araçlarını çağırmasına izin verin.
  </Card>
  <Card title="API bağlantıları" icon="code" href="/tr/guides/api-connections">
    Ajanlara bağlayabileceğiniz yeniden kullanılabilir REST entegrasyonları.
  </Card>
  <Card title="Webhook imzalarını doğrulayın" icon="shield-check" href="/tr/guides/verify-webhook-signatures">
    Webhook'lar ve araç çağrıları için tek bir doğrulama yardımcısı.
  </Card>
</CardGroup>
