ThunderPhone 2.0 ir klāt.Sāciet patstāvīgi — no 2 ¢/min.Lasīt paziņojumu

Function Tools

Funkciju rīki

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ējaKur tā darbojasIestatīšana
Iebūvētie rīkiThunderPhoneUzvednes norādījumi; dažiem rīkiem nepieciešams arī aģenta iestatījums
Lietotņu savienojumiThunderPhone un pievienotais pakalpojumu sniedzējsPievienojiet kontu un piesaistiet apstiprinātās darbības
API savienojumi un funkciju rīkiJūsu HTTP APIDefinējiet galapunktu un shēmu vai saņemiet funkciju izsaukumus, izmantojot tīmekļa aizķeri
MCP serveriAttāls MCP serverisPievienojiet serveri, atklājiet tā rīkus un piesaistiet to aģentam

Rīka shēma

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

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

LauksTipsNepieciešamsApraksts
timeoutskaitlisNēMaksimālais izpildes laiks sekundēs (noklusējums: 20, maksimums: 180)

Funkcijas definīcija

LauksTipsNepieciešamsApraksts
namevirkneJāUnikāls rīka identifikators
descriptionvirkneJāPaskaidro AI, kad izmantot šo rīku
parametersobjektsJāJSON shēma rīka argumentiem

Galapunkta konfigurācija

LauksTipsNepieciešamsApraksts
urlvirkneJāJūsu API galapunkta URL
methodvirkneNēHTTP metode (noklusējums: POST)
headersobjektsNēIekļaujamās pielāgotās galvenes

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 endpointRīks bez endpoint
Kur tiek nosūtīts pieprasījumsTieši uz endpoint.urlJūsu organizācijas mantotais tīmekļa aizķeres URL
PamattekstsAtlasītais pieprasījuma formāts (pēc noklusējuma — tikai argumenti)telephony.tool / web.tool aploksne
GalvenesJūsu endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature-V2 + X-ThunderPhone-SignatureContent-Type + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature
Parakstīšanas atslēgaOrganizācijas tīmekļa aizķeres noslēpumsOrganizā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

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

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:

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

Vapi

vapi nosūta Vapi tool-calls servera ziņojumu 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:

{
  "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:

{
  "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:

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

Atbilde

Atgrieziet JSON atbildi ar rīka rezultātu:

{
  "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, 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.

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


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:

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}
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 });
});

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.


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

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

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

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.

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.

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.

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.


Saistīts saturs