ThunderPhone 2.0 अब लाइव है।सेल्फ़-सर्व, 2¢/मिनट से।घोषणा पढ़ें

Function Tools

फ़ंक्शन टूल्स

अपने AI एजेंट्स को ऐसे फ़ंक्शन टूल्स दें जो बातचीत के दौरान एक्सटर्नल APIs को कॉल करें — कस्टमर डेटा प्राप्त करें, अपॉइंटमेंट बुक करें, रिकॉर्ड्स अपडेट करें — टाइप्ड पैरामीटर्स के साथ।

फ़ंक्शन टूल्स आपके AI फ़ोन एजेंट्स को फ़ोन कॉल के दौरान बाहरी APIs इनवोक करने देते हैं। इनका उपयोग कस्टमर डेटा देखने, उपलब्धता जांचने, अपॉइंटमेंट बुक करने या आपके बैकएंड द्वारा समर्थित कोई भी कार्रवाई करने के लिए करें।

यह कैसे काम करता है

  1. आप स्कीमा के साथ टूल्स परिभाषित करते हैं (टूल कौन से आर्ग्युमेंट स्वीकार करता है)
  2. आप endpoint कॉन्फ़िगरेशन प्रदान करते हैं (जहां ThunderPhone आपके API को कॉल करता है) — या अपने संगठन वेबहुक पर टूल कॉल प्राप्त करने के लिए इसे छोड़ दें
  3. कॉल के दौरान, AI बातचीत के आधार पर तय करता है कि टूल का उपयोग कब करना है
  4. ThunderPhone टूल आर्ग्युमेंट्स के साथ आपके एंडपॉइंट को कॉल करता है
  5. बातचीत जारी रखने के लिए आपके 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-SignatureContent-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 हेडर की जांच करते हैं:

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

पूरी रेसिपी — साइन की गई स्ट्रिंग, एक वर्क्ड उदाहरण, 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 उपयोगकर्ता से आवश्यक जानकारी माँगेगा।


संबंधित