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. Виберіть стратегію зберігання

Вбудований в агента

Додайте одноразовий інструмент до масиву tools агента. Це просто, але не придатне для повторного використання.

Збережена інтеграція

Збережіть інструмент як повторно використовувану інтеграцію і прив’яжіть його до багатьох агентів. Рекомендовано для всього, що використовується більше одного разу.

У цьому посібнику використовується шлях зі збереженою інтеграцією.

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).

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, ...}"
}

Цей тест також посилює SSRF-захист ThunderPhone — запити до 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: <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. Протестуйте цикл

Запустіть mic session для агента та поставте запитання, яке обробляє ваш інструмент («Яка погода в 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.

Поширені помилки

Агент ніколи не викликає інструмент

LLM ухвалює рішення на основі опису інструмента. Якщо запитання абонента не відповідає опису, модель не викличе інструмент. Уточніть опис (додайте поширені синоніми та формулювання) або явно згадайте його в промпті агента («Коли абонент запитує про погоду, використовуй get_weather.»).

Інструмент повертає забагато даних

Відповіді понад 6 кБ обрізаються в попередньому перегляді транскрипту. Повертайте лише поля, потрібні LLM, а не весь ваш рядок.

Тайм-аути

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

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

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


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