---
title: "Nástroje funkcí"
description: "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

1. Definujete nástroje pomocí schématu (jaké argumenty nástroj přijímá)
2. 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
3. Během hovoru AI podle konverzace rozhodne, kdy nástroj použít
4. ThunderPhone zavolá váš endpoint s argumenty nástroje
5. 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](/cs/guides/built-in-tools) | ThunderPhone | Pokyny v promptu; některé nástroje také vyžadují nastavení agenta |
| [Připojení aplikací](/cs/guides/connect-apps) | ThunderPhone a připojený poskytovatel | Připojte účet a přiřaďte schválené akce |
| [Připojení API](/cs/guides/api-connections) 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](/cs/guides/mcp-servers) | 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:

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

### 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í |

<Note>
  Konfigurace `endpoint` se modelu AI **neodesílá** — ThunderPhone ji používá pouze k provedení volání nástroje.
</Note>

---

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

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

Vlastní 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ů](/cs/guides/verify-webhook-signatures)
- `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če
- `X-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.

<Warning>
  Podpis používá jako klíč tajemství webhooku na úrovni organizace z
  [`GET /v1/webhook`](/api-reference/organizations#legacy-single-url-webhook).
  Pokud vaše organizace nikdy nenakonfigurovala starší webhook, nemá
  žádné tajemství a volání nástrojů obsahují **pouze**
  `X-ThunderPhone-Call-ID` — obslužná rutina, která selže při chybějícím
  podpisu, by je odmítla.
  Chcete-li získat tajemství, nakonfigurujte starší webhook, nebo vložte
  vlastní sdílené tajemství do `endpoint.headers`.
</Warning>

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

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

#### Vapi

`vapi` odesílá [serverovou zprávu `tool-calls` platformy Vapi](https://docs.vapi.ai/tools/custom-tools)
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:

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

```json
{
  "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](https://docs.retellai.com/build/single-multi-prompt/custom-function):

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

### Odpověď

Vraťte odpověď JSON s výsledkem nástroje:

```json
{
  "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](/cs/webhooks/events),
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.

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

<Note>
  Přihlášené [endpointy webhooků](/cs/webhooks/endpoints) navíc dostávají
  neblokující **oznámení `telephony.tool` / `web.tool`
  po** každém provedení nástroje (bez ohledu na použitou cestu), včetně
  odpovědi nástroje — užitečné pro auditní stopy. Viz
  [katalog událostí](/cs/webhooks/events).
</Note>

---

## 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-V2` podepisuje č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, pro `GET` / `DELETE` prá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:

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

Ú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ů](/cs/guides/verify-webhook-signatures).

---

## Příklad: Kompletní proces rezervace

Zde je sada nástrojů pro kompletní systém rezervace termínů:

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

---

## Osvědčené postupy

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

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

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

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

---

## Související

<CardGroup cols={2}>
  <Card title="Vestavěné nástroje" icon="wrench" href="/cs/guides/built-in-tools">
    Vyvolávejte akce hovorů spravované platformou bez definování endpointu.
  </Card>
  <Card title="Připojení aplikací" icon="plug" href="/cs/guides/connect-apps">
    Nástroje spravované platformou pro HubSpot, Salesforce, Slack, Google
    Calendar, Google Sheets a Cal.com — endpoint není potřeba.
  </Card>
  <Card title="Servery MCP" icon="server" href="/cs/guides/mcp-servers">
    Připojte server MCP a nechte agenta volat jeho nástroje.
  </Card>
  <Card title="Připojení API" icon="code" href="/cs/guides/api-connections">
    Opakovaně použitelné integrace REST, které můžete připojit k agentům.
  </Card>
  <Card title="Ověření podpisů webhooků" icon="shield-check" href="/cs/guides/verify-webhook-signatures">
    Jeden pomocný nástroj pro ověřování webhooků a volání nástrojů.
  </Card>
</CardGroup>
