通用协议规则
- 规范性
- 草案 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。
幂等键的作用域是客户端和接口。它应是不超过 255 个字符的唯一值,例如 ULID 或 UUID。服务应至少保存幂等键 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 | 否 | 任务已经 succeeded 或 failed。 |
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。
健康接口只返回运行状态,不得返回模型路径、提示词、访问令牌等敏感信息。