ThunderPhone 2.0 ist live.Direkt im Self-Service – ab 2 ¢/Min..Ankündigung lesen

Function Tools

Funktionswerkzeuge

Geben Sie Ihren KI-Agenten Funktionswerkzeuge, die während des Gesprächs externe APIs aufrufen — Kundendaten abrufen, Termine buchen, Datensätze aktualisieren — mit typisierten Parametern.

Funktions-Tools ermöglichen Ihren KI-Agenten, während Telefonaten externe APIs aufzurufen. Verwenden Sie sie, um Kundendaten abzurufen, Verfügbarkeiten zu prüfen, Termine zu buchen oder jede von Ihrem Backend unterstützte Aktion auszuführen.

Funktionsweise

  1. Definieren Sie Tools mit einem Schema (welche Argumente das Tool akzeptiert)
  2. Geben Sie eine endpoint-Konfiguration an (wo ThunderPhone Ihre API aufruft) — oder lassen Sie sie weg, um Tool-Aufrufe über den Webhook Ihrer Organisation zu erhalten
  3. Während eines Anrufs entscheidet die KI anhand des Gesprächs, wann ein Tool verwendet werden soll
  4. ThunderPhone ruft Ihren Endpunkt mit den Tool-Argumenten auf
  5. Die API-Antwort wird an die KI zurückgegeben, damit sie das Gespräch fortsetzen kann
FunktionAusführungsortEinrichtung
Integrierte ToolsThunderPhonePrompt-Anweisungen; einige Tools benötigen zusätzlich eine Agenteneinstellung
App-VerbindungenThunderPhone und der verbundene AnbieterVerbinden Sie das Konto und fügen Sie genehmigte Aktionen hinzu
API-Verbindungen und Funktions-ToolsIhre HTTP-APIDefinieren Sie den Endpunkt und das Schema oder empfangen Sie Funktionsaufrufe über einen Webhook
MCP-ServerEin Remote-MCP-ServerFügen Sie den Server hinzu, ermitteln Sie seine Tools und verknüpfen Sie ihn mit dem Agenten

Tool-Schema

Jedes Tool folgt dieser Struktur:

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

Tool-Konfiguration

FeldTypErforderlichBeschreibung
timeoutZahlNeinMaximale Ausführungszeit in Sekunden (Standard: 20, Maximum: 180)

Funktionsdefinition

FeldTypErforderlichBeschreibung
nameZeichenfolgeJaEindeutiger Bezeichner für das Tool
descriptionZeichenfolgeJaErklärt der KI, wann dieses Tool verwendet werden soll
parametersObjektJaJSON-Schema für Tool-Argumente

Endpunkt-Konfiguration

FeldTypErforderlichBeschreibung
urlZeichenfolgeJaURL Ihres API-Endpunkts
methodZeichenfolgeNeinHTTP-Methode (Standard: POST)
headersObjektNeinEinzuschließende benutzerdefinierte Header

Zwei Aufrufpfade

Welche Anfrage Ihr Server erhält, hängt davon ab, ob das Tool einen endpoint hat:

Tool mit endpointTool ohne endpoint
Ziel der AnfrageDirekt an endpoint.urlDie Legacy-Webhook-URL Ihrer Organisation
BodyAusgewähltes Anfrageformat (standardmäßig reine Argumente)telephony.tool / web.tool-Envelope
HeaderIhre endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature-V2 + X-ThunderPhone-SignatureContent-Type + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature
SignaturschlüsselWebhook-Secret der OrganisationWebhook-Secret der Organisation

Beide Pfade sind blockierend — die KI wartet mitten im Satz auf das Ergebnis. Das Standard-Timeout beträgt 20 s; legen Sie das oberste timeout des Tools fest, um eine längere Ausführung bis zum Plattformmaximum von 180 s zu erlauben. Halten Sie Handler schnell. Eine Mischung ist möglich: Bei einem Anruf, dessen Organisation eine Webhook-URL hat, werden Tools mit einem endpoint direkt aufgerufen, während die übrigen auf den Webhook zurückfallen.

