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

Developer cookbook

टूल इंटीग्रेशन (API) बनाएं

अपने एजेंट को बातचीत के दौरान आपके APIs कॉल करने दें — डेटाबेस खोजें, टिकट बनाएं, ऑर्डर देखें।

एक टूल इंटीग्रेशन एक पुन: उपयोग योग्य HTTP एंडपॉइंट है जिसे एजेंट कॉल के दौरान इनवोक कर सकता है। आप ThunderPhone को टूल का JSON-schema विवरण और एक एंडपॉइंट URL देते हैं; एजेंट बातचीत के आधार पर तय करता है कि इसे कब कॉल करना है, और ThunderPhone अपने सर्वरों से आउटबाउंड HTTP रिक्वेस्ट करता है और एजेंट को रिस्पॉन्स लौटाता है।

यह गाइड शुरू से अंत तक मौसम-लुकअप टूल बनाने की प्रक्रिया बताती है।

टूल की संरचना

दो भाग:

  1. स्कीमा — एक OpenAI-स्टाइल फ़ंक्शन डेफ़िनिशन ({type: "function", function: {name, description, parameters}}) जो LLM को बताता है कि टूल क्या करता है और कौन से आर्ग्युमेंट लेता है।
  2. एंडपॉइंट — वह URL जिसे ThunderPhone के सर्वर तब कॉल करते हैं जब LLM टूल का उपयोग करने का निर्णय लेता है। रिक्वेस्ट JSON POST होती है, जिसमें LLM के चुने हुए आर्ग्युमेंट बॉडी के रूप में होते हैं।

1. एक एडिटर चुनें

डैशबोर्ड

कनेक्शन → APIs खोलें, API कनेक्शन बनाएं या एडिट करें, पैरामीटर एडिटर को JSON पर स्विच करें, और वहाँ फ़ॉर्मैट जोड़ें।

इंटीग्रेशंस API

POST /v1/integrations से स्पेक बनाएं, या इसे PATCH /v1/integrations/{id} से अपडेट करें।

दोनों रास्ते एक सेव किया हुआ इंटीग्रेशन बनाते हैं। सेव करने के बाद उस इंटीग्रेशन को एजेंट से अटैच करें। Agents API में कोई लिखने योग्य इनलाइन tools फ़ील्ड नहीं है। यह गाइड इंटीग्रेशंस API पाथ का उपयोग करती है।

2. इंटीग्रेशन बनाएँ

curl -X POST https://api.thunderphone.com/v1/integrations \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Weather API",
    "spec": {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Return the current weather for a zip code.",
        "parameters": {
          "type": "object",
          "properties": {
            "zip": { "type": "string", "description": "5-digit US ZIP code" }
          },
          "required": ["zip"]
        }
      }
    },
    "endpoint_url":    "https://api.example.com/weather",
    "endpoint_method": "GET",
    "headers": [
      { "key": "X-Api-Key", "value": "your-provider-key" }
    ]
  }'

लौटाया गया id (एक UUID) सहेजें। हेडर वैल्यू केवल-लिखने योग्य हैं: रिस्पॉन्स में केवल हेडर नाम सूचीबद्ध होते हैं, और बाद का PATCH संग्रहीत वैल्यू बनाए रखने के लिए बिना value के हेडर भेज सकता है।

एड्रेस पैरामीटर पर format: "email" घोषित करें

ईमेल एड्रेस प्राप्त करने वाले पैरामीटर को अपने स्कीमा में यह बताना चाहिए:

"email": { "type": "string", "format": "email", "description": "The caller's email address" }

format केवल एक हिंट से अधिक है। रिज़ॉल्व किए गए ईमेल स्कीमा के लिए, आपके एंडपॉइंट को कॉल करने से पहले ThunderPhone वैल्यू को ट्रिम करता है, डोमेन को लोअरकेस करता है, स्वतंत्र अंग्रेज़ी शब्दों at, dot, underscore, dash, और hyphen को उनके कैरेक्टर में बदलता है, और @, ., _, तथा - के ठीक आसपास का व्हाइटस्पेस हटा देता है। इन शब्दों का अर्थ एक ही रहता है, चाहे ट्रांसक्रिप्ट में पहले से लिटरल @ मौजूद हो या नहीं: "john dot smith at gmail dot com" बदलकर john.smith@gmail.com हो जाता है।

