异步任务
- 规范性
- 草案 1.0
- 更新于
- 查看 Markdown
7.1 创建任务
客户端通过发送它想要运行的响应请求来创建任务,请求要包在任务信封中。建议携带 Idempotency-Key 请求头(第 9.2 节)。
POST /lmsp/v1/tasks
Authorization: Bearer <token>
Idempotency-Key: 01J8M7C4Y3N5P8R2T6V9X1Z4BH
{
"type": "response",
"input": {
"model": "qwen3:14b-q4_k_m",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Write a long report."
}
]
}
]
},
"on_restart": "fail"
}
| 字段 | 必需 | 含义 |
|---|---|---|
type |
是 | response,1.0 中唯一的任务类型。 |
input |
是 | 一个响应请求,与 POST /lmsp/v1/responses 的请求相同。其中的 stream 字段会被忽略。 |
on_restart |
否 | fail(默认)、retry 或 resume。参见第 7.5 节。 |
服务必须先持久化任务,再作出应答。随后返回:
HTTP/1.1 202 Accepted
{
"id": "task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC",
"object": "task",
"type": "response",
"status": "queued",
"created_at": 1794200100,
"updated_at": 1794200100,
"response_id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW",
"events_url": "/lmsp/v1/tasks/task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC/events",
"on_restart": "fail",
"response": null,
"error": null
}
| 任务字段 | 含义 |
|---|---|
id |
任务标识符,例如 task_...。 |
object |
始终为 "task"。 |
type |
response。 |
status |
当前状态(第 7.2 节)。 |
created_at、updated_at |
时间,自 Unix 纪元起的秒数。 |
response_id |
该任务所产生的响应的 id,在创建任务时分配。 |
events_url |
事件流的路径。event_resume 能力为 true 时存在。 |
on_restart |
该任务的重启策略。 |
response |
status 为 succeeded 后是响应对象,否则为 null。 |
error |
status 为 failed 时是一个 problem 对象(第 9.3 节),否则为 null。 |
GET /lmsp/v1/tasks/{task_id} 返回任务对象。不使用事件流的客户端轮询该接口。未知的 id 返回 404 和 task_not_found。已结束的任务如下所示:
{
"id": "task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC",
"object": "task",
"type": "response",
"status": "succeeded",
"created_at": 1794200100,
"updated_at": 1794200162,
"response_id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW",
"events_url": "/lmsp/v1/tasks/task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC/events",
"on_restart": "fail",
"response": {
"id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW",
"object": "response",
"created_at": 1794200100,
"status": "completed",
"model": "qwen3:14b-q4_k_m",
"output": [
{
"id": "msg_01J8M8R6A2C5E8G1J4M7P0S3VY",
"type": "message",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "Local model services make on-device inference a shared, discoverable utility..."
}
]
}
],
"usage": {
"input_tokens": 12,
"output_tokens": 1480,
"total_tokens": 1492
},
"error": null,
"incomplete_details": null
},
"error": null
}
7.2 状态机
queued --> loading --> running --> succeeded
| | |
| | +--> failed
| | +--> cancelling --> cancelled
| +--------------> failed
+--------------------------> cancelled
| 状态 | 含义 | 后续状态 |
|---|---|---|
queued |
已接受并持久化,等待开始。 | loading、cancelled、failed |
loading |
正在加载模型。 | running、cancelling、failed |
running |
模型正在生成。 | succeeded、failed、cancelling |
cancelling |
已请求取消,后端尚未停止。 | cancelled |
succeeded |
终态。响应已完成。 | 无 |
failed |
终态。 | 无 |
cancelled |
终态。 | 无 |
终态只有 succeeded、failed 和 cancelled。处于终态的任务不得再发生变化。响应以 incomplete 结束的任务(例如达到 token 上限)是 succeeded。
每次状态转换都是原子的,因此任务不会既被取消又已完成,先提交的转换生效。
7.3 取消
POST /lmsp/v1/tasks/{task_id}/cancel
服务返回 200 OK 和当前任务对象。queued 任务立即变为 cancelled;loading 或 running 任务先变为 cancelling,直到后端停止后再变为 cancelled。
取消操作必须幂等:重复取消已处于 cancelling 或 cancelled 的任务,仍返回当前任务,不产生新错误。
取消已经 succeeded 或 failed 的任务,返回 409 和 task_not_cancelable。未知的 id 返回 404 和 task_not_found。
7.4 事件流
GET /lmsp/v1/tasks/{task_id}/events
Accept: text/event-stream
该接口是可选的,在 event_resume 能力为 true 时可用。
- 事件是第 6.3 节中的响应事件,对应该任务所产生的响应。序号与恢复规则遵循第 6.4 节。
- 事件流以
response.created开始,它在任务被接受时记录。流以与结果相符的一个最终事件结束:response.completed、response.incomplete、response.failed或response.cancelled。 - 较晚连接的客户端先收到自己错过的事件,再收到实时事件。服务在最终事件之后关闭流。
- 事件会保留一段保留期(第 11.2 节)。更早的事件返回
410 Gone和event_history_expired。
7.5 重启语义
on_restart 规定服务重启时对未完成任务如何处理:
| 取值 | 行为 |
|---|---|
fail |
默认值。服务把未完成的任务标记为 failed,错误码为 server_restarted。 |
retry |
服务从头重新执行该任务。 |
resume |
服务从快照继续执行。仅当后端明确支持可恢复快照时才允许,否则创建请求会被拒绝,返回 400 和 unsupported_capability。 |
服务重启时处于 cancelling 的任务,无论其策略如何,都会完成取消并变为 cancelled。
不建议把 retry 作为默认值,因为任务可能已经执行了工具或产生了外部副作用。选择 retry 的客户端必须同时使用 Idempotency-Key,并使其工具调用幂等。