Direkte Endpunktaufrufe

Wenn die KI ein Tool mit einem endpoint aufruft, sendet ThunderPhone eine Anfrage an Ihre URL:

Anfrage-Header

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

Benutzerdefinierte Header aus Ihren endpoint.headers werden immer unverändert einbezogen, zusätzlich zu diesen Headern im ThunderPhone-Namensraum:

  • X-ThunderPhone-Signature-V2 — HMAC-SHA256 mit Zeitstempel über Methode, Pfad, Abfrage und Body, signiert mit Ihrem Webhook-Geheimnis der Organisation. Überprüfen Sie diesen und lehnen Sie Anfragen ab, die älter als 5 Minuten sind; siehe Webhook-Signaturen überprüfen
  • X-ThunderPhone-Signature — Legacy-HMAC-SHA256 der exakten Request-Body-Bytes, mit demselben Schlüssel, wird weiterhin für bestehende Verifizierer gesendet
  • X-ThunderPhone-Call-ID — Die aktuelle Anruf-ID

Content-Type: application/json wird gesetzt, sofern Ihr endpoint.headers ihn nicht überschreibt — ein benutzerdefinierter Content-Type hat Vorrang.

Anfrageformat

Jede API-Verbindung verfügt über eine Einstellung für request_format. Wählen Sie vapi oder retell, wenn ein importiertes Tool weiterhin einen für diese Plattform erstellten Endpunkt aufrufen soll. Neue und bestehende Verbindungen verwenden standardmäßig standard.

Für POST / PUT / PATCH serialisiert ThunderPhone den ausgewählten Umschlag kanonisch (sortierte Schlüssel, kompakte Trennzeichen). Beide Signaturen decken diese exakten Bytes ab.

Standard

standard sendet nur die Tool-Argumente ohne Wrapper. Dies ist die Standardeinstellung und bewahrt den ursprünglichen Anfrage-Body von ThunderPhone Byte für Byte:

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

Vapi

vapi sendet Vapis tool-calls-Servernachricht in der von Vapi dokumentierten Form. Die call.id ist die ThunderPhone-Anruf-ID. Die Tool-Call-id ist für den Aufruf eindeutig und wird wiederverwendet, um das Ergebnis des Endpunkts zuzuordnen. Der Anruf erscheint sowohl in toolCallList als auch in toolWithToolCallList, wobei function.arguments ein JSON-Objekt ist:

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

Nur für Vapi bestimmte Felder wie assistant, artifact und das vollständige call-Objekt werden nicht gesendet.

Geben Sie Vapis Antwortumschlag mit der passenden Tool-Call-ID zurück:

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

ThunderPhone übergibt der KI die entpackte result-Zeichenfolge. Aus Kompatibilitätsgründen akzeptiert es auch einen JSON-Wert für Endpunkte, die bereits einen solchen zurückgeben. Ein error anstelle von result wird der KI als Tool-Fehler zurückgegeben. Gibt der Endpunkt einen fehlerhaften oder nicht passenden Vapi-Umschlag zurück, protokolliert ThunderPhone eine Warnung und greift auf die standardmäßige Antwortverarbeitung zurück, anstatt den Anruf fehlschlagen zu lassen.

Retell

retell sendet die für eine benutzerdefinierte Retell-Funktion dokumentierte Anfrage:

{
  "name": "search_appointments",
  "call": { "call_id": "987654321" },
  "args": { "date": "2025-01-02", "service": "consultation" }
}

Das call-Objekt enthält nur call_id. ThunderPhone enthält keine Retell-spezifischen Felder, die es beim Versand nicht korrekt bereitstellen kann, wie agent_id, transcript, transcript_object, metadata oder dynamische Variablen. Retell akzeptiert jeden Antworttext; ThunderPhone leitet ihn mit der standardmäßigen Antwortverarbeitung weiter.