किसी अन्य आंतरिक व्हाइटस्पेस को चुपचाप जोड़ने के बजाय अस्वीकार कर दिया जाता है। बोले गए सेपरेटर शब्द केवल अंग्रेज़ी के लिए हैं; गैर-अंग्रेज़ी या अपरिचित स्पेस वाले रूप बंद स्थिति में विफल होते हैं। वैध अंतरराष्ट्रीयकृत डोमेन और SMTPUTF8 लोकल पार्ट स्वीकार किए जाते हैं। पार्सर नॉर्मलाइज़ेशन के बाद Punycode इनपुट Punycode ही रहता है और Unicode डोमेन इनपुट Unicode ही रहता है, इसलिए आपकी API को कॉलर द्वारा दिया गया पारंपरिक प्रतिनिधित्व मिलता है। यदि अंतिम वैल्यू अमान्य है, तो टूल को कॉल नहीं किया जाता। एजेंट को invalid_email_argument मिलता है, जो उसे कॉलर के साथ स्पेलिंग की पुष्टि करने और लिटरल एड्रेस दोबारा भेजने के लिए कहता है।

छोड़ा गया वैकल्पिक ईमेल अपरिवर्तित रहता है। null, एक खाली स्ट्रिंग, या केवल व्हाइटस्पेस वाली स्ट्रिंग भी तब अपरिवर्तित रहती है जब प्रॉपर्टी वैकल्पिक या nullable हो; आवश्यक, non-nullable ईमेल के लिए इन्हीं वैल्यू को अस्वीकार कर दिया जाता है।

#/$defs/email और #/definitions/email जैसे लोकल स्कीमा रेफरेंस, साथ ही anyOf, oneOf, और allOf, को साइकिल और डेप्थ सीमाओं के साथ निरीक्षित किया जाता है। गैर-लोकल या अनरिज़ॉल्वेबल $ref एक ज्ञात एनफोर्समेंट सीमा है और उसे बिना बदलाव के पास किया जाता है, ठीक उसी तरह जैसे उस कॉल को जिसकी टूल स्नैपशॉट में कोई उपयोगी स्कीमा नहीं है। जब आपको इस गेट को लागू करना हो, तो ईमेल स्कीमा लोकल रखें।

लागू किए गए ईमेल फॉर्मेट के बिना पैरामीटर को मॉडल द्वारा उत्पादित रूप में ही पास किया जाता है।

समर्थित फॉर्मेट date-time, time, date, duration, email, hostname, ipv4, ipv6, और uuid हैं; आज केवल email को नॉर्मलाइज़ और एनफोर्स किया जाता है।

3. एंडपॉइंट का सैंडबॉक्स टेस्ट करें

इंटीग्रेशन को किसी एजेंट से लिंक करने से पहले, कनेक्टिविटी की पुष्टि करने के लिए ThunderPhone के सर्वर से एक साइन किया हुआ रिक्वेस्ट भेजें:

curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url":    "https://api.example.com/weather?zip=94110",
    "method": "GET",
    "headers": { "X-Api-Key": "your-provider-key" }
  }'
Response
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}

यह टेस्ट ThunderPhone के SSRF गार्ड्स को भी मजबूत करता है — localhost या निजी IP रेंज के रिक्वेस्ट 400 code=url_not_allowed लौटाते हैं।

4. इंटीग्रेशन को एजेंट से लिंक करें

एजेंट बनाते या अपडेट करते समय integration_ids के जरिए अटैच करें:

curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_ids": ["f9b5a1a4-..."]
  }'

आप एक एजेंट से कई इंटीग्रेशन लिंक कर सकते हैं। एजेंट का प्रॉम्प्ट उन्हें नाम से रेफर कर सकता है — "कॉलर कंडीशंस के बारे में पूछे तो get_weather का उपयोग करें" — या वह स्कीमा डिस्क्रिप्शन से उन्हें इम्प्लिसिट रूप से डिस्कवर कर सकता है।

