> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 建立工具整合（API）

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

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

<Note>
  控制台無須使用此 API 即可滿足大多數工具需求：**連線
  → 應用程式**可透過幾次 OAuth 點擊連接 Slack、HubSpot、Salesforce、Google Calendar、
  Google Sheets 與 Cal.com；**連線 →
  APIs** 可將任何 HTTP API 轉換為智慧體動作（貼上 cURL 指令，
  AI 精靈便會草擬工具，並提供內建的「測試請求」）；**連線 → MCP**
  可新增 MCP 伺服器。請參閱
  [連線](/zh-Hant/guides/concepts)。本指南介紹 APIs 介面底層的
  原始 API。
</Note>

本指南將帶你端對端建立天氣查詢工具。

## 工具的結構

包含兩個部分：

1. **Schema**——OpenAI 風格的函式定義
   (`{type: "function", function: {name, description, parameters}}`)，
   用於告訴 LLM 工具的用途及其接受的引數。
2. **端點**——當 LLM 決定使用工具時，ThunderPhone 伺服器呼叫的
   URL。請求是 JSON POST，並以 LLM 選定的引數作為本文內容。

## 1. 選擇儲存策略

<CardGroup cols={2}>
  <Card title="直接附加至智慧體" icon="paperclip">
    將一次性工具附加至智慧體的 `tools` 陣列。簡單，但
    無法重複使用。
  </Card>

  <Card title="已儲存的整合" icon="plug">
    將工具儲存為可重複使用的[整合](/api-reference/integrations)，
    並從多個智慧體連結至該工具。建議用於任何使用超過
    一次的工具。
  </Card>
</CardGroup>

本指南使用已儲存的整合方式。

## 2. 建立整合

```bash theme={null}
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）。

<Tip>
  請認真撰寫工具及各項引數的 `description`。LLM 會在執行階段
  使用這些字串來決定是否以及如何呼叫工具。描述模糊 →
  工具呼叫也會模糊。
</Tip>

## 3. 在沙箱中測試端點

在將整合連結至智慧體之前，先從 ThunderPhone 的伺服器發出已簽署的
請求，以確認連線能力：

```bash theme={null}
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" }
  }'
```

```json Response theme={null}
{
  "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` 附加整合：

```bash theme={null}
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: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json

{"zip": "94110"}
```

你的伺服器會回傳 JSON，並交回給 LLM：

```json theme={null}
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}
```

LLM 會擷取該回應，並向來電者說出自然語言摘要。

<Warning>
  簽章是使用與你的 webhook 端點相同的 `secret`，針對原始
  請求主體計算而成。**請驗證簽章**——工具端點面向網際網路，
  與 webhook 一樣面臨偽造風險。請參閱
  [驗證 webhook 簽章](/zh-Hant/guides/verify-webhook-signatures)。
</Warning>

## 6. 測試流程

對智慧體執行 [麥克風工作階段](/api-reference/mic-sessions)，
並提出你的工具可處理的問題（「94110 的天氣如何？」）。通話的逐字稿會顯示完整往返流程：

```json theme={null}
{
  "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`](/api-reference/calls#get-transcript) 取得此資訊；
原始事件串流（包含每筆項目的時間與音訊偏移）位於
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history)。

## 常見陷阱

<AccordionGroup>
  <Accordion title="智慧體從不呼叫工具">
    LLM 會根據工具描述決定是否呼叫工具。如果來電者的
    問題不符合描述，模型便不會呼叫該工具。請強化描述（加入常見同義詞和
    說法），或在智慧體提示詞中明確提及它（「當
    來電者詢問天氣時，使用 `get_weather`。」）。
  </Accordion>

  <Accordion title="工具回傳過多資料">
    超過 6 kB 的回應會在逐字稿預覽中遭到截斷。請只回傳
    LLM 所需的欄位——不要回傳整筆資料列。
  </Accordion>

  <Accordion title="逾時">
    工具端點的預設逾時時間為 10 秒。如果你需要更長時間，
    請以非同步方式處理：回傳 `{"status": "pending", "request_id": "..."}`
    並透過另一個工具呼叫呈現結果。
  </Accordion>

  <Accordion title="版本管理">
    每次整合 `PATCH` 都會建立新的修訂版本。查看
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    以了解誰變更了哪些內容。如果你破壞了工具的結構描述，可以
    手動將較舊的快照 PATCH 回去以復原。
  </Accordion>
</AccordionGroup>

***

## 後續步驟

<CardGroup cols={2}>
  <Card title="整合參考資料" icon="plug" href="/api-reference/integrations">
    CRUD、移轉、版本紀錄。
  </Card>

  <Card title="函式工具規格" icon="screwdriver-wrench" href="/zh-Hant/tools/overview">
    完整的 JSON 結構描述語法與簽署端點契約。
  </Card>

  <Card title="驗證簽章" icon="shield-check" href="/zh-Hant/guides/verify-webhook-signatures">
    將 Webhook 簽章模式套用至工具端點。
  </Card>

  <Card title="逐字稿與歷程 API" icon="phone" href="/api-reference/calls">
    檢視工具呼叫的完整往返流程。
  </Card>
</CardGroup>
