# 回應與串流傳輸

> LMSP 的核心對話介面：Responses 風格的請求與輸出項、同步與串流生成、伺服器傳送事件的型別、事件 id、斷線重連以及工具呼叫。

Source: https://madeforagent.com/zh-tw/lmsp/1.0/responses/
Language: zh-TW
Specification: LMSP 1.0 (draft)
Updated: 2026-11-08

## 6.1 請求 {#request}

```http
POST /lmsp/v1/responses
Authorization: Bearer <token>
Content-Type: application/json
Idempotency-Key: 01J8M5T7Z2K4N6Q8S0V3X5B9DG
LMSP-Version: 1.0
```

```json
{
  "model": "qwen3:14b-q4_k_m",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Describe a local model service in one sentence."
        }
      ]
    }
  ],
  "stream": false,
  "max_output_tokens": 512,
  "temperature": 0.7,
  "response_format": {
    "type": "text"
  },
  "store": true
}
```

核心協定採用 Responses 風格的 `input`/`output` 結構，而不是只支援簡單的 messages 字串，以便用同一種請求格式統一承載：

- 多輪訊息；
- 文本、圖片、音訊和檔案；
- 工具呼叫及工具結果；
- 結構化輸出；
- 推理摘要；
- 多模態輸出。

LMSP 1.0 只定義文本內容。圖片、音訊和檔案的內容型別留待後續版本。

