ThunderPhone 2.0 je tu.Začnite sami, že od 2 ¢/min.Preberite obvestilo

Function Tools

Funkcijska orodja

Svojim agentom UI zagotovite funkcijska orodja, ki med pogovorom kličejo zunanje API-je — pridobivajo podatke o strankah, rezervirajo termine in posodabljajo zapise — s tipiziranimi parametri.

Funkcijska orodja vašim glasovnim agentom omogočajo klicanje zunanjih API-jev med telefonskimi klici. Uporabite jih za iskanje podatkov o strankah, preverjanje razpoložljivosti, rezervacijo terminov ali izvajanje katerega koli dejanja, ki ga podpira vaš zaledni sistem.

Kako deluje

  1. Orodja določite s shemo (katere argumente orodje sprejema)
  2. Zagotovite konfiguracijo endpoint (kam ThunderPhone kliče vaš API) — ali jo izpustite, da prejemate klice orodij na spletnem kavlju svoje organizacije
  3. Med klicem se AI glede na pogovor odloči, kdaj uporabiti orodje
  4. ThunderPhone pokliče vašo končno točko z argumenti orodja
  5. Odgovor vašega API-ja se posreduje nazaj AI-ju za nadaljevanje pogovora
ZmogljivostKje se izvajaNastavitev
Vgrajena orodjaThunderPhoneNavodila v pozivu; nekatera orodja potrebujejo tudi nastavitev agenta
Povezave aplikacijThunderPhone in povezani ponudnikPovežite račun in dodajte odobrena dejanja
Povezave API in funkcijska orodjaVaš HTTP APIDoločite končno točko in shemo ali prejemajte funkcijske klice prek spletnega kavlja
Strežniki MCPOddaljeni strežnik MCPDodajte strežnik, odkrijte njegova orodja in ga dodajte agentu

Shema orodja

Vsako orodje sledi tej strukturi:

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

Konfiguracija orodja

PoljeVrstaObveznoOpis
timeoutnumberNeNajdaljši čas izvajanja v sekundah (privzeto: 20, največ: 180)

Definicija funkcije

PoljeVrstaObveznoOpis
namestringDaEnolični identifikator orodja
descriptionstringDaAI-ju pojasni, kdaj uporabiti to orodje
parametersobjectDaShema JSON za argumente orodja

Konfiguracija končne točke

PoljeVrstaObveznoOpis
urlstringDaURL končne točke vašega API-ja
methodstringNeMetoda HTTP (privzeto: POST)
headersobjectNeGlave po meri, ki jih želite vključiti

Dve poti klicanja

Katero zahtevo prejme vaš strežnik, je odvisno od tega, ali ima orodje endpoint:

Orodje z endpointOrodje brez endpoint
Kam se pošlje zahtevaNeposredno na endpoint.urlNa podedovani URL spletnega kavlja vaše organizacije
TeloSami argumenti orodjaOvojnica telephony.tool / web.tool
GlaveVaše endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-SignatureContent-Type + X-ThunderPhone-Signature
Ključ za podpisovanjeSkrivnost spletnega kavlja organizacijeSkrivnost spletnega kavlja organizacije

Obe poti sta blokirni — AI sredi stavka čaka na rezultat. Privzeta časovna omejitev je 20 s; nastavite timeout na najvišji ravni orodja, da omogočite daljše izvajanje, do največje omejitve platforme 180 s. Obravnavalnike ohranite hitre. Kombinacija je povsem ustrezna: pri klicu, katerega organizacija ima URL spletnega kavlja, se orodja z endpoint pokličejo neposredno, preostala pa uporabijo spletni kavelj.

Neposredni klici končnih točk

Ko AI pokliče orodje, ki ima endpoint, ThunderPhone pošlje zahtevo na vaš URL:

Glave zahtev

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

Glave po meri iz vašega endpoint.headers so vedno vključene dobesedno, poleg dveh glav v imenskem prostoru ThunderPhone:

  • X-ThunderPhone-Signature — HMAC-SHA256 natančnih bajtov telesa zahteve, pri čemer je ključ vaš skrivni ključ webhooka organizacije
  • X-ThunderPhone-Call-ID — ID trenutnega klica

Content-Type: application/json je nastavljen, razen če ga vaš endpoint.headers prepiše — Content-Type po meri ima prednost.

Telo zahteve

Za POST / PUT / PATCH telo vsebuje samo argumente orodja (brez ovoja), kanonično serializirane (razvrščeni ključi, strnjena ločila):

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

Za GET / DELETE so argumenti poslani kot parametri poizvedbe in telo je prazno — podpis se nato izračuna nad praznim bajtnim nizom. Oglejte si Preverjanje podpisov webhookov.

Odgovor

Vrnite odgovor JSON z rezultatom orodja:

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

Odgovor je oblikovan in posredovan AI, da nadaljuje pogovor. Odgovori, ki niso JSON, so oviti kot {"data": "<text>"}; prekinitve zaradi časovne omejitve in povezave so AI sporočene kot napake, zato se lahko agent opraviči in nadaljuje, namesto da obstane.

Posredovanje v načinu webhook

Orodja brez endpoint so posredovana na URL starejšega webhooka vaše organizacije kot podpisana zahteva telephony.tool (telefonski klici) ali web.tool (spletni klici). Za razliko od obvestil za revizijo, dostavljenih na končne točke webhookov po izvedbi, ta zahteva je izvedba — vaš odgovor HTTP je rezultat orodja.

{
  "type": "telephony.tool",
  "data": {
    "call_id": 987654321,
    "tool_name": "search_appointments",
    "arguments": { "date": "2026-04-21" },
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  }
}

web.tool namesto from_number / to_number vsebuje origin_domain. Na rezultat orodja odgovorite kot JSON — velja ista pogodba za odgovor kot pri neposrednih klicih končnih točk. Zahteva je s skrivnim ključem webhooka organizacije podpisana nad neobdelanim telesom, kot vsak drug webhook.


Preverjanje podpisa

Neposredni klici orodij so podpisani enako kot spletni kljuki:

  • HMAC-SHA256 nad natančnimi bajti telesa zahteve (kanonični JSON — razvrščeni ključi, brez dodatnih presledkov)
  • S ključem, ki je skrivnost spletne kljuke vaše organizacije
  • Orodja GET / DELETE podpišejo prazen niz bajtov
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 });
});

Celotni recepti — vključno s primerom praznega telesa in opozorilom glede odsotnosti skrivnosti — so v razdelku Preverjanje podpisov spletnih kljuk.


Primer: celoten potek rezervacije

Tukaj je nabor orodij za celoten sistem rezervacije terminov:

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

Najboljše prakse

Napišite jasne opise

Polje description pomaga UI razumeti, kdaj uporabiti orodje. Natančno opišite, kaj počne in kdaj ga je primerno uporabiti.

Ustrezno obravnavajte napake

Vrnite sporočila o napakah, ki jih UI razume: {"error": "No slots available for that date"} namesto splošnih napak 500.

Odgovori naj bodo jedrnati

Vrnite samo tisto, kar UI potrebuje za nadaljevanje pogovora. Velika bremena upočasnijo odzivni čas.

Polja, ki so obvezna, uporabljajte premišljeno

Polja označite kot required le, kadar je to res potrebno. UI bo pred klicem orodja uporabnika vprašala za zahtevane informacije.


Sorodno