REST API 基础

REST API 设计基础

本文档介绍 REST API 设计原则和 LLM 推理 API 的特殊需求,为理解 Dynamo HTTP 层奠定基础。


1. REST API 设计原则

1.1 核心原则

REST(Representational State Transfer)是 Web API 设计的主流范式:

原则说明示例
资源导向URL 表示资源/v1/models/v1/chat/completions
无状态每个请求独立不依赖服务端会话
统一接口标准 HTTP 方法GET、POST、PUT、DELETE
分层系统客户端无感知中间层负载均衡、网关

1.2 HTTP 方法语义

graph LR subgraph methods["HTTP 方法"] G["GET"] P["POST"] U["PUT"] D["DELETE"] end subgraph semantics["语义"] G --> GS["读取资源"] P --> PS["创建资源"] U --> US["更新资源"] D --> DS["删除资源"] end
方法幂等性安全性典型用途
GET查询资源
POST创建资源
PUT全量更新
PATCH部分更新
DELETE删除资源

2. LLM 推理 API 的特殊挑战

2.1 流式响应需求

传统 HTTP 请求-响应模型:

Client ──Request──> Server
Client <──Response── Server (一次性返回)

LLM 流式响应模型:

Client ──Request──> Server
Client <──Token 1── Server
Client <──Token 2── Server
Client <──Token 3── Server
...
Client <──[DONE]─── Server

2.2 时序对比

sequenceDiagram participant C as Client participant S as Server Note over C,S: 传统模式 C->>S: Request Note over S: 处理完成后响应 S-->>C: Complete Response Note over C,S: 流式模式 C->>S: Request loop Token 生成 Note over S: 生成一个 Token S-->>C: Token end S-->>C: [DONE]

2.3 特殊需求

需求说明解决方案
长连接Token 生成可能持续数分钟适当的超时配置
断开检测客户端断开需取消生成服务端主动检测
高并发GPU 资源有限请求排队、负载均衡
资源管理及时释放计算资源RAII 模式

3. 流式响应技术选型

3.1 技术对比

技术方向协议特点适用场景
SSE单向HTTP/1.1自动重连、文本LLM Token 流 ✓
WebSocket双向升级协议二进制支持聊天应用
HTTP/2 Push单向HTTP/2需要 HTTP/2静态资源
Long Polling单向HTTP/1.1兼容性好遗留系统

3.2 为什么选择 SSE

graph TB subgraph sse["SSE 优势"] A["HTTP/1.1 兼容"] B["自动重连"] C["简单协议"] D["浏览器原生支持"] end subgraph llm["LLM 需求"] E["服务端推送"] F["文本数据"] G["单向流"] H["易于调试"] end A --> E C --> F B --> G D --> H

3.3 SSE 协议格式

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

data: {"id":"chatcmpl-1","choices":[{"delta":{"content":"Hello"}}]}

data: {"id":"chatcmpl-1","choices":[{"delta":{"content":" world"}}]}

data: [DONE]

SSE 事件格式:

字段说明
data:数据内容(必需)
event:事件类型(可选)
id:事件 ID(可选)
retry:重连间隔(可选)

4. OpenAI API 规范

4.1 为什么兼容 OpenAI

OpenAI API 已成为 LLM 服务的事实标准:

  • 广泛采用:大量客户端库和应用支持
  • 文档完善:详细的 API 文档
  • 生态丰富:LangChain、LlamaIndex 等框架原生支持
  • 易于迁移:用户可以无缝切换

4.2 核心端点

端点方法说明
/v1/chat/completionsPOST聊天完成(主要端点)
/v1/completionsPOST文本完成(Legacy)
/v1/modelsGET列出可用模型

4.3 请求格式

{
  "model": "llama-3-70b",
  "messages": [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello!"}
  ],
  "stream": true,
  "max_tokens": 256,
  "temperature": 0.7
}

4.4 响应格式

非流式响应

{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1694268190,
  "model": "llama-3-70b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! How can I help you today?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 10,
    "completion_tokens": 8,
    "total_tokens": 18
  }
}

流式响应(SSE)

data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"llama-3-70b","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"llama-3-70b","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"llama-3-70b","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}

data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"llama-3-70b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

4.5 消息角色

角色说明
system系统指令,定义助手行为
user用户输入
assistant助手回复
tool工具调用结果

5. 请求参数详解

5.1 采样参数

参数类型说明默认值
temperaturefloat控制随机性,0-21.0
top_pfloat核采样概率1.0
frequency_penaltyfloat频率惩罚0
presence_penaltyfloat存在惩罚0

5.2 生成控制

参数类型说明
max_tokensint最大生成 Token 数
stoparray停止词列表
nint生成候选数量

5.3 参数效果

graph LR subgraph temp["Temperature 效果"] T0["0.0 - 确定性"] T1["0.7 - 平衡"] T2["2.0 - 高随机"] end subgraph output["输出特征"] T0 --> O0["总是相同输出"] T1 --> O1["多样但合理"] T2 --> O2["创意但可能离题"] end

6. 错误处理

6.1 HTTP 状态码

状态码说明示例场景
200成功正常响应
400请求错误参数格式错误
401未授权API Key 无效
404未找到模型不存在
429限流请求过多
500服务器错误内部异常
503服务不可用模型未就绪

6.2 错误响应格式

{
  "error": {
    "message": "Model 'unknown-model' not found",
    "type": "invalid_request_error",
    "code": "model_not_found"
  }
}

7. 客户端使用示例

7.1 Python(openai 库)

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="not-needed"
)

# 非流式
response = client.chat.completions.create(
    model="llama-3-70b",
    messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)

# 流式
stream = client.chat.completions.create(
    model="llama-3-70b",
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

7.2 cURL

# 非流式
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3-70b",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

# 流式
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3-70b",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'

总结

LLM HTTP API 的设计要点:

  1. REST 原则:资源导向、无状态、统一接口
  2. 流式响应:SSE 技术支持 Token 级流式输出
  3. OpenAI 兼容:降低用户迁移成本
  4. 错误处理:标准 HTTP 状态码和结构化错误信息

这些基础知识是理解 Dynamo HTTP 服务层实现的前提。


参考资料