| 欄位 | 必需 | 含義 |
| --- | --- | --- |
| `model` | 是 | 要使用的模型 id。 |
| `input` | 是 | 輸入項陣列。`message` 項包含 `role`（`system`、`user` 或 `assistant`）和由多個部分組成的 `content` 陣列，例如 `input_text`。使用工具時會增加 `function_call` 和 `function_call_output` 項（[第 6.5 節](https://madeforagent.com/zh-tw/lmsp/1.0/responses.md#tools)）。 |
| `stream` | 否 | 為 `true` 時接收伺服器傳送事件，預設為 `false`。 |
| `max_output_tokens` | 否 | 生成 token 數的上限。 |
| `temperature` | 否 | 取樣溫度。 |
| `response_format` | 否 | `{"type": "text"}`（預設），或用於結構化輸出的 `{"type": "json_schema", "json_schema": {"name": "...", "schema": {...}}}`。需要 `structured_output` 能力。 |
| `tools`、`tool_choice` | 否 | 模型可以呼叫的函式工具（[第 6.5 節](https://madeforagent.com/zh-tw/lmsp/1.0/responses.md#tools)）。需要 `tools` 能力。 |
| `store` | 否 | 請求服務儲存該回應，以便之後查詢，並可用作 `previous_response_id`。預設為 `false`。沒有 `conversations` 能力的服務會忽略它。 |
| `previous_response_id` | 否 | 接著已儲存的某個回應繼續對話。需要 `conversations` 能力。 |
| `extensions` | 否 | 私有擴充（[第 9.1 節](https://madeforagent.com/zh-tw/lmsp/1.0/common-rules.md#versioning)）。 |

請求需要模型不具備的能力時，回傳 `400` 和 `unsupported_capability`。請求放不進上下文視窗時，回傳 `400` 和 `context_length_exceeded`。

能夠儲存工作階段的服務**可以**額外支援 `previous_response_id`；否則每次請求都**必須**攜帶完整上下文。服務**不得**依賴 HTTP 連線儲存對話狀態。

## 6.2 同步回應 {#sync}

當 `stream` 為 `false` 時，服務在生成結束後回傳 `200 OK` 和一個回應物件。

```json
{
  "id": "resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF",
  "object": "response",
  "created_at": 1794200000,
  "status": "completed",
  "model": "qwen3:14b-q4_k_m",
  "output": [
    {
      "id": "msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE",
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "A local model service is a resident interface layer that discovers, manages and calls models on the user's own device."
        }
      ]
    }
  ],
  "usage": {
    "input_tokens": 28,
    "output_tokens": 31,
    "total_tokens": 59
  },
  "error": null,
  "incomplete_details": null
}
```

| 欄位 | 含義 |
| --- | --- |
| `id` | 回應識別碼，例如 `resp_...`。 |
| `object` | 始終為 `"response"`。 |
| `created_at` | 建立時間，自 Unix 紀元起的秒數。 |
| `status` | `in_progress`、`completed`、`incomplete`、`failed` 或 `cancelled`。同步回應回傳時已處於最終狀態。 |
| `model` | 生成該回應的模型 id。 |
| `output` | 輸出項陣列。 |
| `usage` | token 用量：`input_tokens`、`output_tokens` 和 `total_tokens`。 |
| `error` | `null`；當 `status` 為 `failed` 時是一個 problem 物件（[第 9.3 節](https://madeforagent.com/zh-tw/lmsp/1.0/common-rules.md#errors)）。 |
| `incomplete_details` | `null`；當 `status` 為 `incomplete` 時是帶有 `reason`（例如 `max_output_tokens`）的物件。 |

輸出項型別：

| 項型別 | 結構 |
| --- | --- |
| `message` | `id`、`role`（`assistant`）和 `content`，後者是 `output_text` 部分的陣列，每個部分帶有 `text`。 |
| `function_call` | `id`、`call_id`、`name` 和 `arguments`，後者是 JSON 編碼的字串。 |
| `reasoning` | `id` 和 `summary`，後者是 `summary_text` 部分的陣列，每個部分帶有 `text`。 |

如果生成失敗，同步請求回傳錯誤狀態碼和 problem 文件（[第 9.3 節](https://madeforagent.com/zh-tw/lmsp/1.0/common-rules.md#errors)），而不是回應物件。`failed` 狀態只出現在流、任務和已儲存的回應中。

`GET /lmsp/v1/responses/{response_id}` 回傳以 `store: true` 儲存的回應。它是可選介面，需要 `conversations` 能力。未知的 id 回傳 `404` 和 `response_not_found`。

## 6.3 串流回應 {#streaming}

要使用串流傳輸，在請求中設定 `stream`：

```json
{
  "stream": true
}
```

服務回傳 `200 OK` 和 `Content-Type: text/event-stream`，並傳送語義化事件。每個事件包含 `id`、`event` 名稱和一個 JSON `data` 物件：

```text
id: 1
event: response.created
data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","status":"in_progress"}

id: 2
event: response.output_item.added
data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","output_index":0,"item":{"id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","type":"message","role":"assistant","content":[]}}

id: 3
event: response.output_text.delta
data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","item_id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","delta":"A local model "}

id: 4
event: response.output_text.delta
data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","item_id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","delta":"service is a resident interface layer."}

id: 5
event: response.output_item.done
data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","output_index":0,"item":{"id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","type":"message","role":"assistant","content":[{"type":"output_text","text":"A local model service is a resident interface layer."}]}}

id: 6
event: response.completed
data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","status":"completed","usage":{"input_tokens":28,"output_tokens":12,"total_tokens":40}}
```

最少定義以下事件：

| 事件 | 含義 | 資料欄位 |
| --- | --- | --- |
| `response.created` | 回應已建立。 | `response_id`、`status`（`in_progress`） |
| `response.output_item.added` | 開始了一個新的輸出項。 | `response_id`、`output_index`、`item` |
| `response.output_text.delta` | 文本被追加到某個 message 項。 | `response_id`、`item_id`、`delta` |
| `response.output_item.done` | 一個輸出項已完成。 | `response_id`、`output_index`、`item` |
| `response.completed` | 回應已完成。最終事件。 | `response_id`、`status`、`usage` |
| `response.incomplete` | 生成提前停止，例如達到 token 上限。最終事件。 | `response_id`、`status`、`incomplete_details`、`usage` |
| `response.failed` | 生成失敗。最終事件。 | `response_id`、`status`、`error` |
| `response.cancelled` | 回應已取消。最終事件。 | `response_id`、`status` |
| `error` | 與某個具體回應無關的問題，出現後流無法繼續。 | `error`，一個 problem 物件 |

服務在最終事件或 `error` 事件之後關閉流。

服務**可以**傳送額外的事件，例如工具呼叫引數、圖片、音訊和結構化 JSON 增量。客戶端**必須**忽略不認識的事件型別。

如果客戶端關閉了串流請求的連線，服務**應**停止生成。

## 6.4 事件 id 與重連 {#reconnection}

事件的 `id` **必須**是整數序號，在該回應內嚴格遞增，從 1 開始。

連線斷開後，客戶端透過傳送自己收到的最後一個 id 來恢復。可以使用請求標頭：

```http
Last-Event-ID: 2
```

或使用查詢引數：

```http
GET /lmsp/v1/tasks/{task_id}/events?after=2
```

兩者都發往任務的事件介面（[第 7.4 節](https://madeforagent.com/zh-tw/lmsp/1.0/tasks.md#events)）。服務只補發序號大於 2 的事件。兩者同時出現時，以 `after` 為準。

如果請求的事件已超出保留期，服務回傳 `410 Gone` 和錯誤碼 `event_history_expired`，客戶端改為透過 `GET /lmsp/v1/tasks/{task_id}` 取得最終結果。

直接從 `POST /lmsp/v1/responses` 串流回傳的回應屬於該 HTTP 連線，無法恢復。需要可恢復輸出的客戶端**應**建立[任務](https://madeforagent.com/zh-tw/lmsp/1.0/tasks.md)並跟隨它的事件。

## 6.5 工具呼叫 {#tools}

LMSP 1.0 定義由客戶端執行的函式工具，服務本身不執行工具。`tools:execute` 許可權範圍預留給會執行工具的擴充（[第 10.3 節](https://madeforagent.com/zh-tw/lmsp/1.0/security.md#scopes)）。

首先，客戶端列出工具。每個條目的 `type` 為 `function`，並帶有 `name`、`description` 和 `parameters`（一個 JSON Schema 物件）。`tool_choice` 可以是 `auto`（預設）、`none`、`required`，或 `{"type": "function", "name": "get_weather"}`。

```json
{
  "model": "qwen3:14b-q4_k_m",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "What is the weather in Hangzhou?"
        }
      ]
    }
  ],
  "tools": [
    {
      "type": "function",
      "name": "get_weather",
      "description": "Get the current weather for a city.",
      "parameters": {
        "type": "object",
        "properties": {
          "city": { "type": "string" }
        },
        "required": ["city"]
      }
    }
  ],
  "tool_choice": "auto"
}
```

當模型決定呼叫工具時，回應中會包含一個 `function_call` 項，其 `arguments` 是 JSON 編碼的字串。在流中，該項會以完整形式出現在 `response.output_item.done` 中。

```json
{
  "id": "resp_01J8M7B3N6Q9T2V5X8Z1C4D7FH",
  "object": "response",
  "created_at": 1794200050,
  "status": "completed",
  "model": "qwen3:14b-q4_k_m",
  "output": [
    {
      "id": "fc_01J8M7B3N8R1S4W7Y0A3E6G9JK",
      "type": "function_call",
      "call_id": "call_01J8M7B3N9T2V5X8Z1C4D7F0HM",
      "name": "get_weather",
      "arguments": "{\"city\":\"Hangzhou\"}"
    }
  ],
  "usage": {
    "input_tokens": 74,
    "output_tokens": 18,
    "total_tokens": 92
  },
  "error": null,
  "incomplete_details": null
}
```

客戶端執行工具，然後傳送一個攜帶完整上下文的新請求：之前的輸入項、收到的 `function_call` 項，以及一個 `call_id` 相同的 `function_call_output` 項。其 `output` 是字串，通常為 JSON 編碼。

```json
{
  "type": "function_call_output",
  "call_id": "call_01J8M7B3N9T2V5X8Z1C4D7F0HM",
  "output": "{\"temperature_c\":17,\"condition\":\"light rain\"}"
}
```
