ThunderPhone 2.0 正式上線。自助開通,每分鐘 2¢ 起。查看公告

Developer cookbook

建立工具整合(API)

讓你的智慧體在對話中呼叫你的 API——搜尋資料庫、建立工單、查詢訂單。

工具整合是可重複使用的 HTTP 端點,智慧體可在通話期間 呼叫它。你需向 ThunderPhone 提供工具的 JSON Schema 描述 以及端點 URL;智慧體會根據對話決定何時呼叫工具,而 ThunderPhone 會從其伺服器發出對外 HTTP 請求,並將回應傳回給智慧體。

本指南會帶你從頭到尾建立天氣查詢工具。

工具的結構

包含兩個部分:

  1. Schema——OpenAI 風格的函式定義 ({type: "function", function: {name, description, parameters}}), 用於告知 LLM 工具的功能及其接受的引數。
  2. 端點——當 LLM 決定使用工具時,ThunderPhone 伺服器會呼叫的 URL。請求會以 JSON POST 形式傳送,並將 LLM 選定的引數作為 主體。

1. 選擇編輯器

控制台

開啟 連線 → API,建立或編輯 API 連線, 將參數編輯器切換為 JSON,然後在其中新增格式。

Integrations API

使用 POST /v1/integrations 建立規格,或使用 PATCH /v1/integrations/{id} 更新規格。

兩種方式都會建立已儲存的整合。儲存後,將該整合附加至 智慧體。Agents API 沒有可寫入的內嵌 tools 欄位。本指南使用 Integrations 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"

接收電子郵件地址的參數,應在其 schema 中明確指出:

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

format 不只是提示。對於已解析的電子郵件 schema,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 的電子郵件,這些值會遭拒絕。

系統會檢查本機 schema 參照,例如 #/$defs/email 與 #/definitions/email,以及 anyOf、oneOf 和 allOf,並設有循環與深度限制。非本機或無法解析的 $ref 屬於已知的強制驗證限制,會原樣傳遞;工具快照沒有可用 schema 的呼叫也是如此。需要套用此閘門時,請將電子郵件 schema 保持為本機參照。

未強制使用電子郵件格式的參數,會完全依照模型產生的內容原樣傳遞。

支援的格式為 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 現在會將測試通話與實際流量分開報告。瀏覽器 Talk 測試和模擬可重複使用真實電話號碼,且可能顯示為撥入通話,但不會計入正式環境的通話總數、評分或問題指標。

常見問題

智慧體從未呼叫工具

LLM 會根據工具的描述做出決定。若來電者的問題與描述不符,模型就不會呼叫 工具。請調整描述(加入常見同義詞與措辭),或在智慧體提示詞中明確提及它 (「當來電者詢問天氣時,使用 get_weather。」)。

工具回傳過多資料

超過 6 kB 的回應會在逐字稿預覽中遭到截斷。只回傳 LLM 所需的欄位——不要回傳整列資料。

逾時

工具端點的預設逾時時間為 10 秒。若你需要更長時間,請以非同步方式處理:回傳 {"status": "pending", "request_id": "..."} 並透過另一個工具呼叫提供結果。

版本管理

每次整合 PATCH 都會建立新的修訂版本。查看 GET /v1/integrations/{id}/versions 以瞭解誰變更了哪些內容。若你破壞了工具的架構,可以手動將較舊的快照 PATCH 回去以復原。


後續步驟