Für GET / DELETE werden die Argumente als Abfrageparameter gesendet und der Anfragekörper ist unabhängig von request_format leer. Die V2-Signatur deckt die gesendete Abfragezeichenfolge ab; die Legacy-Signatur wird über die leere Bytezeichenfolge berechnet. Siehe Webhook-Signaturen verifizieren.

Antwort

Geben Sie eine JSON-Antwort mit dem Tool-Ergebnis zurück:

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

Die Antwort wird formatiert und der KI bereitgestellt, damit sie das Gespräch fortsetzen kann. Nicht-JSON-Antworten werden als {"data": "<text>"} verpackt; Timeouts und Verbindungsfehler werden der KI als Fehler gemeldet, sodass der Agent sich entschuldigen und fortfahren kann, statt hängen zu bleiben.

Versand im Webhook-Modus

Tools ohne einen endpoint werden als signierte Anfrage vom Typ telephony.tool (Telefonanrufe) oder web.tool (Webanrufe) an die Legacy-Webhook-URL Ihrer Organisation gesendet. Anders als die Audit-Benachrichtigungen, die nach der Ausführung an Webhook-Endpunkte zugestellt werden, ist diese Anfrage die Ausführung — Ihre HTTP-Antwort ist das Tool-Ergebnis.

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

web.tool enthält origin_domain anstelle von from_number / to_number. Antworten Sie mit dem Tool-Ergebnis als JSON — gemäß demselben Antwortvertrag wie bei direkten Endpunktaufrufen. Die Anfrage wird wie jeder andere Webhook mit dem Webhook-Secret der Organisation und beiden Signatur-Headern signiert.


Signaturverifizierung

Direkte Tool-Aufrufe werden wie Webhooks signiert, wobei Ihr Webhook-Secret der Organisation verwendet wird:

  • X-ThunderPhone-Signature-V2 signiert den Zeitstempel, die Methode, den Pfad und die Abfragezeichenfolge wie gesendet sowie die exakten Body-Bytes. Lehnen Sie Anfragen ab, deren Zeitstempel mehr als 5 Minuten von Ihrer Uhrzeit abweicht.
  • X-ThunderPhone-Signature (Legacy) signiert nur die Body-Bytes, bei GET / DELETE die leere Bytezeichenfolge. Dieser Header wird weiterhin unverändert gesendet.

Die SDK-Hilfsfunktionen prüfen den V2-Header einschließlich des 5-Minuten-Zeitfensters:

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

Vollständige Anleitungen — die signierte Zeichenfolge, ein durchgerechnetes Beispiel, Code ohne SDK, der Fall GET / DELETE und der Hinweis bei fehlendem Secret — finden Sie unter Webhook-Signaturen verifizieren.


Beispiel: Vollständiger Buchungsablauf

Hier ist eine Reihe von Tools für ein vollständiges System zur Terminbuchung:

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

Best Practices

Klare Beschreibungen schreiben

Das Feld description hilft der KI zu verstehen, wann das Tool verwendet werden soll. Beschreiben Sie präzise, was es tut und wann sein Einsatz angemessen ist.

Fehler angemessen behandeln

Geben Sie Fehlermeldungen zurück, die die KI verstehen kann: {"error": "No slots available for that date"} statt allgemeiner 500-Fehler.

Antworten knapp halten

Geben Sie nur zurück, was die KI benötigt, um das Gespräch fortzusetzen. Große Nutzdaten verlangsamen die Antwortzeiten.

Pflichtfelder sinnvoll verwenden

Markieren Sie Felder nur dann als required, wenn dies wirklich erforderlich ist. Die KI fragt den Benutzer nach erforderlichen Informationen, bevor sie das Tool aufruft.


Verwandte Inhalte