Open in
फ़ंक्शन टूल्स
अपने AI एजेंट्स को ऐसे फ़ंक्शन टूल्स दें जो बातचीत के दौरान एक्सटर्नल APIs को कॉल करें — कस्टमर डेटा प्राप्त करें, अपॉइंटमेंट बुक करें, रिकॉर्ड्स अपडेट करें — टाइप्ड पैरामीटर्स के साथ।
फ़ंक्शन टूल्स आपके AI फ़ोन एजेंट्स को फ़ोन कॉल के दौरान बाहरी APIs इनवोक करने देते हैं। इनका उपयोग कस्टमर डेटा देखने, उपलब्धता जांचने, अपॉइंटमेंट बुक करने या आपके बैकएंड द्वारा समर्थित कोई भी कार्रवाई करने के लिए करें।
यह कैसे काम करता है
- आप स्कीमा के साथ टूल्स परिभाषित करते हैं (टूल कौन से आर्ग्युमेंट स्वीकार करता है)
- आप
endpointकॉन्फ़िगरेशन प्रदान करते हैं (जहां ThunderPhone आपके API को कॉल करता है) — या अपने संगठन वेबहुक पर टूल कॉल प्राप्त करने के लिए इसे छोड़ दें - कॉल के दौरान, AI बातचीत के आधार पर तय करता है कि टूल का उपयोग कब करना है
- ThunderPhone टूल आर्ग्युमेंट्स के साथ आपके एंडपॉइंट को कॉल करता है
- बातचीत जारी रखने के लिए आपके API का रिस्पॉन्स AI को वापस दिया जाता है
| क्षमता | यह कहां चलता है | सेटअप |
|---|---|---|
| बिल्ट-इन टूल्स | ThunderPhone | प्रॉम्प्ट निर्देश; कुछ टूल्स के लिए एजेंट सेटिंग भी आवश्यक होती है |
| ऐप कनेक्शन | ThunderPhone और कनेक्टेड प्रोवाइडर | अकाउंट कनेक्ट करें और अप्रूव्ड एक्शन अटैच करें |
| API कनेक्शन और फ़ंक्शन टूल्स | आपका HTTP API | एंडपॉइंट और स्कीमा परिभाषित करें, या वेबहुक के माध्यम से फ़ंक्शन कॉल प्राप्त करें |
| MCP सर्वर्स | रिमोट MCP सर्वर | सर्वर जोड़ें, उसके टूल्स खोजें और उसे एजेंट से अटैच करें |
टूल स्कीमा
हर टूल इस संरचना का पालन करता है:
{
"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
}टूल कॉन्फ़िगरेशन
| फ़ील्ड | टाइप | आवश्यक | विवरण |
|---|---|---|---|
timeout | नंबर | नहीं | सेकंड में अधिकतम एक्जीक्यूशन समय (डिफ़ॉल्ट: 20, अधिकतम: 180) |
फ़ंक्शन डेफ़िनिशन
| फ़ील्ड | टाइप | आवश्यक | विवरण |
|---|---|---|---|
name | स्ट्रिंग | हां | टूल के लिए यूनिक आइडेंटिफ़ायर |
description | स्ट्रिंग | हां | AI को बताता है कि इस टूल का उपयोग कब करना है |
parameters | ऑब्जेक्ट | हां | टूल आर्ग्युमेंट्स के लिए JSON स्कीमा |
एंडपॉइंट कॉन्फ़िगरेशन
| फ़ील्ड | टाइप | आवश्यक | विवरण |
|---|---|---|---|
url | स्ट्रिंग | हां | आपके API का एंडपॉइंट URL |
method | स्ट्रिंग | नहीं | HTTP मेथड (डिफ़ॉल्ट: POST) |
headers | ऑब्जेक्ट | नहीं | शामिल करने के लिए कस्टम हेडर्स |
दो इनवोकेशन पाथ
आपके सर्वर को कौन सा रिक्वेस्ट मिलता है, यह इस पर निर्भर करता है कि टूल में
endpoint है या नहीं:
endpoint वाला टूल | endpoint के बिना टूल | |
|---|---|---|
| रिक्वेस्ट कहाँ जाती है | सीधे endpoint.url पर | आपके संगठन के लीगेसी वेबहुक URL पर |
| बॉडी | चुना गया रिक्वेस्ट फ़ॉर्मैट (डिफ़ॉल्ट रूप से केवल आर्ग्युमेंट्स) | telephony.tool / web.tool एनवेलप |
| हेडर्स | आपके endpoint.headers + X-ThunderPhone-Call-ID + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature | Content-Type + X-ThunderPhone-Signature-V2 + X-ThunderPhone-Signature |
| साइनिंग की | संगठन का वेबहुक सीक्रेट | संगठन का वेबहुक सीक्रेट |
दोनों पाथ ब्लॉकिंग हैं — AI रिज़ल्ट के लिए वाक्य के बीच में प्रतीक्षा कर रहा है।
डिफ़ॉल्ट टाइमआउट 20 s है; अधिक लंबा एक्जीक्यूशन समय, प्लेटफ़ॉर्म की 180 s
अधिकतम सीमा तक, अनुमति देने के लिए टूल का टॉप-लेवल timeout सेट करें। हैंडलर्स को तेज़ रखें। मिश्रण करना भी ठीक है:
ऐसी कॉल पर जिसके संगठन में वेबहुक URL है, endpoint वाले टूल्स को
सीधे कॉल किया जाता है और बाकी वेबहुक पर फ़ॉलबैक हो जाते हैं।
डायरेक्ट एंडपॉइंट कॉल
जब AI किसी ऐसे टूल को इनवोक करता है जिसमें endpoint होता है, तो ThunderPhone
आपके URL पर एक रिक्वेस्ट भेजता है:
रिक्वेस्ट हेडर्स
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आपके endpoint.headers के कस्टम हेडर हमेशा ज्यों के त्यों शामिल किए जाते हैं,
साथ ही ये ThunderPhone-नेमस्पेस्ड हेडर भी शामिल होते हैं:
X-ThunderPhone-Signature-V2— मेथड, पाथ, क्वेरी और बॉडी पर टाइमस्टैम्प वाला HMAC-SHA256, जो आपके संगठन वेबहुक सीक्रेट से की किया गया है। इसे वेरिफ़ाई करें और 5 मिनट से पुराने रिक्वेस्ट अस्वीकार करें; देखें वेबहुक सिग्नेचर वेरिफ़ाई करेंX-ThunderPhone-Signature— सटीक रिक्वेस्ट-बॉडी बाइट्स का लेगेसी HMAC-SHA256, उसी की के साथ, मौजूदा वेरिफ़ायर के लिए अभी भी भेजा जाता हैX-ThunderPhone-Call-ID— वर्तमान कॉल ID
Content-Type: application/json सेट किया जाता है, जब तक कि आपके endpoint.headers
इसे ओवरराइड न करें — कस्टम Content-Type को प्राथमिकता मिलती है।
रिक्वेस्ट फ़ॉर्मैट
हर API कनेक्शन में एक request_format सेटिंग होती है। जब किसी इंपोर्ट किए गए टूल को उस प्लेटफ़ॉर्म के लिए बने एंडपॉइंट को कॉल करना जारी रखना हो, तो vapi या
retell चुनें। नए और मौजूदा कनेक्शन डिफ़ॉल्ट रूप से standard पर सेट होते हैं।
POST / PUT / PATCH के लिए, ThunderPhone चुने गए
एनवेलप को कैनॉनिकली सीरियलाइज़ करता है (सॉर्ट की गई कीज़, कॉम्पैक्ट सेपरेटर)। दोनों सिग्नेचर इन सटीक बाइट्स को कवर करते हैं।
Standard
standard बिना किसी रैपर के केवल टूल आर्ग्युमेंट्स भेजता है। यह डिफ़ॉल्ट है और ThunderPhone के मूल रिक्वेस्ट बॉडी को बाइट-दर-बाइट सुरक्षित रखता है:
{"date":"2025-01-02","service":"consultation"}Vapi
vapi, Vapi का कस्टम टूल्स के लिए tool-calls सर्वर मैसेज
Vapi के डॉक्यूमेंटेशन के अनुसार भेजता है। call.id, ThunderPhone कॉल ID है। टूल-कॉल id इनवोकेशन के लिए यूनिक होता है और एंडपॉइंट के रिज़ल्ट से मैच करने के लिए दोबारा उपयोग किया जाता है। कॉल toolCallList और
toolWithToolCallList, दोनों में दिखाई देती है, जहाँ function.arguments एक JSON ऑब्जेक्ट होता है:
{
"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" }
}
}
}
]
}
}assistant, artifact और पूरा call ऑब्जेक्ट जैसे केवल-Vapi फ़ील्ड नहीं भेजे जाते।
मैचिंग टूल-कॉल ID के साथ Vapi का रिस्पॉन्स एनवेलप लौटाएँ:
{
"results": [
{
"toolCallId": "call_00112233445566778899aabbccddeeff",
"result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
}
]
}ThunderPhone AI को अनरैप की गई result स्ट्रिंग देता है। यह उन एंडपॉइंट्स के साथ कंपैटिबिलिटी के लिए JSON वैल्यू भी स्वीकार करता है जो पहले से एक वैल्यू लौटाते हैं। result की जगह दिया गया error, AI को टूल एरर के रूप में लौटाया जाता है। यदि एंडपॉइंट गलत फ़ॉर्मैट वाला या मिसमैचिंग Vapi एनवेलप लौटाता है, तो ThunderPhone एक वॉर्निंग लॉग करता है और कॉल को फेल करने के बजाय अपने स्टैंडर्ड रिस्पॉन्स पार्सिंग पर फ़ॉलबैक करता है।
Retell
retell, Retell कस्टम फंक्शन के लिए डॉक्यूमेंट की गई रिक्वेस्ट भेजता है:
{
"name": "search_appointments",
"call": { "call_id": "987654321" },
"args": { "date": "2025-01-02", "service": "consultation" }
}call ऑब्जेक्ट में केवल call_id शामिल होता है। ThunderPhone ऐसे Retell-विशिष्ट फ़ील्ड शामिल नहीं करता जिन्हें वह डिस्पैच के समय वास्तविक रूप से उपलब्ध नहीं करा सकता, जैसे
agent_id, transcript, transcript_object, metadata, या डायनामिक वेरिएबल्स। Retell कोई भी रिस्पॉन्स बॉडी स्वीकार करता है; ThunderPhone इसे स्टैंडर्ड रिस्पॉन्स हैंडलिंग का उपयोग करके पास थ्रू करता है।
GET / DELETE के लिए, आर्ग्युमेंट्स क्वेरी पैरामीटर के रूप में भेजे जाते हैं
और request_format की परवाह किए बिना बॉडी खाली रहती है। V2 सिग्नेचर भेजी गई क्वेरी स्ट्रिंग को कवर करता है; लेगसी सिग्नेचर खाली बाइट स्ट्रिंग पर कंप्यूट किया जाता है। देखें
वेबहुक सिग्नेचर वेरिफ़ाई करें।
रिस्पॉन्स
टूल रिजल्ट के साथ एक JSON रिस्पॉन्स लौटाएं:
{
"available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
"timezone": "America/Los_Angeles"
}रिस्पॉन्स को फॉर्मैट करके बातचीत जारी रखने के लिए AI को दिया जाता है।
नॉन-JSON रिस्पॉन्स को {"data": "<text>"} के रूप में रैप किया जाता है;
टाइमआउट और कनेक्शन विफलताएं AI को एरर के रूप में रिपोर्ट की जाती हैं, ताकि
एजेंट रुकने के बजाय माफ़ी मांगकर आगे बढ़ सके।
वेबहुक-मोड डिस्पैच
endpoint के बिना टूल्स को आपके संगठन के लेगसी वेबहुक URL पर साइन किए गए
telephony.tool (फोन कॉल) या web.tool (वेब कॉल) रिक्वेस्ट के रूप में डिस्पैच किया
जाता है। निष्पादन के बाद वेबहुक एंडपॉइंट्स पर भेजी जाने वाली
ऑडिट नोटिफिकेशन्स के विपरीत, यह रिक्वेस्ट ही
निष्पादन है — आपका 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, from_number / to_number के बजाय origin_domain भेजता है। टूल के परिणाम के साथ JSON में उत्तर दें — डायरेक्ट एंडपॉइंट कॉल्स जैसा ही रिस्पॉन्स कॉन्ट्रैक्ट। हर अन्य वेबहुक की तरह, अनुरोध पर दोनों सिग्नेचर हेडर्स के साथ संगठन के वेबहुक सीक्रेट से साइन किया जाता है।
सिग्नेचर वेरिफिकेशन
डायरेक्ट टूल कॉल पर वेबहुक की तरह ही सिग्नेचर किए जाते हैं, जो आपके संगठन के वेबहुक सीक्रेट पर आधारित होते हैं:
X-ThunderPhone-Signature-V2भेजे गए टाइमस्टैम्प, मेथड, पाथ और क्वेरी के साथ-साथ सटीक बॉडी बाइट्स पर सिग्नेचर करता है। जिन रिक्वेस्ट का टाइमस्टैम्प आपकी घड़ी से 5 मिनट से अधिक अलग हो, उन्हें अस्वीकार करें।X-ThunderPhone-Signature(लीगेसी) केवल बॉडी बाइट्स पर सिग्नेचर करता है,GET/DELETEके लिए खाली बाइट स्ट्रिंग पर। इसे अब भी बिना बदलाव के भेजा जाता है।
SDK हेल्पर 5 मिनट की विंडो सहित V2 हेडर की जांच करते हैं:
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}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 });
});पूरी रेसिपी — साइन की गई स्ट्रिंग, एक वर्क्ड उदाहरण, SDK के बिना कोड,
GET / DELETE केस और बिना सीक्रेट वाली सावधानी — वेबहुक सिग्नेचर सत्यापित करें में उपलब्ध हैं।
उदाहरण: पूरा बुकिंग फ्लो
यह एक पूर्ण अपॉइंटमेंट बुकिंग सिस्टम के लिए टूल्स का सेट है:
{
"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 समझ सके: सामान्य 500 त्रुटियों के बजाय {"error": "No slots available for that date"}।
रिस्पॉन्स संक्षिप्त रखें
बातचीत जारी रखने के लिए AI को केवल वही लौटाएँ जिसकी उसे आवश्यकता है। बड़े पेलोड रिस्पॉन्स समय को धीमा करते हैं।
आवश्यक फ़ील्ड का समझदारी से उपयोग करें
फ़ील्ड को required केवल तभी चिह्नित करें जब वे वास्तव में आवश्यक हों। टूल कॉल करने से पहले AI उपयोगकर्ता से आवश्यक जानकारी माँगेगा।
संबंधित
एंडपॉइंट परिभाषित किए बिना प्लेटफ़ॉर्म-प्रबंधित कॉल एक्शन प्रॉम्प्ट करें।
HubSpot, Salesforce, Slack, Google Calendar, Google Sheets और Cal.com के लिए प्लेटफ़ॉर्म-प्रबंधित टूल — किसी एंडपॉइंट की आवश्यकता नहीं।
MCP सर्वर अटैच करें और एजेंट को उसके टूल कॉल करने दें।
पुन: उपयोग योग्य REST इंटीग्रेशन जिन्हें आप एजेंटों से अटैच कर सकते हैं।
वेबहुक और टूल कॉल के लिए एक वेरिफ़िकेशन हेल्पर।