ThunderPhone 2.0 متاح الآن.خدمة ذاتية، ابتداءً من 2 سنت/دقيقة.اقرأ الإعلان

Function Tools

أدوات الدوال

زوّد وكلاء الذكاء الاصطناعي لديك بأدوات دوال تستدعي واجهات برمجة التطبيقات الخارجية أثناء المحادثة — لجلب بيانات العملاء، وحجز المواعيد، وتحديث السجلات — باستخدام معلمات محددة النوع.

تتيح أدوات الدوال لوكلاء الهاتف بالذكاء الاصطناعي استدعاء واجهات API خارجية أثناء المكالمات الهاتفية. استخدمها للبحث عن بيانات العملاء، والتحقق من التوفر، وحجز المواعيد، أو تنفيذ أي إجراء تدعمه الواجهة الخلفية لديك.

آلية العمل

  1. عرّف الأدوات باستخدام مخطط يحدد الوسيطات التي تقبلها الأداة
  2. قدّم إعداد endpoint لتحديد المكان الذي يستدعي فيه ThunderPhone واجهة API لديك، أو اتركه غير محدد لتلقي استدعاءات الأدوات على خطاف الويب الخاص بمؤسستك
  3. أثناء المكالمة، يقرر الذكاء الاصطناعي متى يستخدم أداة بناءً على المحادثة
  4. يستدعي ThunderPhone نقطة النهاية لديك باستخدام وسيطات الأداة
  5. تُعاد استجابة واجهة API لديك إلى الذكاء الاصطناعي لمواصلة المحادثة

مخطط الأداة

تتبع كل أداة هذه البنية:

{
  "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سلسلة نصيةنعميوضح للذكاء الاصطناعي متى يستخدم هذه الأداة
parametersكائننعممخطط JSON لوسيطات الأداة

إعداد نقطة النهاية

الحقلالنوعمطلوبالوصف
urlسلسلة نصيةنعمعنوان URL لنقطة نهاية API لديك
methodسلسلة نصيةلاطريقة HTTP ‏(الافتراضية: POST)
headersكائنلارؤوس مخصصة لتضمينها

مسارا الاستدعاء

يعتمد الطلب الذي يتلقاه خادمك على ما إذا كانت الأداة تحتوي على endpoint:

أداة تحتوي على endpointأداة لا تحتوي على endpoint
وجهة الطلبمباشرة إلى endpoint.urlعنوان URL القديم لخطاف الويب الخاص بمؤسستك
النصوسيطات الأداة فقطغلاف telephony.tool / web.tool
الرؤوسendpoint.headers لديك + X-ThunderPhone-Call-ID + X-ThunderPhone-SignatureContent-Type + X-ThunderPhone-Signature
مفتاح التوقيعسر خطاف الويب الخاص بالمؤسسةسر خطاف الويب الخاص بالمؤسسة

كلا المسارين حاجبان — ينتظر الذكاء الاصطناعي النتيجة في منتصف الجملة. المهلة الافتراضية هي 20 ثانية؛ اضبط timeout على المستوى الأعلى للأداة للسماح بتنفيذ أطول، حتى الحد الأقصى للمنصة البالغ 180 ثانية. حافظ على سرعة المعالجات. يمكن استخدام مزيج من المسارين: في مكالمة تكون لمؤسستها عنوان URL لخطاف ويب، تُستدعى الأدوات التي تحتوي على endpoint مباشرة، بينما تعود الأدوات الأخرى إلى خطاف الويب.

استدعاءات نقطة النهاية المباشرة

عندما يستدعي الذكاء الاصطناعي أداة لها 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 دائمًا كما هي، بالإضافة إلى ترويسَتين ضمن نطاق أسماء ThunderPhone:

  • X-ThunderPhone-Signature — قيمة HMAC-SHA256 لبايتات نص الطلب الدقيقة، باستخدام سر خطاف الويب الخاص بمؤسستك كمفتاح
  • X-ThunderPhone-Call-ID — معرّف المكالمة الحالية

يُضبط Content-Type: application/json ما لم تستبدله endpoint.headers لديك — إذ تكون الأولوية لقيمة Content-Type المخصصة.

نص الطلب

بالنسبة إلى POST / PUT / PATCH، يحتوي النص على وسيطات الأداة فقط (من دون غلاف)، ومُسلسَل بصيغة معيارية (مفاتيح مرتبة، وفواصل مختصرة):

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

بالنسبة إلى GET / DELETE، تُرسل الوسيطات باعتبارها معلمات استعلام ويكون النص فارغًا — ويُحتسب التوقيع حينها على سلسلة البايتات الفارغة. راجع التحقق من توقيعات خطاف الويب.

الاستجابة

أعِد استجابة JSON بنتيجة الأداة:

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

تُنسَّق الاستجابة وتُقدَّم إلى الذكاء الاصطناعي لمتابعة المحادثة. تُغلَّف الاستجابات غير التابعة لـ JSON بصيغة {"data": "<text>"}؛ وتُبلَّغ مهلات الانتظار وإخفاقات الاتصال إلى الذكاء الاصطناعي كأخطاء، ليتمكن الوكيل من الاعتذار والمتابعة بدلًا من التوقف.

الإرسال في وضع خطاف الويب

تُرسل الأدوات التي لا تحتوي على 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 القيمة origin_domain بدلًا من from_number / to_number. استجب بنتيجة الأداة بصيغة JSON — وهو عقد الاستجابة نفسه لاستدعاءات نقطة النهاية المباشرة. يُوقَّع الطلب بسر خطاف الويب الخاص بالمؤسسة على النص الخام، كما في كل خطافات الويب الأخرى.


التحقق من التوقيع

تُوقَّع استدعاءات الأدوات المباشرة بالطريقة نفسها التي تُوقَّع بها خطافات الويب:

  • HMAC-SHA256 على وحدات البايت الدقيقة لنص الطلب (JSON القياسي — مفاتيح مرتبة، دون مسافات بيضاء إضافية)
  • باستخدام سر خطاف الويب الخاص بمؤسستك
  • توقّع أدوات GET / DELETE سلسلة البايت الفارغة
Python
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}
Node.js
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 });
});

تتوفر الوصفات الكاملة — بما في ذلك حالة النص الفارغ والتنبيه المتعلق بعدم وجود سر — في التحقق من توقيعات خطاف الويب.


مثال: مسار حجز كامل

إليك مجموعة من الأدوات لنظام حجز مواعيد متكامل:

{
  "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 الذكاء الاصطناعي على فهم متى يستخدم الأداة. حدّد بدقة ما الذي تفعله ومتى يكون استخدامها مناسبًا.

تعامل مع الأخطاء بسلاسة

أرجع رسائل خطأ يمكن للذكاء الاصطناعي فهمها، مثل: {"error": "No slots available for that date"} بدلًا من أخطاء 500 العامة.

حافظ على إيجاز الاستجابات

أرجع فقط ما يحتاجه الذكاء الاصطناعي لمتابعة المحادثة. تؤدي الحمولات الكبيرة إلى إبطاء أوقات الاستجابة.

استخدم الحقول المطلوبة بحكمة

علّم الحقول على أنها required فقط عندما تكون ضرورية فعلًا. سيطلب الذكاء الاصطناعي من المستخدم المعلومات المطلوبة قبل استدعاء الأداة.


ذو صلة