공통 규칙
- 규범적
- 초안 1.0
- 갱신일
- Markdown으로 보기
9.1 버전과 확장
각 LMSP 요청은 다음 헤더를 실을 수 있다.
LMSP-Version: 1.0
LMSP-Client: example-client/1.2.0
LMSP-Version은 클라이언트가 대상으로 하는 프로토콜 버전이다. LMSP-Client는 진단을 위해 클라이언트 소프트웨어를 name/version 형식으로 식별한다. 서비스는 이를 근거로 프로토콜 동작을 바꾸어서는 안 된다.
규칙:
- 경로의
v1은 주 버전을 뜻한다. - 알 수 없는 주 버전을 지정한 요청에는
426 Upgrade Required와 오류 코드unsupported_protocol_version으로 응답한다. - 새로운 선택적 필드는 1.x 호환성을 깨뜨려서는 안 된다.
- 서비스와 클라이언트는 알지 못하는 필드를 무시해야 한다.
- 비공개 확장은
extensions객체에 넣고 역도메인 표기로 이름을 짓는다.
{
"extensions": {
"com.example.cache": {
"enabled": true
}
}
}
9.2 멱등성
응답 생성, 작업 생성, 모델 로드처럼 무언가를 만드는 요청은 멱등성 키를 받는다.
Idempotency-Key: <client-generated-unique-value>
서비스는 키를 요청 본문의 다이제스트 및 결과와 함께 저장한다.
- 같은 키에 같은 본문이면 원래 결과를 반환한다.
- 같은 키에 다른 본문이면
409 Conflict와idempotency_conflict로 응답한다.
키의 범위는 클라이언트와 엔드포인트이다. 키는 ULID나 UUID처럼 최대 255자의 고유한 값인 것이 좋다. 서비스는 키를 최소 24시간 보관하는 것이 좋다.
서비스는 스트리밍 요청에서는 키를 무시할 수 있다. 안전한 재시도가 필요한 클라이언트는 작업을 사용한다.
9.3 오류
LMSP 인터페이스의 모든 오류는 application/problem+json(RFC 9457)을 사용한다.
{
"type": "urn:lmsp:error:model-not-found",
"title": "Model not found",
"status": 404,
"code": "model_not_found",
"detail": "No local model with id 'qwen3:14b-q4_k_m'",
"request_id": "req_01J8M9S6Y4W8C3P5R1V7Z2A0DH",
"retryable": false
}
| 필드 | 필수 | 의미 |
|---|---|---|
type |
예 | 오류의 종류를 식별하는 URI. LMSP는 urn:lmsp:error: 뒤에 밑줄을 하이픈으로 바꾼 코드를 붙여 쓴다. |
title |
예 | 사람이 읽을 수 있는 짧은 요약. |
status |
예 | HTTP 상태 코드. |
code |
예 | 아래 목록에 있는, 기계 판독 가능한 오류 코드. |
detail |
아니요 | 이번 오류에 대한 사람이 읽을 수 있는 설명. 비밀 값, 프롬프트, 생성된 콘텐츠를 담아서는 안 된다. |
request_id |
아니요 | 서비스 로그와 대조하기 위한 요청의 식별자. |
retryable |
예 | 나중에 요청을 반복하면 성공할 수 있는지 여부. |
일반적인 오류 코드:
| 코드 | HTTP 상태 | 재시도 가능 | 의미 |
|---|---|---|---|
invalid_request |
400 | 아니요 | 요청 형식이 잘못되었거나 매개변수가 올바르지 않다. |
unauthorized |
401 | 아니요 | 토큰이 없거나, 올바르지 않거나, 만료되었거나, 폐기되었다. 또는 페어링 코드가 틀렸다. |
forbidden |
403 | 아니요 | 토큰에 필요한 스코프가 없거나, Origin 또는 Host 검사에 실패했다. |
model_not_found |
404 | 아니요 | 이 id의 로컬 모델이 없다. |
model_not_ready |
409 | 예 | 모델이 로드되어 있지 않고 요청 시 로드되지도 않는다. |
model_load_failed |
500 | 예 | 모델 로드에 실패했다. |
context_length_exceeded |
400 | 아니요 | 입력이 모델의 컨텍스트 윈도우에 들어가지 않는다. |
unsupported_capability |
400 또는 501 | 아니요 | 모델 또는 서비스가 요청에 필요한 것을 지원하지 않는다. 구현되지 않은 선택적 엔드포인트는 501로 응답한다. |
unsupported_protocol_version |
426 | 아니요 | 서비스가 요청한 주 버전을 지원하지 않는다. |
response_not_found |
404 | 아니요 | 이 id의 저장된 응답이 없다. |
task_not_found |
404 | 아니요 | 이 id의 작업이 없다. |
task_not_cancelable |
409 | 아니요 | 작업이 이미 성공했거나 실패했다. |
idempotency_conflict |
409 | 아니요 | 그 멱등성 키가 이미 다른 요청 본문과 함께 쓰였다. |
event_history_expired |
410 | 아니요 | 요청한 이벤트가 보존 기간보다 오래되었다. |
rate_limited |
429 | 예 | 요청이 너무 많다. |
resource_exhausted |
503 | 예 | 기기의 메모리나 다른 리소스가 부족하다. |
backend_unavailable |
503 | 예 | 모델 런타임에 연결할 수 없다. |
server_restarted |
503 | 예 | 작업이 끝나지 않은 상태에서 서비스가 재시작되었다. |
internal_error |
500 | 경우에 따라 다름 | 서비스 내부의 예기치 못한 실패. |
retryable 필드가 기준이다. 위 열은 일반적인 값을 보여 준다. 서비스는 코드를 더 정의할 수 있다. 클라이언트는 알지 못하는 코드를 HTTP 상태와 retryable 필드로 처리해야 한다.
9.4 상태 점검
GET /lmsp/v1/health
{
"status": "ready",
"service_id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2",
"uptime_seconds": 86420,
"loaded_models": 1,
"active_tasks": 2,
"storage": "ok"
}
| 필드 | 의미 |
|---|---|
status |
starting, ready, degraded, stopping. |
service_id |
서비스 설명에 있는 서비스 id. |
uptime_seconds |
서비스가 시작된 뒤 지난 초. |
loaded_models |
ready 상태인 모델의 수. |
active_tasks |
queued, loading, running, cancelling 상태인 작업의 수. |
storage |
ok 또는 error. |
status가 ready 또는 degraded이면 200 OK, 그렇지 않으면 503 Service Unavailable이다.
상태 점검 엔드포인트는 운영 상태만 반환한다. 모델 경로, 프롬프트, 액세스 토큰 또는 그 밖의 민감한 정보를 반환해서는 안 된다.