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

# Xây dựng tích hợp công cụ (API)

> Cho phép tác nhân AI gọi API của bạn trong khi hội thoại — tìm kiếm cơ sở dữ liệu, tạo phiếu hỗ trợ, tra cứu đơn hàng.

**Tích hợp công cụ** là một điểm cuối HTTP có thể tái sử dụng mà tác nhân AI có thể
gọi trong cuộc gọi. Bạn cung cấp cho ThunderPhone mô tả JSON-schema
của công cụ cùng URL điểm cuối; tác nhân AI quyết định thời điểm gọi công cụ
dựa trên cuộc trò chuyện, còn ThunderPhone gửi yêu cầu HTTP đi từ máy chủ của mình
và trả phản hồi về cho tác nhân AI.

<Note>
  Dashboard đáp ứng hầu hết nhu cầu về công cụ mà không cần API này: **Kết nối
  → Ứng dụng** kết nối Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets và Cal.com chỉ với vài lần nhấp OAuth; **Kết nối →
  API** biến bất kỳ HTTP API nào thành hành động của tác nhân AI (dán lệnh cURL
  và trình hướng dẫn AI sẽ soạn công cụ, kèm tính năng Kiểm tra yêu cầu tích hợp sẵn); và
  **Kết nối → MCP** thêm máy chủ MCP. Xem
  [Kết nối](/vi/guides/concepts). Hướng dẫn này trình bày API
  nền tảng bên dưới giao diện API.
</Note>

Hướng dẫn này sẽ chỉ bạn cách xây dựng công cụ tra cứu thời tiết từ đầu đến cuối.

## Cấu trúc của một công cụ

Gồm hai phần:

1. **Schema** — định nghĩa hàm theo kiểu OpenAI
   (`{type: "function", function: {name, description, parameters}}`)
   cho LLM biết công cụ làm gì và nhận những đối số nào.
2. **Điểm cuối** — URL mà máy chủ ThunderPhone gọi khi
   LLM quyết định sử dụng công cụ. Yêu cầu là JSON POST với
   các đối số do LLM chọn trong phần thân.

## 1. Chọn chiến lược lưu trữ

<CardGroup cols={2}>
  <Card title="Nội tuyến trên tác nhân AI" icon="paperclip">
    Đính kèm một công cụ dùng một lần vào mảng `tools` của tác nhân AI. Đơn giản, nhưng
    không thể tái sử dụng.
  </Card>

  <Card title="Tích hợp đã lưu" icon="plug">
    Lưu công cụ dưới dạng [tích hợp](/api-reference/integrations) có thể tái sử dụng
    và liên kết công cụ đó từ nhiều tác nhân AI. Khuyến nghị cho mọi thứ được dùng
    nhiều hơn một lần.
  </Card>
</CardGroup>

Hướng dẫn này sử dụng phương án tích hợp đã lưu.

## 2. Tạo tích hợp

```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" }
    ]
  }'
```

Lưu `id` được trả về (một UUID).

<Tip>
  Hãy đầu tư kỹ vào `description` của công cụ và từng
  tham số. LLM sử dụng các chuỗi này trong thời gian chạy để quyết định
  có nên gọi công cụ hay không và gọi như thế nào. Mô tả mơ hồ → lệnh gọi công cụ mơ hồ.
</Tip>

## 3. Kiểm tra điểm cuối trong sandbox

Trước khi liên kết tích hợp với một tác nhân AI, hãy gửi một yêu cầu đã ký
từ máy chủ ThunderPhone để xác nhận kết nối:

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

Kiểm tra này cũng tăng cường các biện pháp bảo vệ SSRF của ThunderPhone — các yêu cầu đến
localhost hoặc dải IP riêng tư sẽ trả về `400 code=url_not_allowed`.

## 4. Liên kết integration với tác nhân AI

Gắn qua `integration_ids` khi bạn tạo hoặc cập nhật một tác nhân AI:

```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-..."]
  }'
```

