6.2 API 表面与协议集成

API 表面与协议集成#

这章解决什么问题#

这一章解决的是“调用方到底通过哪些表面进入 SGLang,以及这些表面怎样回到同一条 runtime path”。如果不单独讲这一层,容易把 OpenAI-compatible API、native APIs、offline engine 和 frontend language 当成互相独立的产品,而不是同一套系统暴露出的不同入口。

对工程读者来说,这个问题很实际。因为你在排查行为差异、设计接口迁移方案,或者把某条业务流从 OpenAI 托管迁到自托管时,真正关心的不是“这个接口像不像”,而是“它最后落到同一套 runtime 了吗”。

为什么要把协议表面单独拎出来#

从官方 docs 可以看到,SGLang 明确把 OpenAI-compatible APIs、native APIs 和 offline engine 分开写。docs/basic_usage/openai_api.rst 聚合的是 OpenAI-compatible usage;docs/basic_usage/native_api.ipynb 则罗列 /generate/server_info/flush_cache/tokenize/detokenize 等 native endpoints;docs/basic_usage/offline_engine_api.ipynb 则直接讨论不经过 HTTP server 的 inference engine。

这说明协议表面本身就是系统的一层设计,而不是文档编排巧合。SGLang 一方面希望让调用方能平滑迁移到 OpenAI-compatible 表面,另一方面又保留自己的 native surface 和 offline engine path,让内部能力不被单一协议形状限制住。

OpenAI-compatible API 在这套系统里的位置#

OpenAI-compatible API 的价值在于降低迁移成本。官方 openai_api_completions.ipynb 和相关 basic usage 文档都在强调这一点:你可以用接近 OpenAI 的请求格式对接本地模型服务。对于多数应用接入者来说,这是最容易上手的一层。

但从运行时角度看,重要的不是“长得像 OpenAI”,而是它最终怎样落进 http_server.pyTokenizerManager.generate_request(...) 这条路径。也正因为如此,OpenAI-compatible 层更适合作为“协议适配面”来理解,而不是当作独立 runtime。

下面这张图解决的是“不同表面到底怎样收敛到同一条 runtime path”。相比段落说明,它更适合把 OpenAI-compatible、native API、offline engine 和 frontend language 并列出来,再看它们怎样回到共享执行层。

flowchart LR
    A["Frontend language\npython/sglang/lang/api.py"] --> E["Runtime / Engine surface"]
    B["OpenAI-compatible APIs\ndocs/basic_usage/openai_api.rst"] --> F["http_server.py routes"]
    C["Native APIs\ndocs/basic_usage/native_api.ipynb"] --> F
    D["Offline Engine\ndocs/basic_usage/offline_engine_api.ipynb"] --> E
    E --> G["TokenizerManager"]
    F --> G
    G --> H["Scheduler -> DetokenizerManager"]

从这张图里,读者应该看懂两件事:第一,OpenAI-compatible 和 native API 的差别主要在协议表面;第二,offline engine 与 frontend language 更像“绕过 HTTP 的程序内部入口”。真正共享的那一层,是进入 runtime 之后的 manager 链路。

native API 和 offline engine 为什么仍然重要#

docs/basic_usage/native_api.ipynb 给出的是 SGLang 原生 server 接口,它包括 /generate/get_model_info/server_info/flush_cache/encode/classify 等原生 endpoints。这里的意义在于:当你需要更直接地触达 runtime 能力时,不必经过 OpenAI-compatible 抽象。

docs/basic_usage/offline_engine_api.ipynb 又进一步说明,SGLang 提供 “direct inference engine without the need for an HTTP server”。这条路径特别适合离线 batch inference 或在 Python 里自建 custom server。换句话说,SGLang 不是只有“起一个 HTTP 服务”这一个使用姿势,它还有更贴近程序内部的 engine surface。

这些表面最终怎样与 runtime 对齐#

虽然三类表面看起来不同,但从前面章节建立的主线看,它们都在朝同一个方向收敛:要么直接进入 runtime endpoint / engine,要么通过 HTTP server 进入 TokenizerManager -> Scheduler -> DetokenizerManager 链路。区别主要在于调用协议、封装层次和附带约束,而不是底层目标完全不同。

这也是为什么本章放在结构化生成之后讲更合理。结构化生成说明了“输出怎样被约束”,而 API / protocol integration 说明“这些约束与请求怎样被送进来”。两者结合起来,你才能同时看清“输入表面”和“输出形状”。

本章对应哪些代码路径#

这一章最重要的锚点包括 docs/basic_usage/openai_api.rstdocs/basic_usage/native_api.ipynbdocs/basic_usage/offline_engine_api.ipynbpython/sglang/launch_server.pypython/sglang/srt/entrypoints/http_server.py 以及 python/sglang/lang/api.py

要继续追具体入口,最直接的阅读顺序是:先看 OpenAI-compatible 和 native / offline 文档分别提供什么接口,再回到 launch_server.pyhttp_server.pylang/api.py,确认这些外部表面最终怎样映射到 runtime。这样读下来,协议表面和内部主链路之间的关系会更稳定。

小结#

这一章真正想说明的是:SGLang 对外并不是“只有一种 API”。它同时提供 OpenAI-compatible surface、native server APIs 和 offline engine path,而这些表面之所以能共存,是因为它们最终都能被折叠回一套共享 runtime。理解了这一点,后面无论你从协议迁移、服务封装还是内部集成角度看 SGLang,都会更清楚它为什么不是单一路径产品。