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

# AI Chat v2 API 對接說明

> AI Dialogue 整合指南 - Ace Data Cloud

AI Chat v2 API（`/aichat2/conversations`）是新一代的對話接口，是 [AI Chat API](https://platform.acedata.cloud/documents/aichat-conversations) 的全面升級版本。它在 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.8、Claude Sonnet 4.6、Gemini 3.1 Pro、GLM 5.1、DeepSeek V4、Kimi K3 等當代模型。

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

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

## 申請流程

要使用 AI Chat v2 API，首先到 [Ace Data Cloud 控制台](https://platform.acedata.cloud/console/applications) 獲取您的 API Token，留作備用。

![](https://cdn.acedata.cloud/5hmkdg.jpg)

如果你尚未登錄或註冊，會自動跳轉到登錄頁面邀請你註冊和登錄，完成後會自動返回當前頁面。

**一個 API Token 即可調用平台所有服務，無需為每個服務單獨申請。** 首次申請會贈送免費額度，可免費體驗；額度不足時可在 [控制台](https://platform.acedata.cloud/console/coin) 充值通用餘額。

> 📘 完整文檔：[AI Chat v2 API →](https://platform.acedata.cloud/documents/aichat2-conversations)

## 基本使用

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

CURL 示例：

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

返回結果：

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

Python 示例：

```python theme={null}
import requests

url = "https://api.acedata.cloud/aichat2/conversations"

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

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

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-8`、`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` 等
* DeepSeek：`deepseek-v4-flash`、`deepseek-v3.2-exp`、`deepseek-r1-0528` 等
* Moonshot：`kimi-k3`、`kimi-k2.6`、`kimi-k2.5` 等
* 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.acedata.cloud/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.acedata.cloud/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.acedata.cloud/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.acedata.cloud/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.acedata.cloud/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://platform.acedata.cloud/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`）可以強制單次回答、不允許任何工具調用。

## 非同步執行與無人值守授權

如果你的調用來自告警 Webhook、CI/CD、監控系統或其他後台任務，可以設置 `async: true` 讓接口立即返回任務 ID，後台繼續執行：

```json theme={null}
{
  "model": "gpt-5.5",
  "async": true,
  "question": "我的服務報警了，用個人微信通知微信群「AceDataCloud團隊」……"
}
```

返回示例：

```json theme={null}
{
  "task_id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "conversation_id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "status": "queued"
}
```

之後可用 `action: retrieve` + `id` 查詢會話結果；也可以提供 `callback_url`，任務完成後平台會把 `{ status, answer, usage, error }` POST 到你的回調地址。`callback_url` 必須使用 `http` / `https`，且不能直接填寫 `localhost` 或私有 IP 字面地址。

後台任務通常沒有人能點擊確認。如果你希望某些 Skill 或 MCP Server 在無人值守模式下執行發送、發布、寫入等動作，請在請求體裡顯式傳預授權列表：

```json theme={null}
{
  "model": "gpt-5.5",
  "async": true,
  "allowed_skills": ["acedatacloud/personal-wechat"],
  "allowed_mcp_servers": [],
  "question": "我的服務報警了，用個人微信通知微信群「AceDataCloud團隊」……"
}
```

`allowed_skills` 裡的值是已連接 Skill 的 slug；`allowed_mcp_servers` 裡的值是已連接 MCP Server 的 slug。未列入預授權的 Skill / MCP Server 在無人值守模式下仍只能預覽、dry-run 或拒絕執行寫操作。

如果需要更細的控制，也可以使用等價的 `unattended_policy` 對象：

```json theme={null}
{
  "unattended_policy": {
    "allowed_skills": ["acedatacloud/personal-wechat"],
    "allowed_mcp_servers": [],
    "expires_at": 1790000000
  }
}
```

預授權就是這兩個列表本身：列表為空即不授權任何能力，無需額外的開關字段。

注意：預授權只代表「本次請求允許這些能力在無人值守模式下跳過人工確認」。具體 Skill 仍必須支持 `--unattended-confirm` 或對應的安全機制；否則它會繼續 dry-run，不會直接執行寫操作。

## 恢復暫停的對話

某些工具會讓模型「反問用戶」，模型這時會發出一個 `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.acedata.cloud/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.acedata.cloud/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://platform.acedata.cloud/documents/aichat-conversations)，遷移到 v2 幾乎不需要改碼：

1. 把 URL 由 `https://api.acedata.cloud/aichat/conversations` 改成 `https://api.acedata.cloud/aichat2/conversations`。
2. 如果你之前傳的是 v1 模型名（如 `gpt-3.5`、`gpt-4-browsing` 等），切換到 v2 時建議升級到當代模型（如 `gpt-5.4`、`claude-opus-4-8`、`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 集成可以分階段平滑遷移。如有任何問題，請隨時聯繫我們的技術支持團隊。