Bạn có thể liên kết nhiều integration với một tác nhân AI. Prompt của tác nhân AI có thể
tham chiếu chúng theo tên — "dùng `get_weather` khi người gọi hỏi
về điều kiện thời tiết" — hoặc có thể ngầm nhận diện chúng từ
mô tả schema.

## 5. Triển khai endpoint

Khi tác nhân AI gọi công cụ, ThunderPhone gửi một POST có chữ ký đến
`endpoint_url` của bạn:

```
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"}
```

Máy chủ của bạn phản hồi bằng JSON, sau đó được chuyển lại cho LLM:

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

LLM tiếp nhận phản hồi đó và nói bản tóm tắt dễ hiểu cho
người gọi.

<Warning>
  Chữ ký được tính trên phần thân yêu cầu thô bằng cùng
  `secret` với endpoint webhook của bạn. **Hãy xác minh chữ ký** — endpoint công cụ
  được công khai trên internet và chịu các rủi ro giả mạo tương tự
  webhook. Xem
  [Xác minh chữ ký webhook](/vi/guides/verify-webhook-signatures).
</Warning>

## 6. Kiểm thử quy trình

Chạy một [phiên micro](/api-reference/mic-sessions) với tác nhân AI
và đặt câu hỏi mà công cụ của bạn xử lý ("Thời tiết ở
94110 thế nào?"). Bản chép lời của cuộc gọi hiển thị toàn bộ quy trình:

```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." }
  ]
}
```

Bạn có thể truy xuất nội dung này qua
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript);
luồng sự kiện thô (có thời gian của từng mục và độ lệch âm thanh) nằm tại
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history).

## Các lỗi thường gặp

<AccordionGroup>
  <Accordion title="Tác nhân AI không bao giờ gọi công cụ">
    LLM quyết định dựa trên mô tả của công cụ. Nếu câu hỏi của người gọi
    không khớp với mô tả, mô hình sẽ không gọi
    công cụ. Hãy làm rõ mô tả hơn (thêm các từ đồng nghĩa và cách diễn đạt
    phổ biến) hoặc đề cập rõ trong prompt của tác nhân AI ("Khi
    người gọi hỏi về thời tiết, hãy dùng `get_weather`.").
  </Accordion>

  <Accordion title="Công cụ trả về quá nhiều dữ liệu">
    Phản hồi vượt quá 6 kB sẽ bị cắt bớt trong bản xem trước của bản chép lời. Chỉ trả về
    các trường mà LLM cần — không phải toàn bộ hàng dữ liệu của bạn.
  </Accordion>

  <Accordion title="Hết thời gian chờ">
    Endpoint công cụ có thời gian chờ mặc định là 10 giây. Nếu cần lâu hơn,
    hãy xử lý bất đồng bộ: trả về `{"status": "pending", "request_id": "..."}`
    và đưa kết quả qua một lần gọi công cụ riêng.
  </Accordion>

  <Accordion title="Lập phiên bản">
    Mỗi lần `PATCH` integration đều tạo một bản sửa đổi mới. Kiểm tra
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    để xem ai đã thay đổi gì. Nếu bạn làm hỏng schema của một công cụ, bạn có thể
    khôi phục thủ công bằng cách PATCH lại một snapshot cũ hơn.
  </Accordion>
</AccordionGroup>

***

## Bước tiếp theo

<CardGroup cols={2}>
  <Card title="Tài liệu tham khảo về tích hợp" icon="plug" href="/api-reference/integrations">
    CRUD, chuyển, lịch sử phiên bản.
  </Card>

  <Card title="Đặc tả Function Tools" icon="screwdriver-wrench" href="/vi/tools/overview">
    Ngữ pháp JSON schema đầy đủ và hợp đồng endpoint đã ký.
  </Card>

  <Card title="Xác minh chữ ký" icon="shield-check" href="/vi/guides/verify-webhook-signatures">
    Áp dụng mẫu chữ ký webhook cho các endpoint công cụ.
  </Card>

  <Card title="API bản chép lời + lịch sử" icon="phone" href="/api-reference/calls">
    Kiểm tra toàn bộ quy trình khứ hồi của một lệnh gọi công cụ.
  </Card>
</CardGroup>
