---
title: "建立工具整合（API）"
description: "讓你的智能體在對話期間呼叫你的 API——搜尋資料庫、建立支援單、查詢訂單。"
---

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

<Note>
  控制台已可滿足大部分工具需求，無需使用此 API：**連線
  → 應用程式**只需數次 OAuth 點擊，即可連接 Slack、HubSpot、Salesforce、Google Calendar、
  Google Sheets 及 Cal.com；**連線 →
  API**可將任何 HTTP API 轉換為智能體動作（貼上 cURL 指令，
  AI 精靈便會草擬工具，並內置「測試請求」）；而 **連線 → MCP**則可加入 MCP 伺服器。請參閱
  [連線](/yue/guides/concepts)。本指南介紹 API 介面背後的底層
  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="window-maximize">
    開啟 **連線 → API**，建立或編輯 API 連線，
    將參數編輯器切換至 **JSON**，並在當中加入格式定義。
  </Card>
  <Card title="整合 API" icon="plug">
    使用 `POST /v1/integrations` 建立規格，或使用
    `PATCH /v1/integrations/{id}` 更新規格。
  </Card>
</CardGroup>

兩種方式均會建立已儲存的整合。儲存後，將該整合附加至
智能體。Agents API 並無可寫入的內嵌 `tools`
欄位。本指南使用整合 API 的方式。

## 2. 建立整合

```bash
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>

### 在地址參數宣告 `format: "email"`

接收電郵地址的參數，應在其 schema 中註明：

```json
"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`、空字串或只包含
空白的字串亦不會被修改；如屬必填且不可為空值的電郵，則會拒絕相同數值。

系統會檢查本機 schema 參照，例如 `#/$defs/email` 及
`#/definitions/email`，以及 `anyOf`、`oneOf` 和 `allOf`，並設有循環及深度
限制。非本機或無法解析的 `$ref` 是已知的強制執行限制，會原樣傳遞；工具快照
沒有可用 schema 的呼叫亦會原樣傳遞。如需套用此檢查，請將電郵 schema 保持為本機參照。

未強制要求電郵格式的參數，會完全按照模型產生的內容傳遞。

支援的格式包括 `date-time`、`time`、`date`、`duration`、
`email`、`hostname`、`ipv4`、`ipv6` 及 `uuid`；目前只有 `email`
會被正規化及強制執行。

## 3. 在沙盒測試端點

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

```bash
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
{
  "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
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
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}
```

LLM 會理解該回應，並向來電者口述自然易懂的摘要。

<Warning>
  簽章是使用與 webhook 端點相同的 `secret`，根據原始請求內容計算得出。
  **驗證簽章**——工具端點面向互聯網，與 webhook 一樣有遭偽造的風險。請參閱
  [驗證 webhook 簽章](/yue/guides/verify-webhook-signatures)。
</Warning>

## 6. 測試流程

針對智能體執行一個[咪高峰工作階段](/api-reference/mic-sessions)，
並提出你的工具可處理的問題（「94110 的天氣如何？」）。通話的文字記錄會顯示完整往返流程：

```json
{
  "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="Function Tools 規格" icon="screwdriver-wrench" href="/yue/tools/overview">
    完整 JSON schema 語法及已簽署端點合約。
  </Card>
  <Card title="驗證簽署" icon="shield-check" href="/yue/guides/verify-webhook-signatures">
    將 webhook 簽署模式套用至工具端點。
  </Card>
  <Card title="逐字稿＋記錄 API" icon="phone" href="/api-reference/calls">
    檢視工具呼叫的完整往返流程。
  </Card>
</CardGroup>
