# 모델 카탈로그

> LMSP 서비스가 로컬 모델을 나열하는 방법, 모델 객체와 기능 플래그, 모델 수명 주기 상태, 안정적인 모델 id, 카탈로그 리비전을 설명합니다.

Source: https://madeforagent.com/ko/lmsp/1.0/models/
Language: ko
Specification: LMSP 1.0 (draft)
Updated: 2026-11-08

## 5.1 모델 나열 {#list}

```http
GET /lmsp/v1/models?capability=chat&ready_only=false
Authorization: Bearer <token>
```

| 쿼리 매개변수 | 의미 |
| --- | --- |
| `capability` | 지정한 기능을 가진 모델만 반환한다. 예: `chat`, `embeddings`, `tools`. |
| `ready_only` | `true`이면 `status`가 `ready`인 모델만 반환한다. 기본값은 `false`. |

```json
{
  "object": "list",
  "catalog_revision": "42",
  "data": [
    {
      "id": "qwen3:14b-q4_k_m",
      "object": "model",
      "display_name": "Qwen3 14B Q4_K_M",
      "owned_by": "local",
      "family": "qwen3",
      "revision": "sha256:8f27c1a4e9b05d36f2a7c8e1b4d90a63c5e2f7b8a1d4c9e60b3f5a7d2c8e1b04",
      "status": "ready",
      "capabilities": {
        "chat": true,
        "completion": true,
        "embeddings": false,
        "tools": true,
        "vision": false,
        "structured_output": true,
        "streaming": true
      },
      "input_modalities": ["text"],
      "output_modalities": ["text"],
      "context_window": 32768,
      "max_output_tokens": 8192,
      "runtime": {
        "backend": "llama.cpp",
        "device": "metal",
        "load_on_demand": true
      }
    }
  ]
}
```

클라이언트가 전체 카탈로그를 반복해서 가져오지 않도록, 서비스는 `ETag` 헤더, `catalog_revision` 필드, 또는 둘 다를 반환하는 **것이 좋다**.

- `catalog_revision`은 카탈로그가 바뀔 때마다 바뀌는 불투명한 문자열이다.
- `ETag`를 보내는 서비스는 일치하는 `If-None-Match`에 `304 Not Modified`로 응답하는 **것이 좋다**.

## 5.2 모델 객체 {#object}

| 필드 | 의미 |
| --- | --- |
| `id` | 안정적인 모델 식별자. 모델을 지정하는 모든 요청에서 쓴다. |
| `object` | 항상 `"model"`. |
| `display_name` | 사람이 읽을 수 있는 이름. 사용자가 바꿀 수 있다. |
| `aliases` | 다른 이름의 선택적 목록. 참고용일 뿐이다. |
| `owned_by` | 모델의 출처. 이 기기에 설치된 모델은 `local`. |
| `family` | 모델 계열. 예: `qwen3`. |
| `revision` | 모델 내용의 다이제스트. 예: `sha256:8f27...`. |
| `status` | 수명 주기 상태([5.3절](https://madeforagent.com/ko/lmsp/1.0/models.md#lifecycle)). |
| `capabilities` | 불리언 플래그: `chat`, `completion`, `embeddings`, `tools`, `vision`, `structured_output`, `streaming`. |
| `input_modalities`, `output_modalities` | 모델이 읽고 쓰는 콘텐츠의 종류. 1.0에서 정의된 모달리티는 `text`뿐이다. |
| `context_window` | 컨텍스트의 최대 토큰 수. |
| `max_output_tokens` | 응답 하나의 최대 토큰 수. |
| `runtime` | `backend`(예: `llama.cpp`), `device`(예: `metal`), `load_on_demand`. |
| `error` | `status`가 `error`일 때 존재한다. problem 객체([9.3절](https://madeforagent.com/ko/lmsp/1.0/common-rules.md#errors)). |

모델 `id`는 안정적이어**야 한다**. 표시 이름과 별칭은 사용자가 바꿀 수 있으므로 기본 키로 써서는 **안 된다**.

## 5.3 모델 수명 주기 {#lifecycle}

```text
installed --> loading --> ready --> unloading --> installed
                 |
                 +-----> error
```

| 상태 | 의미 |
| --- | --- |
| `installed` | 모델은 있지만 로드되지 않았다. |
| `loading` | 메모리를 할당하는 중이거나 런타임을 초기화하는 중이다. |
| `ready` | 모델이 즉시 요청을 처리할 수 있다. |
| `unloading` | 리소스를 해제하는 중이다. |
| `error` | 로드에 실패했다. 모델 객체는 구조화된 오류를 담는 **것이 좋다**. |

`error` 상태의 모델은 새 로드 요청이 오면 `loading`으로 돌아간다.

요청이 `installed` 상태이면서 `runtime.load_on_demand`가 `true`인 모델을 지정하면, 서비스는 요청의 일부로 그 모델을 로드한다. 모델을 바로 쓸 수 없고 요청 시 로드되지도 않으면, 서비스는 `409`와 `model_not_ready`로 응답한다. 로드에 실패하면 오류는 `model_load_failed`이다.

## 5.4 모델 작업 {#operations}

`GET /lmsp/v1/models/{model_id}`는 모델 객체 하나를 반환한다. 알 수 없는 id는 `404`와 `model_not_found`를 반환한다.

두 개의 선택적 엔드포인트로 로드를 명시적으로 제어한다. 이들은 `model_management` 기능이 `true`일 때 사용할 수 있으며, `models:manage` 스코프가 필요하다([10.3절](https://madeforagent.com/ko/lmsp/1.0/security.md#scopes)).

| 엔드포인트 | 동작 |
| --- | --- |
| `POST /lmsp/v1/models/{model_id}/load` | 모델을 미리 로드한다. 로드가 시작되면 `202 Accepted`와 함께, 이미 `ready`이면 `200`과 함께 모델 객체를 반환한다. |
| `POST /lmsp/v1/models/{model_id}/unload` | 모델을 언로드한다. 모델 객체를 반환한다. 요청을 반복해도 해가 없다. |

둘 다 `Idempotency-Key`([9.2절](https://madeforagent.com/ko/lmsp/1.0/common-rules.md#idempotency))를 받는다.
