自托管推理服务的 API
自托管推理服务的 API 文档自动生成:基于 OpenAPI 与 Swagger 的实现
根据中国信通院《人工智能发展报告(2024)》统计,国内已有超过 **62%** 的 AI 企业将模型推理部署在自托管或混合云环境中,但其中仅有 **不到 18%** 的团队为推理服务生成了结构化的 API 文档。这意味着绝大多数自托管推理服务处于“黑盒”状态——调用方依赖口头沟通或零散的 README 文件来拼…
根据中国信通院《人工智能发展报告(2024)》统计,国内已有超过 62% 的 AI 企业将模型推理部署在自托管或混合云环境中,但其中仅有 不到 18% 的团队为推理服务生成了结构化的 API 文档。这意味着绝大多数自托管推理服务处于“黑盒”状态——调用方依赖口头沟通或零散的 README 文件来拼接请求格式。当模型版本迭代加速、微调服务数量从个位数增长到上百个时,缺乏标准化文档直接导致集成效率下降 40% 以上,错误重试率翻倍。本文从 OpenAPI 3.1 规范出发,结合 Swagger UI 与 vLLM、Replicate 等主流框架的集成实践,提供一套可在 30 分钟内 落地到任何自托管推理服务的文档生成方案。
为什么 OpenAPI 是自托管推理服务的“必选项”
OpenAPI 规范(原 Swagger 规范)是目前全球使用最广泛的 RESTful API 描述标准。根据 SmartBear 2024 年开发者调查,78% 的 API 开发者优先使用 OpenAPI 3.x 版本进行接口定义,而国内云原生社区在 2023-2024 年间采用率也增长了 34%【SmartBear, 2024, State of API Report】。
对于自托管推理服务,OpenAPI 的价值体现在三个层面:
- 机器可读:客户端 SDK 可通过 OpenAPI 文件自动生成类型安全的请求代码,避免手动拼写 JSON 时的字段错误。
- 文档即契约:OpenAPI 文件可被 Swagger UI、Redoc、Scalar 等渲染工具直接解析,生成交互式 API 文档,无需额外维护 HTML 页面。
- 兼容性:主流推理框架 vLLM、TGI、Ollama 的 REST API 均与 OpenAI 兼容格式对齐,而 OpenAI 的 API 规范本身就是 OpenAPI 的超集。
一个典型的反例是:某头部大模型创业公司在 2024 年 Q1 因未提供 OpenAPI 文档,导致三家合作伙伴的集成开发周期从预期 3 天延长至 11 天,最终不得不紧急补写规范文件。
从零构建 OpenAPI 规范:核心字段与推理场景适配
定义基础信息与服务器地址
OpenAPI 3.1 文件以 JSON 或 YAML 格式编写,根对象必须包含 openapi、info、paths 三个字段。对于推理服务,servers 字段需明确指定部署地址,例如 https://api.yourmodel.com/v1。
openapi: "3.1.0"
info:
title: "LLM 推理服务 API"
version: "1.0.0"
description: "基于 vLLM 部署的 Llama 3.1 70B 推理接口"
servers:
- url: https://api.example.com/v1
description: "生产环境"
适配聊天补全(Chat Completions)端点
推理服务的核心路径通常是 /v1/chat/completions。OpenAPI 需要精确描述请求体中的 model、messages、temperature、max_tokens 等参数。关键点在于:messages 数组的 content 字段需声明为 string 或 array(支持多模态输入时),role 字段枚举值为 system、user、assistant、tool。
定义请求体时,建议使用 $ref 引用外部 schema 文件,避免单个 YAML 文件过于臃肿。例如将 ChatCompletionRequest 定义为独立组件:
components:
schemas:
ChatCompletionRequest:
type: object
required:
- model
- messages
properties:
model:
type: string
example: "llama-3.1-70b"
messages:
type: array
items:
$ref: '#/components/schemas/Message'
temperature:
type: number
default: 0.7
max_tokens:
type: integer
default: 2048
定义流式响应(Server-Sent Events)
推理服务普遍支持流式输出,OpenAPI 3.1 通过 responses 中的 content 字段声明 text/event-stream 类型。需要注意的是,OpenAPI 规范本身不直接描述 SSE 事件流的结构,但可以在 description 中注明事件格式,或使用 oneOf 组合非流式与流式响应。
responses:
'200':
description: "成功响应"
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompletionResponse'
text/event-stream:
schema:
type: string
description: "SSE 事件流,每行格式为 data: {...}"
使用 Swagger UI 生成交互式文档
容器化部署 Swagger UI
Swagger UI 是一个纯前端项目,官方提供 Docker 镜像 swaggerapi/swagger-ui。部署命令只需一行:
docker run -p 8080:8080 -e SWAGGER_JSON=/app/openapi.yaml -v ./openapi.yaml:/app/openapi.yaml swaggerapi/swagger-ui
访问 http://localhost:8080 即可看到交互式文档页面。用户可以直接在页面上填写 messages 数组、调整 temperature 参数,并点击“Try it out”发送真实请求到推理服务。这种方式比 Postman 集合更轻量,且文档与代码同步更新。
集成到 vLLM 服务
vLLM 从 v0.4.0 版本开始内置了 OpenAPI 文档生成功能。启动服务时添加 --api-key 参数,访问 /docs 端点即可获得 Swagger UI 界面。如果使用自定义路由(例如添加了 LoRA 适配器切换端点),vLLM 的自动生成可能无法覆盖,此时需要手动编写补充的 OpenAPI 文件,并通过 Nginx 反向代理将 /docs 指向 Swagger UI 容器。
对于使用 Hostinger 主机 部署的低成本推理节点,建议将 OpenAPI 文件与 Swagger UI 容器一同打包到 Docker Compose 中,确保每次服务重启后文档自动可用。
自动化生成与 CI/CD 集成
从代码注释生成 OpenAPI
对于使用 FastAPI、Flask 或 Express 编写的推理服务包装器,可以利用框架自带的 OpenAPI 生成能力。FastAPI 基于 Pydantic 模型自动生成 OpenAPI 3.1 规范,只需在路由函数上添加类型注解和 docstring。例如:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title="推理服务 API", version="1.0.0")
class ChatRequest(BaseModel):
model: str
messages: list
temperature: float = 0.7
@app.post("/v1/chat/completions")
async def chat_completion(req: ChatRequest):
"""调用底层推理引擎生成回复"""
# 实际推理逻辑
return {"choices": [...]}
FastAPI 会在 /docs 和 /redoc 端点自动生成 Swagger UI 和 ReDoc 文档,且支持直接在页面上测试请求。
在 CI 管道中验证 OpenAPI 文件
将 OpenAPI 文件纳入版本控制后,可以在 CI 流程中添加验证步骤。使用 swagger-cli validate 或 redocly lint 命令检查规范的正确性。例如 GitHub Actions 中:
- name: Validate OpenAPI spec
run: npx @redocly/cli lint openapi.yaml
验证通过后再部署到生产环境,避免因字段类型错误导致客户端 SDK 生成失败。
多框架适配:vLLM、Replicate、Modal 的文档方案差异
| 框架 | 原生 OpenAPI 支持 | 自定义端点覆盖 | 推荐文档工具 |
|---|---|---|---|
| vLLM | 内置 /docs(v0.4.0+) | 需手动补充 LoRA 端点 | Swagger UI + 自定义 YAML |
| Replicate | 不提供 | 完全依赖用户编写 | Redoc + 静态站点 |
| Modal | 不提供 | 依赖 FastAPI 自动生成 | FastAPI 内置 /docs |
| RunPod | 不提供 | 需在 worker 中嵌入 | Swagger UI + Docker Compose |
对于 Replicate 和 Modal 这类 Serverless 平台,推理服务的 API 网关由平台控制,用户无法直接修改路由。此时建议在应用层包装一个 FastAPI 中间件,将平台请求转换为标准 OpenAI 格式,再通过中间件暴露 OpenAPI 文档。RunPod 的 worker 模式则更灵活,可以在 worker 内部启动一个 FastAPI 服务,直接生成文档。
文档安全与访问控制
限制文档访问范围
生产环境的 Swagger UI 不应暴露给公网。常见的做法包括:
- 使用 Nginx 的
auth_basic模块添加 HTTP 基本认证 - 通过反向代理限制 IP 白名单,仅允许内网或 VPN 地址访问
/docs路径 - 在 OpenAPI 文件中设置
security字段,要求 API Key 认证
security:
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
版本化文档管理
当推理模型频繁更新时,建议为每个模型版本维护独立的 OpenAPI 文件,并在服务器路径中体现版本号,例如 /v1/models/llama-3.1-70b/docs。使用 Git 标签管理 OpenAPI 文件的版本,确保回滚时文档与模型版本一一对应。
FAQ
Q1:OpenAPI 文件与 OpenAI 的 API 规范有什么区别?
OpenAPI 是通用规范,OpenAI 的 API 是基于 OpenAPI 3.0 的具体实现。二者在 messages 结构、stream 参数等方面完全兼容,但 OpenAI 额外定义了 tool_calls、logprobs 等扩展字段。自托管服务只需实现 OpenAI 兼容接口的子集即可,无需完全复制所有字段。
Q2:Swagger UI 是否支持 SSE 流式响应的测试?
Swagger UI 原生不支持 SSE 流式响应预览。测试流式输出时,建议使用 curl 命令或 Postman 的 SSE 插件。替代方案是使用 Scalar 工具,它从 2024 年版本开始支持 SSE 事件的实时渲染,且体积比 Swagger UI 小 60%。
Q3:如果推理服务使用 gRPC 而非 REST,如何生成 OpenAPI 文档?
gRPC 服务可以通过 grpc-gateway 工具生成 REST 代理,该代理自动输出 OpenAPI 2.0 规范。随后使用 swagger2openapi 工具转换为 3.1 版本。整个过程需额外增加 2-3 个步骤,但能保持 gRPC 的高性能与 REST 的文档兼容性。
参考资料
- SmartBear, 2024, State of API Report
- 中国信通院, 2024, 人工智能发展报告
- OpenAPI Initiative, 2023, OpenAPI Specification v3.1.0
- FastAPI 官方文档, 2024, FastAPI Path Operation Config
- vLLM Project, 2024, vLLM API Documentation