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

# 送出訊息

> POST /api/agents/{agent}/v1/messages — 請求內容、串流回應與 SDK 用法

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

執行一個 Agent 回合，並以 Anthropic 風格的 server-sent events（SSE）串流回傳結果。

<Note>
  以下範例使用 DataGen Cloud（`https://api.datagen.dev`）。自架安裝請把主機換成自己的
  伺服器 — 例如
  `http://10.0.0.42:3001/api/agents/invoice-agent/v1/messages` — 其餘完全相同。
  詳見 [Base URL](/api-reference/agent-api/zh/overview#base-url)。
</Note>

***

## 請求內容

```json theme={null}
{
  "model": "claude-haiku-4-5",
  "stream": true,
  "system": "這一回合的額外指示。",
  "messages": [
    { "role": "user", "content": "整理昨天失敗的執行紀錄。" }
  ],
  "metadata": {
    "conversation_id": "support-ticket-4821",
    "stream_tool_calls": true
  }
}
```

| 欄位         | 型別      | 必填    | 說明                                                                                                                                     |
| ---------- | ------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `messages` | array   | **是** | 不可為空。只有最新的 `role: "user"` 文字會被使用。`content` 可以是字串，或 `{"type":"text","text":"…"}` 區塊陣列（以空行串接）。非文字區塊不會被讀取 — 檔案請改用 `metadata.attachments`。 |
| `stream`   | boolean | 否     | 請填 `true`。原因見[總覽](/api-reference/agent-api/zh/overview)的串流警告。                                                                          |
| `model`    | string  | 否     | `/v1/models` 回傳的 id 之一。未指定時依序回退到 automation 的模型、Agent 的預設模型。                                                                           |
| `system`   | string  | 否     | 會**附加**在 Agent 自身的指示之後，不會取代它。                                                                                                          |
| `metadata` | object  | 否     | DataGen 的擴充欄位，見下方。                                                                                                                     |

其他 Anthropic 欄位（`max_tokens`、`temperature`、`tools` 等）會被接受但忽略。

### `metadata`

| 欄位                  | 預設值                  | 作用                                                                                                    |
| ------------------- | -------------------- | ----------------------------------------------------------------------------------------------------- |
| `conversation_id`   | 自動產生                 | 接續的目標對話。可以是任意字串 — 例如你自己的工單編號、討論串 id。詳見[對話](/api-reference/agent-api/zh/conversations)。                |
| `stream_tool_calls` | `false`              | 在串流中顯示 `tool_use` 與 `tool_result` 區塊。若用戶端是一般 Anthropic 客戶端（只預期文字），請保持關閉。                              |
| `attachments`       | `[]`                 | 這一回合的附件檔案，base64 編碼。最多 **10 個檔案 / 解碼後 10 MiB**。會寫入 Agent 工作目錄下的 `.uploads/<name>`，並在提示中告知 Agent。      |
| `read_only`         | 使用 API key 時為 `true` | 以 repo 為來源的 Agent：可讀取 repo，但不會 commit 或 push。傳 `false` 才允許寫回，詳見[寫入連結的 repository](#寫入連結的-repository)。 |
| `isolated`          | `false`              | 在一次性的沙箱中執行，不 clone repo、不掛載 workspace 檔案。                                                             |
| `automation`        | —                    | 這個 Agent 上某個啟用中的 automation 名稱。它儲存的提示與模型會成為這一回合的預設值；請求本文中的設定優先。名稱不存在則忽略。                              |
| `delivery`          | `"sync"`             | 目前只支援 `"sync"`。`"async"` 會回傳 `501` — 背景執行請使用 webhook 或排程。                                             |

<Accordion title="內部旗標">
  `metadata.builder` 會在 Agent builder 的工作樹中執行（僅限以儲存空間為來源的
  Agent，需要 Admin 或 Builder 權限）；`metadata.test` 會把新對話標記為隱藏的測試
  執行。兩者是 DataGen 網頁介面在使用的，並非提供給外部整合。
</Accordion>

### 寫入連結的 repository

**使用 API key 呼叫時預設為唯讀。** 以 repo 為來源的 Agent 會 clone 並讀取 repo，
但除非你明確要求，否則不會寫回。

若要讓某一回合可以提交它的成果：

```json theme={null}
"metadata": { "read_only": false }
```

<Warning>
  當 `read_only: false` 時，只要該回合變更了任何檔案，結束前就會執行 `git add -A`、
  以 `datagen-agent` 身分 commit，並 **push 到 repository 的預設分支** — 不是暫存
  分支。請只在整合的目的就是修改 repository 時才送出這個設定，並考慮讓 Agent 指向
  預設分支受保護的 repo。
</Warning>

以儲存空間為來源的 Agent 沒有 repository，也不會 push。它們的工作檔案在每一回合開始
時重新還原、結束後不會寫回；一個回合的持久產出，是 Agent 寫入 outputs 目錄的內容，
這些會發佈到 workspace 的儲存空間。

### 附件

```json theme={null}
"metadata": {
  "attachments": [
    { "name": "leads.csv", "mediaType": "text/csv", "dataBase64": "bmFtZSxkb21haW4K…" }
  ]
}
```

只接受 base64，不要加 `data:` 前綴。檔名會被正規化為安全的檔名並自動去重複。格式錯誤
的項目、以及超出上限的部分會被靜默捨棄，因此若「缺少檔案」對你而言屬於重大問題，請在
用戶端先行驗證。附件永遠不會被提交到連結的 repository。

***

## 回應

`200 OK`、`Content-Type: text/event-stream`，並帶有 **`X-Conversation-Id`** 回應
header — 若你沒有自訂 id，請記得把它保存下來。

```
event: message_start
data: {"type":"message_start","message":{"id":"msg_…","model":"claude-haiku-4-5","usage":{…}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"…"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"text_delta","text":"以下是摘要…"}}

event: content_block_stop
data: {"type":"content_block_stop","index":1}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{…}}

event: message_stop
data: {"type":"message_stop"}
```

**區塊型別。** `text`、`thinking`（其後會跟著 `signature_delta`），以及在開啟
`stream_tool_calls` 時的 `tool_use`（伴隨 `input_json_delta`）與 `tool_result`
（帶有 `tool_use_id`、`content`、`is_error`）。`tool_result` 區塊是 DataGen 的擴充，
一般 Anthropic 客戶端會忽略它。

**顆粒度。** 區塊是整塊送達，而非逐 token：每個區塊是
`content_block_start` + 一次完整的 `content_block_delta` + `content_block_stop`。
`index` 是這一回合的遞增計數。

**結束方式。** 串流在 `message_stop` 結束 — 沒有 `data: [DONE]` 結尾標記。

**用量。** `message_delta.usage` 包含 `input_tokens`、`output_tokens`、
`cache_read_input_tokens`、`cache_creation_input_tokens`，以及 DataGen 專屬的
`total_cost_usd`（該回合的美元成本）。

<Warning>
  串流開始之後才發生的失敗，會以 SSE `error` 事件出現在一個已經回傳 `200` 的回應中：
  `event: error  data: {"error":{"type":"api_error","message":"…"}}`。
  請檢查 `error` 事件，不要只看 HTTP 狀態碼。
</Warning>

***

## 範例

<CodeGroup>
  ```bash cURL 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 - \
    -d '{
      "model": "claude-haiku-4-5",
      "stream": true,
      "metadata": {"conversation_id": "support-ticket-4821"},
      "messages": [{"role": "user", "content": "整理昨天失敗的執行紀錄。"}]
    }'
  ```

  ```python Python theme={null}
  from anthropic import Anthropic

  client = Anthropic(
      api_key=DATAGEN_API_KEY,
      # 結尾不要加 /v1 — SDK 會自動補上
      base_url="https://api.datagen.dev/api/agents/data-agent",
  )

  with client.messages.stream(
      model="claude-haiku-4-5",
      max_tokens=1024,                      # SDK 必填，DataGen 會忽略
      messages=[{"role": "user", "content": "整理昨天失敗的執行紀錄。"}],
      extra_body={"metadata": {"conversation_id": "support-ticket-4821"}},
  ) as stream:
      for text in stream.text_stream:
          print(text, end="", flush=True)
      print(stream.get_final_message().usage)
  ```

  ```typescript TypeScript theme={null}
  import Anthropic from "@anthropic-ai/sdk";

  const client = new Anthropic({
    apiKey: process.env.DATAGEN_API_KEY!,
    baseURL: "https://api.datagen.dev/api/agents/data-agent",
  });

  const stream = client.messages.stream({
    model: "claude-haiku-4-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "整理昨天失敗的執行紀錄。" }],
    // @ts-expect-error DataGen 擴充欄位
    metadata: { conversation_id: "support-ticket-4821", stream_tool_calls: true },
  });

  for await (const event of stream) {
    if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
      process.stdout.write(event.delta.text);
    }
  }
  ```
</CodeGroup>

<Note>
  之所以需要 `extra_body`（Python）與型別轉換（TypeScript），是因為 SDK 把
  `metadata` 定義成 Anthropic 的 `{user_id}` 物件。這個欄位會原封不動傳給 DataGen。
</Note>

### 不使用 SDK 讀取串流

```bash theme={null}
curl -sN … | while IFS= read -r line; do
  case "$line" in
    'data: '*) printf '%s' "$(printf '%s' "${line#data: }" |
      jq -r 'select(.delta.type=="text_delta").delta.text // empty')" ;;
  esac
done
```

***

## 以模型字串指定 Agent

如果你偏好用模型字串而不是 URL 路徑來選擇 Agent：

```
POST https://api.datagen.dev/api/agents/v1/messages
```

並帶上 `"model": "datagen-agent--data-agent"`（或直接用 Agent 名稱）。當用戶端只能
設定一個 base URL、而透過模型選單切換 Agent 時特別有用。其餘行為完全相同。
