---
title: "Funkciju rīki"
description: "Aprīkojiet savus balss aģentus ar funkciju rīkiem, kas sarunas laikā izsauc ārējas API — iegūst klientu datus, rezervē tikšanās, atjaunina ierakstus — ar tipizētiem parametriem."
---

Funkciju rīki ļauj jūsu balss aģentiem tālruņa zvanu laikā izsaukt ārējas API. Izmantojiet tos, lai uzmeklētu klientu datus, pārbaudītu pieejamību, rezervētu tikšanās vai veiktu jebkuru jūsu aizmugursistēmas atbalstītu darbību.

## Kā tas darbojas

1. Definējiet rīkus ar shēmu (kādus argumentus rīks pieņem)
2. Norādiet `endpoint` konfigurāciju (kur ThunderPhone izsauc jūsu API) — vai neiekļaujiet to, lai saņemtu rīku izsaukumus savas organizācijas tīmekļa aizķerē
3. Zvana laikā AI, pamatojoties uz sarunu, nosaka, kad izmantot rīku
4. ThunderPhone izsauc jūsu galapunktu ar rīka argumentiem
5. Jūsu API atbilde tiek nodota atpakaļ AI, lai turpinātu sarunu

| Iespēja | Kur tā darbojas | Iestatīšana |
| --- | --- | --- |
| [Iebūvētie rīki](/lv/guides/built-in-tools) | ThunderPhone | Uzvednes norādījumi; dažiem rīkiem nepieciešams arī aģenta iestatījums |
| [Lietotņu savienojumi](/lv/guides/connect-apps) | ThunderPhone un pievienotais pakalpojumu sniedzējs | Pievienojiet kontu un piesaistiet apstiprinātās darbības |
| [API savienojumi](/lv/guides/api-connections) un funkciju rīki | Jūsu HTTP API | Definējiet galapunktu un shēmu vai saņemiet funkciju izsaukumus, izmantojot tīmekļa aizķeri |
| [MCP serveri](/lv/guides/mcp-servers) | Attāls MCP serveris | Pievienojiet serveri, atklājiet tā rīkus un piesaistiet to aģentam |

---

## Rīka shēma

Katrs rīks izmanto šādu struktūru:

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

### Rīka konfigurācija

| Lauks | Tips | Nepieciešams | Apraksts |
|-------|------|----------|-------------|
| `timeout` | skaitlis | Nē | Maksimālais izpildes laiks sekundēs (noklusējums: `20`, maksimums: `180`) |

### Funkcijas definīcija

| Lauks | Tips | Nepieciešams | Apraksts |
|-------|------|----------|-------------|
| `name` | virkne | Jā | Unikāls rīka identifikators |
| `description` | virkne | Jā | Paskaidro AI, kad izmantot šo rīku |
| `parameters` | objekts | Jā | JSON shēma rīka argumentiem |

### Galapunkta konfigurācija

| Lauks | Tips | Nepieciešams | Apraksts |
|-------|------|----------|-------------|
| `url` | virkne | Jā | Jūsu API galapunkta URL |
| `method` | virkne | Nē | HTTP metode (noklusējums: `POST`) |
| `headers` | objekts | Nē | Iekļaujamās pielāgotās galvenes |

<Note>
  `endpoint` konfigurācija **netiek** nosūtīta AI modelim — ThunderPhone to izmanto tikai rīka izsaukuma izpildei.
</Note>

---

## Divi izsaukšanas ceļi

Tas, kuru pieprasījumu saņem jūsu serveris, ir atkarīgs no tā, vai rīkam ir
`endpoint`:

