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

# AI Chat v2 API 對接說明

> AI Dialogue 集成指南 - XHuoAPI

AI Chat v2 API（`/aichat2/conversations`）是新一代的對話接口，是 [AI Chat API](https://api.xhuoapi.ai/documents/59fb1199-6694-4afb-a222-3554d7f7d05a) 的全面升級版本。它在 v1 簡潔、托管多輪對話的基礎上，擴展了：

* **多模態用戶輸入**：透過結構化 `message` 欄位直接傳文本 + 圖片 + 檔案塊，無需先用 `references` 間接附加。
* **Agent 化工具調用**：內建一套聯網搜尋、網頁抓取、檔案讀取等工具，並可掛載用戶授權的 MCP 伺服器（Google Drive、Notion、Slack、GitHub 等），模型可在一次請求裡多輪自主調用工具完成複雜任務。
* **結構化串流事件**：透過 `accept: text/event-stream` 或 `application/x-ndjson` 可拿到逐 token 的 `text_delta`、`tool_use`、`tool_result`、`thinking`、`citation`、`card`、`artifact` 等事件，便於在前端按對應類型分別渲染。
* **可中斷 / 可恢復**：模型在需要用戶補充資訊時會發出 `ask_user_question` 事件並暫停，下次調用透過 `tool_results` 回填答案即可繼續。
* **新增 CRUD 動作**：在同一個 endpoint 上透過 `action` 欄位完成 `retrieve` / `retrieve_batch` / `update` / `delete`，無需額外的會話管理 API。
* **持續更新的模型列表**：預設接入 GPT-5.4、Claude Opus 4.7、Claude Sonnet 4.6、Gemini 3.1 Pro、GLM 5.1、DeepSeek V4、Kimi K2.5 等當代模型。

同時它在請求體層面**完全向後相容 v1**：只傳 `model` + `question`（+ 可選 `stateful` / `id` / `references` / `preset`）即可得到與 v1 等價的 `{answer, id}` JSON 回應，所以從 `/aichat/conversations` 遷移過來不需要重寫客戶端，只需把路徑換為 `/aichat2/conversations`。

> 如果你目前在使用 `/aichat/conversations`，舊接口仍會保留服務，可以按自己的節奏遷移。

## 申請流程

要使用 API，需要先到 [AI Chat v2 API](https://api.xhuoapi.ai/documents/e4a7c2b9-3f1d-4e8a-9b6c-a5d2f8e1b4c7) 對應頁面申請對應的服務，進入頁面之後，點擊「Acquire」按鈕即可獲取請求所需要的憑證。

如果你尚未登入或註冊，會自動跳轉到登入頁面，註冊並登入之後會自動返回當前頁面。

在首次申請時會有免費額度贈送，可以免費使用該 API。

## 基本使用

最簡單的用法和 v1 完全一致：傳 `model` + `question`，拿到 `{answer, id}`。

CURL 範例：

```shell theme={null}
curl -X POST 'https://api.xhuoapi.ai/v1/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "question": "用一句話介紹下 XHuoAPI。"
  }'
```

返回結果：

```json theme={null}
{
  "answer": "XHuoAPI 是一個聚合主流 AI 模型與多模態服務的統一 API 平台，開發者透過一個密鑰即可調用 GPT、Claude、Gemini、Midjourney、Suno、Veo 等多家服務。",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Python 範例：

```python theme={null}
import requests

url = "https://api.xhuoapi.ai/v1/aichat2/conversations"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json",
}

payload = {
    "model": "gpt-5.4",
    "question": "用一句話介紹下 XHuoAPI。",
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
```

可用的 `model` 取值可在右側的 Try 面板下拉裡直接看到，常用類別包括：

* OpenAI：`gpt-5.4-mini`、`gpt-5.4-nano`、`gpt-5.2-pro`、`gpt-5.1-all`、`gpt-5-all`、`gpt-4.1`、`gpt-4o`、`gpt-4o-image`、`o3`、`o4-mini` 等
* Anthropic：`claude-opus-4-7`、`claude-opus-4-6`、`claude-opus-4-5-20251101`、`claude-sonnet-4-6`、`claude-sonnet-4-5-20250929`、`claude-haiku-4-5-20251001` 等
* Google：`gemini-3.1-pro`、`gemini-3.1-pro-preview`、`gemini-3.1-flash-image-preview`、`gemini-3-pro-preview`、`gemini-2.5-flash-lite` 等
* xAI：`grok-4`、`grok-4-1-fast`、`grok-4-1-fast-reasoning`、`grok-3-mini-fast` 等
* DeepSeek：`deepseek-v4-flash`、`deepseek-v3.2-exp`、`deepseek-r1-0528` 等
* Moonshot：`kimi-k2.5`、`kimi-k2-thinking`、`kimi-k2-thinking-turbo` 等
* Zhipu：`glm-5.1`、`glm-5`、`glm-5-turbo`、`glm-4.7`、`glm-4.5v` 等

具體計費規則參見服務頁面的 Pricing 卡片。

## 多輪對話

和 v1 一樣，傳 `stateful: true` 開啟會話保存，API 會返回一個 `id`；後續請求把 `id` 帶回來即可繼續對話，無需自己維護 messages 歷史。

第一次請求：

```shell theme={null}
curl -X POST 'https://api.xhuoapi.ai/v1/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "question": "記住一個數字：42。"
  }'
```

返回：

```json theme={null}
{
  "answer": "好的，我已經記住了 42。需要我用它做什麼嗎？",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

第二次請求，帶上同一個 `id`：

```shell theme={null}
curl -X POST 'https://api.xhuoapi.ai/v1/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
    "question": "我剛才讓你記住的數字是多少？"
  }'
```

```json theme={null}
{
  "answer": "你讓我記住的數字是 42。",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

> `stateful` 預設是 `true`，省略和顯式傳 `true` 等價。如果你不希望服務端保存這一輪對話，可以顯式設定 `stateful: false`。

## 流式回應

v2 支援兩種流式格式，按照 `accept` 頭選擇：

| 場景                    | `accept`               | 資料形態                                       |
| :-------------------- | :--------------------- | :----------------------------------------- |
| Web 前端 / EventSource  | `text/event-stream`    | `data: {json}\n\n`，最後一行 `data: [DONE]\n\n` |
| 服務端 / CLI / Node 串流解析 | `application/x-ndjson` | 每行一個 JSON 物件                               |
| 不需要流式                 | `application/json`（預設） | 一次性返回 `{answer, id}`                       |

### NDJSON 範例

```python theme={null}
import json
import requests

url = "https://api.xhuoapi.ai/v1/aichat2/conversations"

headers = {
    "accept": "application/x-ndjson",
    "authorization": "Bearer {token}",
    "content-type": "application/json",
}

payload = {
    "model": "gpt-5.4",
    "stateful": True,
    "question": "用三句話介紹杭州。",
}

with requests.post(url, json=payload, headers=headers, stream=True) as resp:
    answer = ""
    for line in resp.iter_lines():
        if not line:
            continue
        event = json.loads(line)
        if event.get("type") == "text_delta":
            # 與 v1 相容：增量片段同時透過 delta_answer 欄位提供
            answer += event["content"]
            print(event["delta_answer"], end="", flush=True)
        elif event.get("type") == "done":
            print()
            print("usage =", event.get("usage"))
```

NDJSON 每一行都是結構化事件，最常見的是 `text_delta`：

```json theme={null}
{"type":"text_delta","content":"杭","delta_answer":"杭","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"州","delta_answer":"州","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"是","delta_answer":"是","id":"f2f4b3e8-..."}
...
{"type":"done","conversation_id":"f2f4b3e8-...","usage":{"prompt_tokens":21,"completion_tokens":58,"total_tokens":79},"terminal_reason":"natural_stop"}
```

### SSE 範例

瀏覽器端使用 `EventSource` 不支援自訂請求體，建議使用 `fetch` + 手動按 `\n\n` 切片解析：

```javascript theme={null}
const resp = await fetch("https://api.xhuoapi.ai/v1/aichat2/conversations", {
  method: "POST",
  headers: {
    accept: "text/event-stream",
    authorization: "Bearer {token}",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    model: "gpt-5.4",
    stateful: true,
    question: "用三句話介紹杭州。",
  }),
});

const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const blocks = buffer.split("\n\n");
  buffer = blocks.pop() ?? "";
  for (const block of blocks) {
    const dataLine = block.split("\n").find((l) => l.startsWith("data: "));
    if (!dataLine) continue;
    const payload = dataLine.slice(6);
    if (payload === "[DONE]") return;
    const event = JSON.parse(payload);
    if (event.type === "text_delta") process.stdout.write(event.content);
  }
}
```

### 流式事件類型

| `type`              | 含義                                                                                              |
| :------------------ | :---------------------------------------------------------------------------------------------- |
| `text_delta`        | 助手回答的增量文本片段。`content` 為新增內容；為相容 v1，同一事件還攜帶 `delta_answer`（等於 `content`）和 `id`。                  |
| `thinking`          | 模型的思考過程（僅在所選模型暴露 reasoning 時出現）。                                                                |
| `tool_use`          | 模型決定調用一個工具，事件攜帶 `tool_id`、`tool_name`、`input`。                                                  |
| `tool_result`       | 工具執行結果，與上一條 `tool_use` 透過 `tool_id` 配對，`is_error` 標識是否失敗。                                       |
| `card`              | 工具產出的結構化卡片（如圖片、連結預覽），適合直接渲染。                                                                    |
| `citation`          | 用於補充對應文本片段引用的來源 URL。                                                                            |
| `ask_user_question` | 模型需要用戶補充資訊時發出，對話進入 `awaiting_user_input` 狀態，詳見下文 [恢復暫停的對話](#恢復暫停的對話)。                           |
| `artifact`          | 模型生成的獨立產物（如程式碼塊、文件），可保存或下載。                                                                     |
| `system_message`    | 系統提示資訊（非用戶與助手內容），僅用於 UI 提示。                                                                     |
| `compact`           | 內部上下文被壓縮的事件，無需特殊處理。                                                                             |
| `error`             | 本輪發生錯誤，`message` 描述錯誤內容。                                                                        |
| `done`              | 流式回應結束，攜帶 `usage`（含 `prompt_tokens` / `completion_tokens` / `total_tokens`）和 `terminal_reason`。 |

對於只關心最終答案的客戶端，把所有 `text_delta` 的 `content` 拼接起來就和 `application/json` 模式下的 `answer` 等價。

## 多模態輸入

如果用戶輸入包含圖片或檔案，傳 `message`（陣列）代替 `question`。每個陣列元素是一個內容塊：

```json theme={null}
{
  "model": "gpt-5.4",
  "stateful": true,
  "message": [
    { "type": "text", "text": "這張圖片裡有幾隻貓？" },
    { "type": "image_url", "image_url": { "url": "https://cdn.xhuoapi.ai/cats.jpg" } }
  ]
}
```

支援的塊類型：

* `text` — 普通文本，必填 `text` 欄位。
* `image_url` — 圖片，必填 `image_url.url`。
* `file_url` — 檔案（PDF、CSV、TXT 等），必填 `file_url.url`。

### 與 v1 `references` 的關係

為了相容舊客戶端，v2 仍然識別 `references: ["https://...", ...]` 欄位：

* URL 後綴是 `jpg / jpeg / png / gif / bmp / webp / svg / heic / heif`，自動轉成 `image_url` 塊；
* 其他副檔名轉成 `file_url` 塊；
* 如果還同時提供了 `question`，則把它作為一個 `text` 塊前置。

因此只想從 v1 遷移又不想改請求體的話，把路徑換成 `/aichat2/conversations` 即可，原 `references` 用法照常工作。

需要更精細控制（比如把多張圖片放在文本之間、或者順序很重要）就直接用 `message` 陣列。

## 工具調用與 MCP

v2 的核心增強點是模型可以自主調用工具完成多步任務，**這是預設開啟的**，不需要客戶端在請求裡做任何額外配置。常見場景：

* 用戶問「幫我搜一下最近上海有什麼新展覽」→ 模型調用內建 web search → 把結果整理成回答。
* 用戶問「讀一下這個 PDF 然後寫個摘要」→ 模型調用 file\_read → 寫摘要。
* 用戶已在 [Connections](https://api.xhuoapi.ai/connections) 裡授權了 Google Drive / GitHub / Notion 等 → 模型可調用對應的 MCP 工具讀寫其資料。

在 NDJSON / SSE 串流裡，工具調用透過 `tool_use` 和 `tool_result` 兩類事件呈現，例如：

```json theme={null}
{"type":"tool_use","tool_id":"toolu_01ABCDEF","tool_name":"web_search","input":{"query":"上海 2026 春季展覽"},"id":"f2f4b3e8-..."}
{"type":"tool_result","tool_id":"toolu_01ABCDEF","output":"...","is_error":false,"id":"f2f4b3e8-..."}
{"type":"text_delta","content":"目前","delta_answer":"目前","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"上海","delta_answer":"上海","id":"f2f4b3e8-..."}
...
```

如果你不想在前端展示工具調用細節，忽略 `tool_use` / `tool_result` / `card` / `citation` 這幾類事件即可，模型最終輸出依然透過 `text_delta` 流出。

`max_turns` 可以限制本次請求裡模型最多自我調用工具幾輪，預設上限由平台決定。把它設小（比如 `max_turns: 1`）可以強制單次回答、不允許任何工具調用。

## 恢復暫停的對話

某些工具會讓模型「反問用戶」，模型這時會發出一個 `ask_user_question` 事件，對話被冻结在 `awaiting_user_input` 狀態：

```json theme={null}
{
  "type": "ask_user_question",
  "tool_id": "toolu_01XYZW",
  "tool_name": "ask_user_question",
  "question": "你希望生成的報告是中文還是英文？",
  "options": ["中文", "英文"],
  "id": "f2f4b3e8-..."
}
```

在前端把這個事件渲染成卡片讓用戶選答案，然後用同一個 `id` 發起下一次請求，把答案透過 `tool_results` 回填：

```shell theme={null}
curl -X POST 'https://api.xhuoapi.ai/v1/aichat2/conversations' \
  -H 'accept: text/event-stream' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
    "tool_results": [
      {
        "tool_use_id": "toolu_01XYZW",
        "output": "中文"
      }
    ]
  }'
