ThunderPhone 2.0 ir klāt.Sāciet uzreiz — no 2 centiem minūtē.Lasīt paziņojumu

Function Tools

Funkciju rīki

Nodrošiniet saviem balss aģentiem funkciju rīkus, kas sarunas laikā izsauc ārējas API — iegūst klientu datus, rezervē vizītes, 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 meklētu klientu datus, pārbaudītu pieejamību, rezervētu tikšanās vai veiktu jebkuru darbību, ko atbalsta jūsu aizmugursistēma.

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 atstājiet to nenorādītu, 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.

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

LauksTipsObligātsApraksts
timeoutskaitlisMaksimālais izpildes laiks sekundēs (noklusējums: 20, maksimums: 180)

Funkcijas definīcija

LauksTipsObligātsApraksts
namevirkneUnikāls rīka identifikators
descriptionvirknePaskaidro AI, kad izmantot šo rīku
parametersobjektsJSON shēma rīka argumentiem

Galapunkta konfigurācija

LauksTipsObligātsApraksts
urlvirkneJūsu API galapunkta URL
methodvirkneHTTP metode (noklusējums: POST)
headersobjektsIekļaujamās pielāgotās galvenes

Divi izsaukšanas ceļi

Tas, kādu 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 mantotā tīmekļa aizķeres URL
PamattekstsTikai rīka argumentitelephony.tool / web.tool aploksne
GalvenesJūsu endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-SignatureContent-Type + X-ThunderPhone-Signature
Parakstīšanas atslēgaOrganizācijas tīmekļa aizķeres slepenā atslēgaOrganizācijas tīmekļa aizķeres slepenā atslēga

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 arī kombināciju: zvanā, kuras 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 AI 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: 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ī divas ThunderPhone nosaukumvietas galvenes:

  • X-ThunderPhone-Signature — precīzo pieprasījuma pamatteksta baitu HMAC-SHA256, kam kā atslēga izmantota jūsu organizācijas tīmekļa aizķeres slepenā atslēga
  • X-ThunderPhone-Call-ID — Pašreizējais zvana ID

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

Pieprasījuma pamatteksts

POST / PUT / PATCH pieprasījumiem pamattekstā ir tikai rīka argumenti (bez ietvara), kas serializēti kanoniski (sakārtotas atslēgas, kompakti atdalītāji):

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

GET / DELETE pieprasījumiem argumenti tiek nosūtīti kā vaicājuma parametri, un pamatteksts ir tukšs — paraksts tad tiek aprēķināts tukšajai baitu virknei. Skatiet Pārbaudīt tīmekļa aizķeres parakstus.

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 AI, lai turpinātu sarunu. Atbildes, kas nav JSON, tiek ietvertas kā {"data": "<text>"}; par noildzēm un savienojuma kļūmēm AI tiek ziņots kā par kļūdām, lai balss aģents varētu atvainoties un turpināt, nevis apstāties.

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

Rīki bez endpoint tiek nosūtīti uz jūsu organizācijas mantotās tīmekļa aizķeres URL kā parakstīts telephony.tool (tālruņa zvani) vai web.tool (tīmekļa zvani) pieprasījums. Atšķirībā no audita paziņojumiem, kas pēc izpildes tiek piegādāti tīmekļa aizķeres 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 satur origin_domain, nevis from_number / to_number. Atbildiet ar rīka rezultātu JSON formātā — tas ir tas pats atbildes līgums kā tiešajiem galapunktu izsaukumiem. Pieprasījums tiek parakstīts ar organizācijas tīmekļa aizķeres slepeno atslēgu, izmantojot neapstrādātu pamattekstu, 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:

  • HMAC-SHA256, izmantojot precīzus pieprasījuma pamatteksta baitus (kanonisko JSON — sakārtotas atslēgas, bez papildu atstarpēm)
  • Ar jūsu organizācijas tīmekļa aizķeres noslēpumu
  • GET / DELETE rīki paraksta tukšu baitu virkni
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 });
});

Pilnīgas receptes — tostarp tukša pamatteksta gadījumam un noslēpuma neesamības nosacījumam — ir pieejamas sadaļā Tīmekļa aizķeres 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" }
      }
    }
  ]
}

Ieteicamā prakse

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.

Korekti apstrādājiet kļūdas

Atgrieziet mākslīgajam intelektam saprotamus kļūdu ziņojumus: {"error": "No slots available for that date"}, nevis vispārīgas 500 kļūdas.

Uzturiet atbildes īsas

Atgrieziet tikai to, kas mākslīgajam intelektam nepieciešams sarunas turpināšanai. 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 lūgs lietotājam obligāto informāciju.


Saistītā informācija