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

# Agent API 總覽

> 透過相容 Anthropic 的串流端點呼叫任何已部署的 DataGen Agent

每一個 DataGen Agent 都提供一個相容 Anthropic Messages API 的端點。把官方
Anthropic SDK（或單純用 `curl`）指向你的 Agent，它就會以串流方式回應。

```
POST {base-url}/api/agents/{agent-name}/v1/messages
GET  {base-url}/api/agents/{agent-name}/v1/models
```

`{base-url}` 在 DataGen Cloud 是 `https://api.datagen.dev`；自架（self-hosted）
則是 `http://<你的伺服器 IP>:3001` — 詳見下方 [Base URL](#base-url)。

背後執行的是完整的 Agent 工作階段，而不是單純呼叫模型：Agent 的檔案與 repo、
skills、MCP 工具與密鑰，在這一回合期間全部都在沙箱中可用。

<Note>
  `{agent-name}` 是 Agent 詳細頁面上顯示的名稱。以 repo 為來源的 Agent 使用
  `owner-repo`（全小寫，`/` 換成 `-`），例如
  `datagendev-executive-assistant`；以儲存空間為來源的 Agent 則使用你自己命名的
  名稱，例如 `data-agent`。
</Note>

***

## Base URL

本節所有範例都使用 DataGen Cloud 的網址。**若你是自架，只要把主機換成自己的
伺服器即可，路徑完全相同。**

| 部署方式          | Base URL                  |
| ------------- | ------------------------- |
| DataGen Cloud | `https://api.datagen.dev` |
| 自架            | `http://<伺服器 IP>:3001`    |
| 自架 + TLS      | `https://<你的網域>`          |

同一個端點在三種部署下的樣子：

```bash theme={null}
# DataGen Cloud
https://api.datagen.dev/api/agents/invoice-agent/v1/messages

# 自架 — 你的伺服器 IP 或主機名稱，連接埠 3001
http://10.0.0.42:3001/api/agents/invoice-agent/v1/messages

# 自架 + TLS — 與網頁介面同一個網域，不需要連接埠
https://datagen.example.com/api/agents/invoice-agent/v1/messages
```

<Note>
  **連接埠 3001 是 API 伺服器，不是網頁介面。** 你的團隊用 **3000** 開啟
  DataGen；整合程式呼叫的是 **3001**。兩者在同一台機器上。如果管理者在 `.env`
  中改過 `WASP_BACKEND_PORT`，請改用該連接埠 — 也就是 `.env` 裡
  `WASP_SERVER_URL` 指向的位址。
</Note>

若採用 TLS 部署模式，反向代理會在同一個網域上同時提供網頁介面與 API，並把
`/api/*` 轉送到 API 伺服器；此時 3001 不對外開放，base URL 就是你的 DataGen
網域，不需要加連接埠。

<Tip>
  請把 base URL 做成設定值，不要寫死在程式碼裡。日後在雲端與自架之間搬移、或替
  既有安裝加上 TLS 時，只需要改一個環境變數，而不是每一個呼叫點。
</Tip>

***

## 第一次呼叫

<Steps>
  <Step title="取得 API key">
    在 DataGen 中開啟 **Workspace Settings → API Keys** 建立金鑰。請在**要呼叫的
    Agent 所屬的同一個 workspace** 中建立 — 金鑰只能存取該 workspace 的 Agent。
  </Step>

  <Step title="送出訊息">
    ```bash theme={null}
    curl -N -X POST "https://api.datagen.dev/api/agents/data-agent/v1/messages" \
      -H "X-Api-Key: $DATAGEN_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "claude-haiku-4-5",
        "stream": true,
        "messages": [{"role": "user", "content": "你能存取哪些資料來源？"}]
      }'
    ```
  </Step>

  <Step title="保留 conversation id">
    回應會帶有 `X-Conversation-Id` header。下一次呼叫時把它放進
    `metadata.conversation_id`，Agent 就會從上次結束的地方接續。詳見
    [對話](/api-reference/agent-api/zh/conversations)。
  </Step>
</Steps>

### 兩回合的完整範例

一段可直接複製執行的腳本，涵蓋整個使用流程 — 先提問，再在同一段對話中追問：

<CodeGroup>
  ```bash cURL theme={null}
  BASE=https://api.datagen.dev
  AGENT=data-agent

  turn() {  # turn "<訊息>" [conversation-id]
    curl -sN -D /tmp/h -X POST "$BASE/api/agents/$AGENT/v1/messages" \
      -H "X-Api-Key: $DATAGEN_API_KEY" -H "Content-Type: application/json" \
      -d "$(jq -n --arg m "$1" --arg c "${2:-}" '{
            stream: true,
            messages: [{role: "user", content: $m}],
            metadata: (if $c == "" then {} else {conversation_id: $c} end)
          }')" |
    # 逐步印出 Agent 的回覆文字。
    sed -n 's/^data: //p' | jq -rj 'select(.delta.type == "text_delta") | .delta.text'
  }

  turn "列出你可以存取的資料表。"
  CONV=$(grep -i '^x-conversation-id' /tmp/h | tr -d '\r' | awk '{print $2}')

  turn "第一個資料表有幾筆資料？" "$CONV"
  ```

  ```python Python theme={null}
  import json, requests   # 也可以改用 Anthropic SDK，見「送出訊息」頁

  BASE, AGENT = "https://api.datagen.dev", "data-agent"
  HEADERS = {"X-Api-Key": DATAGEN_API_KEY, "Content-Type": "application/json"}

  def turn(message, conversation_id=None):
      metadata = {}
      if conversation_id:
          metadata["conversation_id"] = conversation_id

      with requests.post(
          f"{BASE}/api/agents/{AGENT}/v1/messages",
          headers=HEADERS, stream=True, timeout=(10, 660),
          json={"stream": True,
                "messages": [{"role": "user", "content": message}],
                "metadata": metadata},
      ) as r:
          r.raise_for_status()
          for line in r.iter_lines(decode_unicode=True):
              if not line or not line.startswith("data: "):
                  continue
              evt = json.loads(line[6:])
              if evt.get("delta", {}).get("type") == "text_delta":
                  print(evt["delta"]["text"], end="", flush=True)
          return r.headers["X-Conversation-Id"]

  conv = turn("列出你可以存取的資料表。")
  turn("第一個資料表有幾筆資料？", conv)
  ```
</CodeGroup>

這段腳本中有三個關鍵：每次請求都要 `stream: true`、每次只送 **一則** 使用者訊息
（歷史紀錄來自對話本身，而不是陣列），以及從回應 header 讀出 conversation id 再
帶回去。

<Note>
  像上面這樣由程式連續送出多個回合，可能會快過伺服器的紀錄寫入，導致遺失上一回合
  的脈絡。自動化情境請在兩回合之間稍作等待，詳見
  [接續對話](/api-reference/agent-api/zh/conversations#接續對話)。
</Note>

***

## 與 Anthropic API 的三個差異

線路格式與 Anthropic 相同，因此既有的用戶端不必修改即可連線。真正不同的是
**語意**，有三點特別重要。

<Warning>
  **只有最後一則使用者訊息會送給 Agent。** 伺服器只讀取 `messages[]` 中最新的
  `role: "user"` 文字，其餘一律捨棄。對話歷史存在伺服器端 — 請傳
  `metadata.conversation_id`，不要重播整個陣列。若陣列的第一則訊息陳述了某項事實、
  最後一則詢問該事實，你只會得到「我不知道」。
</Warning>

<Warning>
  **一律使用串流。** 即使 `stream: false`，回應仍然是 `text/event-stream`。官方
  SDK 的非串流呼叫（`messages.create()`）並不會因為格式不符而拋出錯誤 — 它會回
  傳一個由誤解析文字填充的 `Message` 物件。請使用 `messages.stream()` 或對應的
  串流 API。
</Warning>

<Note>
  **取樣參數會被忽略。** 伺服器只讀取 `messages`、`stream`、`model`、`system`
  與 `metadata`。`max_tokens`、`temperature`、`top_p`、`stop_sequences`、`tools`
  與 `tool_choice` 會被接受但直接捨棄 — `max_tokens` 並非必填。Agent 使用的是它
  自己設定的工具，你無法從用戶端注入工具定義。
</Note>

還有一點與 Anthropic API 無關：Agent 是可以寫入的。

<Note>
  **使用 API key 呼叫時預設為唯讀。** 以 repo 為來源的 Agent 會讀取 repo，但不會
  commit 或 push，除非你送出 `metadata.read_only: false` — 屆時只要該回合變更了
  檔案，就會把 commit 推送到 repo 的預設分支。詳見
  [寫入連結的 repository](/api-reference/agent-api/zh/messages#寫入連結的-repository)。
</Note>

***

## 驗證

每一次請求都只需要一個 header：

```
X-Api-Key: <你的 api key>
```

請在 DataGen 應用程式的 **Workspace Settings → API Keys**
（`/workspace/settings?tab=apikeys`）建立金鑰；自架安裝也是同一個頁面。

**金鑰決定 workspace。** 金鑰是在 workspace 內建立、並屬於該 workspace，因此只能
存取該 workspace 的 Agent — 呼叫其他 workspace 的 Agent 會得到 `404`，即使你在網
頁介面上看得到它。若要呼叫團隊 workspace 的 Agent，請在選取該 workspace 的狀態下
建立金鑰。沒有任何 header 可以在單次請求中切換 workspace。

**金鑰決定權限。** 執行一個回合需要 **Admin**、**Builder** 或 **Operator** 金鑰；
**Viewer** 金鑰可以讀取對話，但送出訊息時會得到 `403`。

金鑰遺失或無法辨識會回傳 `401`；已撤銷的金鑰回傳
`401 {"message": "API key has been revoked"}`。

***

## 模型

```bash theme={null}
curl "https://api.datagen.dev/api/agents/data-agent/v1/models" \
  -H "X-Api-Key: $DATAGEN_API_KEY"
```

回傳這個 Agent 可使用的模型 id，並把 Agent 設定的預設模型排在第一位：

```json theme={null}
{
  "data": [
    {"type": "model", "id": "claude-opus-4-7",   "display_name": "Claude Opus 4.7"},
    {"type": "model", "id": "claude-sonnet-4-6", "display_name": "Claude Sonnet 4.6"},
    {"type": "model", "id": "claude-haiku-4-5",  "display_name": "Claude Haiku 4.5"}
  ],
  "has_more": false
}
```

驗證與錯誤語意和 `/v1/messages` 完全相同，因此在正式送出請求前，這是一個成本很低
的方式，用來確認 Agent 名稱與金鑰是否搭配正確。

若省略 `model`，解析順序為：automation 指定的模型（當你傳了
`metadata.automation`）→ Agent 的預設模型。

***

## 接下來

<CardGroup cols={3}>
  <Card title="送出訊息" icon="paper-plane" href="/api-reference/agent-api/zh/messages">
    完整的請求內容、SSE 事件串流與 SDK 範例。
  </Card>

  <Card title="對話" icon="comments" href="/api-reference/agent-api/zh/conversations">
    接續、分支、列出、分享與刪除對話。
  </Card>

  <Card title="錯誤與限制" icon="triangle-exclamation" href="/api-reference/agent-api/zh/errors">
    狀態碼、逾時與併發建議。
  </Card>
</CardGroup>
