서비스 검색
- 규범적
- 초안 1.0
- 갱신일
- Markdown으로 보기
3.1 검색 방법
클라이언트는 다음 방법을 순서대로 시도하여 서비스를 찾는다.
- 수동 설정. 사용자가 서비스 주소를 직접 입력한다.
- 관례적인 로컬 주소 탐색. 클라이언트가 후보 주소에
/.well-known/lmsp.json을 요청한다. 관례적인 후보는http://127.0.0.1:17832와http://[::1]:17832이다. - LAN 검색. 클라이언트가 mDNS와 DNS-SD로
_lmsp._tcp.local.을 탐색한다.
유효한 서비스 설명(3.3절)을 얻으면 그 방법은 성공이다. 사용자가 직접 입력한 주소는 항상 검색된 주소보다 우선한다.
3.2 LAN 광고
DNS-SD는 PTR 레코드로 서비스 인스턴스를 찾고, SRV 레코드로 호스트와 포트를 얻고, TXT 레코드로 소량의 추가 정보를 전달한다. mDNS와 결합하면 로컬 네트워크에서 무구성 검색을 제공한다(RFC 6763, RFC 6762).
광고 예시:
Service type: _lmsp._tcp.local.
Instance name: Workstation LMSP._lmsp._tcp.local.
TXT record:
v=1
id=svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2
path=/
auth=pairing
| TXT 키 | 의미 |
|---|---|
v |
광고 형식의 버전. LMSP 1.0에서는 1. |
id |
서비스 id. 서비스 설명의 service.id와 같다. |
path |
서비스 루트의 URL 경로. 클라이언트는 {path}.well-known/lmsp.json을 요청한다. |
auth |
인증 힌트. pairing은 서비스를 쓰기 전에 클라이언트가 페어링해야 함을 뜻한다. |
규칙:
- 서비스는 액세스 토큰, 모델 목록, 파일 경로 등 민감한 정보를 TXT 레코드에 넣어서는 안 된다. 이 레코드는 서비스의 위치만 알려 준다. 실제 기능은 서비스 설명에서 읽어야 한다.
- 서비스는 mDNS 광고를 기본적으로 비활성화해 두어야 한다. 사용자가 LAN 검색을 명시적으로 켠 경우에만 활성화된다. 로컬 컴퓨터에서만 쓰는 서비스는 광고하지 않는다.
- LAN에서 광고하는 서비스는 루프백 밖에서도 수신 대기해야 하는데, 이는 LAN 모드에서만 허용된다(10.5절).
- 클라이언트는 TXT 레코드를 검증되지 않은 힌트로 취급하고, 서비스 설명을 읽어 서비스를 확인해야 한다.
3.3 서비스 설명
GET /.well-known/lmsp.json
서비스는 이 문서를 인증을 요구하지 않고 application/json으로 제공해야 한다.
{
"protocol": "lmsp",
"versions": ["1.0"],
"service": {
"id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2",
"name": "Workstation Local Models",
"version": "1.0.0"
},
"interfaces": [
{
"kind": "lmsp",
"version": "1.0",
"url": "http://127.0.0.1:17832/lmsp/v1",
"transport": "http+json"
},
{
"kind": "openai",
"version": "responses+chat",
"url": "http://127.0.0.1:17832/v1",
"transport": "http+json"
}
],
"capabilities": {
"streaming": true,
"tasks": true,
"event_resume": true,
"conversations": true,
"model_management": true
},
"authentication": {
"type": "bearer",
"pairing_url": "http://127.0.0.1:17832/lmsp/v1/pair"
},
"openapi": "http://127.0.0.1:17832/lmsp/v1/openapi.json"
}
| 필드 | 의미 |
|---|---|
protocol |
항상 "lmsp". |
versions |
서비스가 지원하는 LMSP 버전. major.minor 형식의 문자열. |
service |
id는 안정적인 서비스 식별자, name은 표시 이름, version은 서비스 소프트웨어의 버전. |
interfaces |
제공하는 인터페이스. 각각 kind(lmsp, openai, ollama), version, 기본 url, transport를 가진다. openai의 경우 version은 제공하는 API 계열을 나타낸다(예: responses+chat). |
capabilities |
불리언 기능 플래그. 아래에 나열한다. |
authentication |
type은 bearer. pairing_url은 클라이언트가 페어링 코드를 토큰으로 교환하는 위치이다(10.2절). |
openapi |
LMSP 인터페이스를 기술하는 OpenAPI 문서의 URL. |
기능 플래그:
| 플래그 | 의미 |
|---|---|
streaming |
응답을 서버 전송 이벤트로 스트리밍할 수 있다. 1.0에서는 true여야 한다. |
tasks |
비동기 작업을 사용할 수 있다. 1.0에서는 true여야 한다. |
event_resume |
작업 이벤트 스트림을 구독하고 재개할 수 있다(GET /lmsp/v1/tasks/{task_id}/events). |
conversations |
서비스가 응답을 저장하므로 store와 previous_response_id가 동작하고 GET /lmsp/v1/responses/{response_id}를 사용할 수 있다. |
model_management |
모델을 명시적으로 로드하고 언로드할 수 있다. |
3.4 클라이언트 동작
클라이언트는 다음과 같이 한다.
versions중 자신도 지원하는 가장 높은 버전을 선택하는 것이 좋다.- 자신이 사용할 수 있는 방식에 따라
interfaces에서 LMSP 인터페이스 또는 OpenAI 인터페이스를 선택하는 것이 좋다. - 서비스 설명이 선언한 기능만 사용해야 한다. 플래그가 없으면
false를 뜻한다. - 인식하지 못하는 확장 필드는 무시해야 한다.
- 서비스 설명을 영원히 캐시하지 말고, 주기적으로 그리고 요청이 실패했을 때 다시 읽는 것이 좋다.
- 선택한 서비스는 주소가 아니라
service.id로 기억하는 것이 좋다. 주소는 바뀔 수 있기 때문이다.