5. एंडपॉइंट इम्प्लीमेंट करें

जब एजेंट टूल इनवोक करता है, ThunderPhone आपके endpoint_url पर एक साइन किया हुआ POST भेजता है:

POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<HMAC-SHA256 hex>
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json

{"zip": "94110"}

आपका सर्वर JSON के साथ रिस्पॉन्ड करता है, जो वापस LLM को दिया जाता है:

{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}

LLM उस रिस्पॉन्स को इनजेस्ट करता है और कॉलर को एक मानवीय सारांश बोलता है।

6. लूप टेस्ट करें

एजेंट के खिलाफ एक माइक सेशन चलाएँ और वह प्रश्न पूछें जिसे आपका टूल हैंडल करता है ("94110 में मौसम कैसा है?")। कॉल का ट्रांसक्रिप्ट पूरा राउंड ट्रिप दिखाता है:

{
  "call_id": 987654321,
  "transcripts": [
    { "role": "user",
      "content": "What's the weather in 94110?" },
    { "role": "tool_call",
      "content": "{\"tool_call\": \"get_weather\", \"arguments\": {\"zip\": \"94110\"}}" },
    { "role": "tool_response",
      "content": "{\"tool_name\": \"get_weather\", \"response\": {\"temperature_f\": 64, \"condition\": \"Partly cloudy\"}}" },
    { "role": "agent",
      "content": "It's 64 degrees and partly cloudy." }
  ]
}

आप इसे GET /v1/calls/{call_id}/transcript के जरिए प्राप्त कर सकते हैं; रॉ इवेंट स्ट्रीम (हर एंट्री की टाइमिंग और ऑडियो ऑफ़सेट के साथ) यहाँ है GET /v1/calls/{call_id}/history।

कॉल-लिस्टिंग और एनालिटिक्स सतहों में, ThunderPhone अब टेस्ट कॉल को वास्तविक ट्रैफ़िक से अलग रिपोर्ट करता है। Browser Talk टेस्ट और सिमुलेशन किसी वास्तविक फ़ोन नंबर का दोबारा उपयोग कर सकते हैं और इनबाउंड जैसे दिख सकते हैं, लेकिन वे प्रोडक्शन कॉल कुल, ग्रेड या इश्यू मेट्रिक्स में शामिल नहीं होते हैं।

सामान्य समस्याएँ

एजेंट कभी टूल कॉल नहीं करता

LLM टूल के डिस्क्रिप्शन के आधार पर निर्णय लेता है। अगर कॉलर का प्रश्न डिस्क्रिप्शन से मेल नहीं खाता, तो मॉडल टूल इनवोक नहीं करेगा। डिस्क्रिप्शन को अधिक सटीक बनाएँ (सामान्य सिनोनिम और फ्रेज़िंग जोड़ें) या एजेंट प्रॉम्प्ट में इसका स्पष्ट उल्लेख करें ("जब कॉलर मौसम के बारे में पूछे, तो get_weather का उपयोग करें।")।

टूल बहुत ज़्यादा डेटा लौटाता है

6 kB से बड़े रिस्पॉन्स ट्रांसक्रिप्ट प्रीव्यू में ट्रंकेट हो जाते हैं। केवल वे फ़ील्ड लौटाएँ जिनकी LLM को आवश्यकता है — अपनी पूरी रो नहीं।

टाइमआउट

टूल एंडपॉइंट में 10 सेकंड का डिफ़ॉल्ट टाइमआउट होता है। अगर आपको अधिक समय चाहिए, तो इसे एसिंक्रोनस रूप से हैंडल करें: {"status": "pending", "request_id": "..."} लौटाएँ और परिणाम को अलग टूल कॉल के जरिए दिखाएँ।

वर्ज़निंग

हर इंटीग्रेशन PATCH एक नया रिविज़न बनाता है। किसने क्या बदला, यह देखने के लिए GET /v1/integrations/{id}/versions जाँचें। अगर आप टूल का स्कीमा तोड़ देते हैं, तो पुराने स्नैपशॉट को वापस PATCH करके मैन्युअल रूप से रोल बैक कर सकते हैं।


अगले चरण