| | Rīks **ar** `endpoint` | Rīks **bez** `endpoint` |
|---|---|---|
| Kur tiek nosūtīts pieprasījums | Tieši uz `endpoint.url` | Jūsu organizācijas [mantotais tīmekļa aizķeres URL](/api-reference/organizations#legacy-single-url-webhook) |
| Pamatteksts | Atlasītais pieprasījuma formāts (pēc noklusējuma — tikai argumenti) | `telephony.tool` / `web.tool` aploksne |
| Galvenes | Jūsu `endpoint.headers` + `X-ThunderPhone-Call-ID` + `X-ThunderPhone-Signature-V2` + `X-ThunderPhone-Signature` | `Content-Type` + `X-ThunderPhone-Signature-V2` + `X-ThunderPhone-Signature` |
| Parakstīšanas atslēga | Organizācijas tīmekļa aizķeres noslēpums | Organizācijas tīmekļa aizķeres noslēpums |

Abi ceļi ir **bloķējoši** — AI teikuma vidū gaida
rezultātu. Noklusējuma taimauts ir **20 s**; iestatiet rīka augšējā līmeņa
`timeout`, lai atļautu ilgāku izpildi, līdz platformas **180 s**
maksimumam. Uzturiet apstrādātājus ātrus. Var izmantot abu veidu rīkus:
zvanā, kura organizācijai ir tīmekļa aizķeres URL, rīki ar `endpoint` tiek
izsaukti tieši, bet pārējie izmanto tīmekļa aizķeri.

## Tiešie galapunktu izsaukumi

Kad MI izsauc rīku ar `endpoint`, ThunderPhone nosūta
pieprasījumu uz jūsu URL:

### Pieprasījuma galvenes

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

Pielāgotās galvenes no jūsu `endpoint.headers` vienmēr tiek iekļautas
burtiski, kā arī šīs ThunderPhone vārdtelpas galvenes:

- `X-ThunderPhone-Signature-V2` — HMAC-SHA256 ar laika zīmogu, kas aprēķināts no
  metodes, ceļa, vaicājuma un pamatteksta, izmantojot jūsu **organizācijas tīmekļa aizķeres noslēpumu**.
  Pārbaudiet to un noraidiet pieprasījumus, kas ir vecāki par 5 minūtēm; skatiet
  [Tīmekļa aizķeres parakstu pārbaude](/lv/guides/verify-webhook-signatures)
- `X-ThunderPhone-Signature` — mantotais HMAC-SHA256 no precīziem
  pieprasījuma pamatteksta baitiem ar to pašu atslēgu, kas joprojām tiek sūtīts esošajiem verifikatoriem
- `X-ThunderPhone-Call-ID` — pašreizējās sarunas ID

`Content-Type: application/json` tiek iestatīts, ja vien jūsu `endpoint.headers`
to nepārraksta — pielāgots `Content-Type` ir prioritārs.

<Warning>
  Paraksts tiek ģenerēts ar organizācijas līmeņa tīmekļa āķa noslēpumu no
  [`GET /v1/webhook`](/api-reference/organizations#legacy-single-url-webhook).
  Ja jūsu organizācijā nekad nav konfigurēts mantotais tīmekļa āķis, nav
  noslēpuma, un rīku izsaukumi ietver **tikai** `X-ThunderPhone-Call-ID` —
  apstrādātājs, kas pārtrauc darbību, ja trūkst paraksta, tos noraidīs.
  Lai iegūtu noslēpumu, konfigurējiet mantoto tīmekļa āķi vai ievietojiet savu
  koplietojamo noslēpumu `endpoint.headers`.
</Warning>

### Pieprasījuma formāts

Katram API savienojumam ir iestatījums `request_format`. Izvēlieties `vapi` vai
`retell`, ja importētajam rīkam jāturpina izsaukt šai platformai izveidotu
galapunktu. Jauniem un esošiem savienojumiem pēc noklusējuma tiek izmantots `standard`.

Attiecībā uz `POST` / `PUT` / `PATCH` ThunderPhone kanoniski serializē atlasīto
ietvaru (sakārtotas atslēgas, kompakti atdalītāji). Abi paraksti aptver tieši šos baitus.

#### Standarta

`standard` nosūta tikai rīka argumentus bez ietvara. Šī ir noklusējuma opcija, un tā saglabā ThunderPhone sākotnējo pieprasījuma pamattekstu baitu pa baitam:

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

#### Vapi

`vapi` nosūta Vapi [`tool-calls` servera ziņojumu](https://docs.vapi.ai/tools/custom-tools)
Vapi dokumentētajā formā. `call.id` ir ThunderPhone zvana ID. Rīka izsaukuma
`id` ir unikāls konkrētajam izsaukumam un tiek atkārtoti izmantots, lai sasaistītu
galapunkta rezultātu. Zvans tiek parādīts gan `toolCallList`, gan
`toolWithToolCallList`, kur `function.arguments` ir JSON objekts:

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

Tikai Vapi paredzētie lauki, piemēram, `assistant`, `artifact` un pilnais `call`
objekts, netiek nosūtīti.

Atgrieziet Vapi atbildes ietvaru ar atbilstošo rīka izsaukuma ID:

```json
{
  "results": [
    {
      "toolCallId": "call_00112233445566778899aabbccddeeff",
      "result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
    }
  ]
}
```

ThunderPhone nodod AI neietverto `result` virkni. Savietojamībai ar galapunktiem,
kas jau atgriež JSON vērtību, tas pieņem arī JSON vērtību. `error`, kas tiek
atgriezta `result` vietā, tiek nodota AI kā rīka kļūda. Ja galapunkts atgriež
nepareizi formatētu vai neatbilstošu Vapi ietvaru, ThunderPhone reģistrē
brīdinājumu un zvana pārtraukšanas vietā izmanto standarta atbildes parsēšanu.

#### Retell

`retell` nosūta pieprasījumu, kas dokumentēts [Retell pielāgotai
funkcijai](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` ir tikai `call_id`. ThunderPhone neiekļauj Retell specifiskos
laukus, kurus tas nosūtīšanas brīdī nevar godprātīgi nodrošināt, piemēram,
`agent_id`, `transcript`, `transcript_object`, `metadata` vai dinamiskos
mainīgos. Retell pieņem jebkuru atbildes pamattekstu; ThunderPhone to nodod
tālāk, izmantojot standarta atbilžu apstrādi.

Attiecībā uz `GET` / `DELETE` argumenti tiek nosūtīti kā **vaicājuma parametri**,
un pamatteksts ir tukšs neatkarīgi no `request_format`. V2 paraksts aptver
nosūtīto vaicājuma virkni; mantotais paraksts tiek aprēķināts tukšai baitu virknei.
Skatiet sadaļu
[Tīmekļa aizķeru parakstu verificēšana](/lv/guides/verify-webhook-signatures).

### Atbilde

Atgrieziet JSON atbildi ar rīka rezultātu:

```json
{
  "available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
  "timezone": "America/Los_Angeles"
}
```

Atbilde tiek formatēta un nodota MI, lai turpinātu sarunu. Atbildes, kas nav
JSON, tiek ietvertas kā `{"data": "<text>"}`; noildzes un savienojuma kļūmes
tiek ziņotas MI kā kļūdas, lai balss aģents varētu atvainoties un turpināt,
nevis apstāties.

## Nosūtīšana tīmekļa āķa režīmā

Rīki **bez** `endpoint` tiek nosūtīti uz jūsu organizācijas mantotā
tīmekļa āķa URL kā parakstīts `telephony.tool` (tālruņa sarunas) vai `web.tool`
(tīmekļa sarunas) pieprasījums. Atšķirībā no [audita paziņojumiem](/lv/webhooks/events),
kas pēc izpildes tiek piegādāti tīmekļa āķu galapunktiem, šis pieprasījums
**ir** izpilde — jūsu HTTP atbilde ir rīka rezultāts.

```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` vietā ietver `origin_domain`. Atbildiet ar rīka rezultātu JSON formātā — tas pats atbildes līgums kā tiešiem galapunkta izsaukumiem. Pieprasījums ir parakstīts ar organizācijas tīmekļa aizķeres noslēpumu, izmantojot abas paraksta galvenes, tāpat kā jebkura cita tīmekļa aizķere.

<Note>
  Abonētie [tīmekļa āķu galapunkti](/lv/webhooks/endpoints) papildus
  saņem nebloķējošu `telephony.tool` / `web.tool` **paziņojumu pēc**
  katra rīka izpildes (neatkarīgi no ceļa, kurā tas tika izpildīts), tostarp
  rīka atbildi — noderīgi audita pierakstiem. Skatiet
  [notikumu katalogu](/lv/webhooks/events).
</Note>

---

## Paraksta verifikācija

Tiešie rīku izsaukumi tiek parakstīti tāpat kā tīmekļa aizķeres, izmantojot jūsu
organizācijas tīmekļa aizķeres noslēpumu:

- `X-ThunderPhone-Signature-V2` paraksta laika zīmogu, metodi, ceļu un
  vaicājumu nosūtītajā veidā, kā arī precīzus pamatteksta baitus. Noraidiet pieprasījumus, kuru
  laika zīmogs no jūsu pulksteņa atšķiras par vairāk nekā 5 minūtēm.
- `X-ThunderPhone-Signature` (mantotā versija) paraksta tikai pamatteksta baitus —
  tukšu baitu virkni `GET` / `DELETE` pieprasījumiem. Tā joprojām tiek nosūtīta nemainīta.

SDK palīgfunkcijas pārbauda V2 galveni, tostarp 5 minūšu logu:

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

Pilnas receptes — parakstītā virkne, izstrādāts piemērs, kods bez
SDK, `GET` / `DELETE` gadījums un atruna par noslēpuma neesību — ir pieejamas sadaļā [Tīmekļa aizķeru parakstu pārbaude](/lv/guides/verify-webhook-signatures).

---

## Piemērs: pilnīga rezervēšanas plūsma

Šeit ir rīku kopa pilnīgai vizīšu rezervēšanas sistēmai:

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

---

## Paraugprakse

<AccordionGroup>
  <Accordion title="Rakstiet skaidrus aprakstus">
    Lauks `description` palīdz mākslīgajam intelektam saprast, **kad** izmantot rīku. Precīzi norādiet, ko tas dara un kad to ir lietderīgi izmantot.
  </Accordion>

  <Accordion title="Pienācīgi apstrādājiet kļūdas">
    Atgrieziet kļūdu ziņojumus, ko mākslīgais intelekts var saprast: `{"error": "No slots available for that date"}`, nevis vispārīgas 500 kļūdas.
  </Accordion>

  <Accordion title="Saglabājiet atbildes īsas">
    Atgrieziet tikai to, kas mākslīgajam intelektam nepieciešams, lai turpinātu sarunu. Lielas datu paketes palēnina atbildes laiku.
  </Accordion>

  <Accordion title="Pārdomāti izmantojiet obligātos laukus">
    Atzīmējiet laukus kā `required` tikai tad, kad tas patiešām ir nepieciešams. Pirms rīka izsaukšanas mākslīgais intelekts prasīs lietotājam obligāto informāciju.
  </Accordion>
</AccordionGroup>

---

## Saistīts saturs

<CardGroup cols={2}>
  <Card title="Iebūvētie rīki" icon="wrench" href="/lv/guides/built-in-tools">
    Aktivizējiet platformas pārvaldītas zvanu darbības, nenorādot galapunktu.
  </Card>
  <Card title="Lietotņu savienojumi" icon="plug" href="/lv/guides/connect-apps">
    Platformas pārvaldīti rīki HubSpot, Salesforce, Slack, Google
    Calendar, Google Sheets un Cal.com — galapunkts nav nepieciešams.
  </Card>
  <Card title="MCP serveri" icon="server" href="/lv/guides/mcp-servers">
    Pievienojiet MCP serveri un ļaujiet balss aģentam izsaukt tā rīkus.
  </Card>
  <Card title="API savienojumi" icon="code" href="/lv/guides/api-connections">
    Atkārtoti izmantojamas REST integrācijas, ko varat pievienot balss aģentiem.
  </Card>
  <Card title="Pārbaudiet tīmekļa aizķeru parakstus" icon="shield-check" href="/lv/guides/verify-webhook-signatures">
    Viens pārbaudes palīgrīks tīmekļa aizķerēm un rīku izsaukumiem.
  </Card>
</CardGroup>
