Εργαλεία συναρτήσεων
Τα εργαλεία συναρτήσεων επιτρέπουν στους AI πράκτορές σας να καλούν εξωτερικά API κατά τη διάρκεια τηλεφωνικών κλήσεων. Χρησιμοποιήστε τα για να αναζητάτε δεδομένα πελατών, να ελέγχετε διαθεσιμότητα, να κλείνετε ραντεβού ή να εκτελείτε οποιαδήποτε ενέργεια υποστηρίζει το backend σας.
Πώς λειτουργεί
- Ορίζετε εργαλεία με ένα σχήμα (ποια ορίσματα δέχεται το εργαλείο)
- Παρέχετε μια διαμόρφωση
endpoint(πού το ThunderPhone καλεί το API σας) — ή την παραλείπετε για να λαμβάνετε κλήσεις εργαλείων στο webhook του οργανισμού σας - Κατά τη διάρκεια μιας κλήσης, ο AI πράκτορας αποφασίζει πότε να χρησιμοποιήσει ένα εργαλείο με βάση τη συνομιλία
- Το ThunderPhone καλεί το endpoint σας με τα ορίσματα του εργαλείου
- Η απόκριση του API σας επιστρέφεται στον AI πράκτορα για να συνεχίσει τη συνομιλία
Σχήμα εργαλείου
Κάθε εργαλείο ακολουθεί αυτή τη δομή:
{
"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"
}
}
}
Ορισμός συνάρτησης
| Πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
name | συμβολοσειρά | Ναι | Μοναδικό αναγνωριστικό για το εργαλείο |
description | συμβολοσειρά | Ναι | Εξηγεί στον AI πράκτορα πότε να χρησιμοποιεί αυτό το εργαλείο |
parameters | αντικείμενο | Ναι | JSON Schema για τα ορίσματα του εργαλείου |
Διαμόρφωση endpoint
| Πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
url | συμβολοσειρά | Ναι | URL endpoint του API σας |
method | συμβολοσειρά | Όχι | Μέθοδος HTTP (προεπιλογή: POST) |
headers | αντικείμενο | Όχι | Προσαρμοσμένες κεφαλίδες που θα συμπεριληφθούν |
Δύο διαδρομές κλήσης
Το αίτημα που λαμβάνει ο διακομιστής σας εξαρτάται από το αν το εργαλείο έχει
endpoint:
Εργαλείο με endpoint | Εργαλείο χωρίς endpoint | |
|---|---|---|
| Πού αποστέλλεται το αίτημα | Απευθείας στο endpoint.url | Στο παλαιού τύπου URL webhook του οργανισμού σας |
| Σώμα | Μόνο τα ορίσματα του εργαλείου | Περιτύλιγμα telephony.tool / web.tool |
| Κεφαλίδες | Τα endpoint.headers σας + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature |
| Κλειδί υπογραφής | Μυστικό webhook οργανισμού | Μυστικό webhook οργανισμού |
Και οι δύο διαδρομές μπλοκάρουν τη ροή — ο AI πράκτορας περιμένει το
αποτέλεσμα στη μέση μιας πρότασης — με χρονικό όριο 20 δευτ.. Διατηρείτε
τους χειριστές γρήγορους. Μπορείτε να χρησιμοποιείτε συνδυασμό:
σε μια κλήση όπου ο οργανισμός έχει URL webhook, τα εργαλεία με endpoint
καλούνται απευθείας και τα υπόλοιπα επιστρέφουν στο webhook.
Άμεσες κλήσεις τελικού σημείου
Όταν ο AI πράκτορας καλεί ένα εργαλείο που διαθέτει endpoint, το ThunderPhone στέλνει
ένα αίτημα στο URL σας:
Κεφαλίδες αιτήματος
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
Οι προσαρμοσμένες κεφαλίδες από το endpoint.headers σας περιλαμβάνονται πάντα
αυτούσιες, μαζί με δύο κεφαλίδες στο namespace του ThunderPhone:
X-ThunderPhone-Signature— HMAC-SHA256 των ακριβών byte του σώματος του αιτήματος, με κλειδί το μυστικό webhook του οργανισμού σαςX-ThunderPhone-Call-ID— Το αναγνωριστικό της τρέχουσας κλήσης
Το Content-Type: application/json ορίζεται εκτός αν το endpoint.headers σας
το παρακάμπτει — υπερισχύει ένα προσαρμοσμένο Content-Type.
Σώμα αιτήματος
Για POST / PUT / PATCH, το σώμα περιέχει μόνο τα ορίσματα του εργαλείου
(χωρίς περιτύλιγμα), σειριοποιημένα κανονικά (ταξινομημένα κλειδιά, συμπαγείς
διαχωριστές):
{"date":"2025-01-02","service":"consultation"}
Για GET / DELETE, τα ορίσματα στέλνονται ως παράμετροι ερωτήματος
και το σώμα είναι κενό — η υπογραφή υπολογίζεται τότε πάνω στην κενή
συμβολοσειρά byte. Δείτε την ενότητα
Επαλήθευση υπογραφών webhook.
Απόκριση
Επιστρέψτε μια απόκριση JSON με το αποτέλεσμα του εργαλείου:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}
Η απόκριση μορφοποιείται και παρέχεται στον AI πράκτορα για να συνεχίσει τη
συνομιλία. Οι αποκρίσεις που δεν είναι JSON περιτυλίγονται ως {"data": "<text>"};
οι χρονικές υπερβάσεις και οι αποτυχίες σύνδεσης αναφέρονται στον AI πράκτορα ως
σφάλματα, ώστε ο πράκτορας να μπορεί να ζητήσει συγγνώμη και να συνεχίσει αντί να
παραμένει σε αναμονή.
Δρομολόγηση σε λειτουργία webhook
Τα εργαλεία χωρίς endpoint δρομολογούνται στο URL webhook παλαιού τύπου του
οργανισμού σας ως υπογεγραμμένο αίτημα telephony.tool (τηλεφωνικές κλήσεις) ή
web.tool (κλήσεις web). Σε αντίθεση με τις ειδοποιήσεις
ελέγχου που παραδίδονται στα τελικά σημεία webhook μετά την
εκτέλεση, αυτό το αίτημα είναι η εκτέλεση — η απόκρισή σας HTTP είναι το
αποτέλεσμα του εργαλείου.
{
"type": "telephony.tool",
"data": {
"call_id": 987654321,
"tool_name": "search_appointments",
"arguments": { "date": "2026-04-21" },
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}
Το web.tool μεταφέρει origin_domain αντί για from_number /
to_number. Απαντήστε με το αποτέλεσμα του εργαλείου ως JSON — ισχύει το ίδιο
συμβόλαιο απόκρισης όπως στις άμεσες κλήσεις τελικού σημείου. Το αίτημα
υπογράφεται με το μυστικό webhook του οργανισμού πάνω στο ακατέργαστο σώμα,
όπως κάθε άλλο webhook.
Επαλήθευση υπογραφής
Οι άμεσες κλήσεις εργαλείων υπογράφονται με τον ίδιο τρόπο όπως τα webhook:
- HMAC-SHA256 πάνω στα ακριβή byte του σώματος του αιτήματος (το κανονικοποιημένο JSON — ταξινομημένα κλειδιά, χωρίς επιπλέον κενά)
- Με κλειδί το μυστικό webhook του οργανισμού σας
- Τα εργαλεία
GET/DELETEυπογράφουν την κενή ακολουθία byte
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}
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 });
});
Πλήρεις οδηγίες — συμπεριλαμβανομένης της περίπτωσης κενού σώματος και της επισήμανσης για απουσία μυστικού — θα βρείτε στο Επαλήθευση υπογραφών webhook.
Παράδειγμα: Πλήρης ροή κράτησης
Ακολουθεί ένα σύνολο εργαλείων για ένα ολοκληρωμένο σύστημα κράτησης ραντεβού:
{
"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" }
}
}
]
}
Βέλτιστες πρακτικές
Γράψτε σαφείς περιγραφές
Το πεδίο description βοηθά την AI να κατανοήσει πότε να χρησιμοποιεί το εργαλείο. Περιγράψτε συγκεκριμένα τι κάνει και πότε είναι κατάλληλο.
Χειριστείτε τα σφάλματα ομαλά
Επιστρέφετε μηνύματα σφάλματος που μπορεί να κατανοήσει η AI: {"error": "No slots available for that date"} αντί για γενικά σφάλματα 500.
Διατηρήστε τις αποκρίσεις σύντομες
Επιστρέφετε μόνο ό,τι χρειάζεται η AI για να συνεχίσει τη συνομιλία. Τα μεγάλα payload επιβραδύνουν τους χρόνους απόκρισης.
Χρησιμοποιήστε τα υποχρεωτικά πεδία με σύνεση
Επισημαίνετε πεδία ως required μόνο όταν είναι πραγματικά απαραίτητο. Η AI θα ζητήσει από τον χρήστη τις απαιτούμενες πληροφορίες πριν καλέσει το εργαλείο.
Σχετικά
Εργαλεία διαχειριζόμενα από την πλατφόρμα για HubSpot, Salesforce, Slack, Google Calendar, Google Sheets και Cal.com — δεν απαιτείται endpoint.
Συνδέστε έναν διακομιστή MCP και επιτρέψτε στον πράκτορα να καλεί τα εργαλεία του.
Επαναχρησιμοποιήσιμες ενσωματώσεις REST που μπορείτε να συνδέσετε με πράκτορες.
Ένα βοήθημα επαλήθευσης για webhook και κλήσεις εργαλείων.