ThunderPhone 2.0 уже доступний.Підключайте самостійно — від 2 ¢/хв.Прочитати анонс

Developer cookbook

Створення інтеграції інструменту (API)

Дозвольте своєму агенту викликати ваші API під час розмови — шукати в базі даних, створювати заявку, знаходити замовлення.

Інтеграція інструмента — це багаторазово використовувана HTTP-кінцева точка, яку агент може викликати під час дзвінка. Ви надаєте ThunderPhone опис інструмента у форматі JSON-схеми разом з URL кінцевої точки; агент вирішує, коли її викликати, на основі розмови, а ThunderPhone надсилає вихідний HTTP-запит зі своїх серверів і повертає відповідь агенту.

Цей посібник покроково пояснює створення інструмента для отримання даних про погоду.

Будова інструмента

Дві складові:

  1. Схема — визначення функції у стилі OpenAI ({type: "function", function: {name, description, parameters}}), яке повідомляє LLM, що робить інструмент і які аргументи він приймає.
  2. Кінцева точка — URL, який викликають сервери ThunderPhone, коли LLM вирішує використати інструмент. Запит є JSON POST із вибраними LLM аргументами в тілі.

1. Виберіть редактор

Панель керування

Відкрийте З’єднання → API, створіть або відредагуйте API-з’єднання, перемкніть редактор параметрів на JSON і додайте там формат.

API інтеграцій

Створіть специфікацію за допомогою POST /v1/integrations або оновіть її за допомогою PATCH /v1/integrations/{id}.

Обидва способи створюють збережену інтеграцію. Після збереження прикріпіть цю інтеграцію до агента. 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, порожній рядок або рядок, що містить лише пробіли, також не змінюються, коли властивість необов’язкова або допускає значення null; ті самі значення відхиляються для обов’язкової адреси електронної пошти, що не допускає null.

Локальні посилання на схему, як-от #/$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 надсилає підписаний POST на ваш endpoint_url:

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 кБ скорочуються в попередньому перегляді транскрипту. Повертайте лише поля, потрібні LLM, а не весь запис.

Тайм-аути

Кінцеві точки інструментів мають стандартний тайм-аут 10 секунд. Якщо вам потрібно більше часу, обробляйте запит асинхронно: поверніть {"status": "pending", "request_id": "..."} і передайте результат через окремий виклик інструмента.

Версіонування

Кожен PATCH інтеграції створює нову редакцію. Перегляньте GET /v1/integrations/{id}/versions, щоб дізнатися, хто і що змінив. Якщо ви порушите схему інструмента, ви можете вручну відкотити зміни, застосувавши PATCH зі старішим знімком.


Наступні кроки