```

請求體中 `tool_use_id` **必須**和暫停時的 `tool_id` 完全一致；不一致會返回 400。當請求裡同時存在 `tool_results` 時，`question` / `message` / `references` 都會被忽略。

如果用戶決定放棄這個問題，直接傳一個新的 `question` / `message` 即可，平台會自動把暫停的工具調用標記為「用戶跳過」。

## 會話管理（CRUD）

v2 在同一個 endpoint 上透過 `action` 欄位提供輕量級會話管理，無需另外開 API。

### `action: retrieve` —— 拉取一個會話

```shell theme={null}
curl -X POST 'https://api.xhuoapi.ai/v1/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "action": "retrieve",
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
  }'
```

返回完整的會話文件（包含 `messages` 歷史、`model`、`title`、`tools_used` 等）。

### `action: retrieve_batch` —— 列出會話摘要

```json theme={null}
{
  "action": "retrieve_batch",
  "model_group": "chatgpt",
  "limit": 20,
  "offset": 0
}
```

返回 `{ items: [...], total }`。**摘要不包含 `messages`**，適合做側邊欄列表；如果用戶點開某條會話，再用 `action: retrieve` 單獨拉取它的完整消息。

可選過濾參數：`user_id`、`application_id`、`model_group`、`model`。

### `action: update` —— 改標題或重寫歷史

```json theme={null}
{
  "action": "update",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "title": "杭州旅行計劃"
}
```

`messages` 也可以傳，但服務端會做嚴格的 schema 校驗（必須是折疊後的 `ToolUseContent` 形態），不符合會返回 400。一般只建議用來改 `title`。

### `action: delete` —— 刪除一個會話

```json theme={null}
{
  "action": "delete",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

返回 `{ id, success: true }`。刪除後無法恢復，請確認後再調用。

## 從 v1 平滑遷移

如果你已經在使用 [`/aichat/conversations`](https://api.xhuoapi.ai/documents/59fb1199-6694-4afb-a222-3554d7f7d05a)，遷移到 v2 幾乎不需要改程式碼：

1. 把 URL 由 `https://api.xhuoapi.ai/v1/aichat/conversations` 改成 `https://api.xhuoapi.ai/v1/aichat2/conversations`。
2. 如果你之前傳的是 v1 模型名（如 `gpt-3.5`、`gpt-4-browsing` 等），切換到 v2 時建議升級到當代模型（如 `gpt-5.4`、`claude-opus-4-7`、`gemini-3.1-pro` 等）。
3. NDJSON 串流的欄位保持向後相容：每個 `text_delta` 事件依然帶 `delta_answer` 與 `id`，因此原來按行解析 `delta_answer` 的客戶端無需改動。

遷移之後可以按需啟用 v2 的新能力（多模態 `message`、SSE、工具調用、`action` CRUD），按節奏推進即可。

## 錯誤處理

錯誤回應統一為：

```json theme={null}
{
  "error": {
    "code": "chat_error",
    "message": "upstream LLM returned an error"
  },
  "trace_id": "2cf86e86-22a4-46e1-ac2f-032c0f2a4e89"
}
```

常見錯誤：

* `400 bad_request`：缺少必填欄位、`tool_use_id` 不匹配、`messages` schema 非法等。
* `401 invalid_token`：`authorization` 頭不正確。
* `404 not_found`：`action: retrieve / update / delete` 時 `id` 對應的會話不存在。
* `429 too_many_requests`：觸發了速率限制。
* `500 chat_error`：上游 LLM 報錯或本輪 `completion_tokens=0`（按未消費處理，不會扣費）。

在流式回應裡，錯誤以 `{"type":"error","message":"..."}` 事件發出，緊接著串流就會結束。

## 結論

AI Chat v2 API 在向後相容 v1 的同時，把對話從「單輪 / 多輪問答」升級為「Agent 化的可觀測對話」：多模態輸入、工具調用、可暫停 / 可恢復、流式結構化事件、內建 CRUD。建議新接入直接使用 v2；已有 v1 集成可以分階段平滑遷移。如有任何問題，請隨時聯繫我們的技術支援團隊。
