비동기 작업
- 규범적
- 초안 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로 끝나는 작업(예: 토큰 한도)은 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와 함께 쓰고 도구 호출을 멱등하게 만들어야 한다.