GLM-4 开源版 API 接入踩坑实录:inference endpoint、access token、model name 三处和云端版完全不一样 [特殊字符]
上周三智谱把 GLM-4 开源版放出来,我当天晚上就拉了权重往本地部署。心想云端 GLM-4 的 API 我已经跑通了,开源版应该改个端口就完事——结果接了两遍,踩了三个坑,折腾到凌晨两点才把 chat completions 跑通。
核心问题就一句话:GLM-4 开源版本地部署的 base_url 路径格式、鉴权机制、model name 字段,和云端版完全是两套逻辑,但官方文档混在一起写,第一次接必踩。这篇把三处差异拆开讲清楚,附完整代码和报错排查。
这篇适合谁
- 已经在用云端 GLM-4 API,准备本地部署开源版的同学
- 用 vLLM / TGI 跑 GLM-4 开源权重,OpenAI 兼容层死活 401 的同学
- 想在 Cursor / Cline 里接自部署 GLM-4 但 model name 不知道怎么填的同学
- 团队有私有化部署需求,需要搞清楚鉴权差异的后端工程师
整体流程
- 搞清楚云端版 vs 开源版的三处核心差异(base_url / 鉴权 / model name)
- 本地部署开源版,启动 inference endpoint
- 用 OpenAI SDK 接入,配置正确的参数
- 验证 streaming 和 function calling 是否正常
- 踩坑排查(附真实报错)
先说结论
| 对比项 | 云端版(open.bigmodel.cn) | 开源版(本地部署) |
|---|---|---|
| base_url | https://open.bigmodel.cn/api/paas/v4/ |
http://localhost:8000/v1/(取决于你的端口) |
| 鉴权方式 | Bearer Token(平台生成的 API Key,据 SDK 源码推断内部走 JWT 刷新,Key 格式为 xxxxxxxx.yyyyyyyy) |
无鉴权 / 自定义 token(vLLM 启动参数指定) |
| model name | glm-4 / glm-4-air 等固定字符串 |
本地权重路径名,如 THUDM/glm-4-9b-chat |
| 流式输出 | stream=True 直接用 |
同,SSE 数据块中 delta.content 为空时需跳过,否则会拿到 None |
| Function Calling | 原生支持 | 取决于推理框架版本,建议使用较新稳定版 vLLM 并在启动时加 --enable-auto-tool-choice |
第一处坑:base_url 路径格式
云端版的 base_url 大家都熟:
base_url = "https://open.bigmodel.cn/api/paas/v4/"
注意末尾有斜杠,路径是 /api/paas/v4/。
开源版用 vLLM 启动后,endpoint 是标准的 OpenAI 兼容格式:
base_url = "http://localhost:8000/v1"
这里没有 /api/paas/ 这层路径。我第一次接的时候下意识写了 http://localhost:8000/api/paas/v4/,直接 404。说实话这个错误挺蠢的,但文档里两种写法混在同一页,扫一眼真的会搞混。
第二处坑:鉴权方式完全不同
云端版的 API Key 看起来是个普通字符串,但底层其实走的是 JWT 机制——你拿到的 Key 格式是 xxxxxxxx.yyyyyyyy,据 SDK 源码推断前半段是 ID、后半段是 Secret,SDK 内部会用它生成带过期时间的 JWT token(官方文档未公开此字段拆分含义,以 SDK 源码为准)。
开源版本地部署?默认完全不需要鉴权。vLLM 启动时如果没加 --api-key 参数,随便传什么都行:
client = OpenAI(
api_key="whatever", # 本地部署随便填
base_url="http://localhost:8000/v1"
)
我第一次把云端的 Key 原封不动贴过来,报了这个错:
openai.AuthenticationError: Error code: 401 - {'error': {'message': 'Incorrect API key provided'}}
当时人傻了——本地服务还能 401?后来发现是我 vLLM 启动时加了 --api-key mytoken123 但忘了改客户端代码里的 key。如果你启动时指定了 api-key,客户端必须传完全一致的字符串,不是云端那套 JWT。
# vLLM 启动命令(指定自定义 token)
# 注意:vllm serve 子命令需要 vLLM 0.4.1+;更早版本请改用:
# python -m vllm.entrypoints.openai.api_server --model THUDM/glm-4-9b-chat --api-key mytoken123
vllm serve THUDM/glm-4-9b-chat --api-key mytoken123
第三处坑:model name 字段格式
这个最坑。云端版 model name 是智谱定义的产品名:
model = "glm-4" # 云端版
开源版的 model name 必须和你加载的权重路径一致:
model = "THUDM/glm-4-9b-chat" # 开源版
如果你写 glm-4,vLLM 会返回:
{"error": {"message": "The model `glm-4` does not exist."}}
报错信息倒是很明确,但问题是——你怎么知道该填什么?答案是看 vLLM 启动日志里的 model_name 字段,或者直接调 /v1/models 接口:
curl http://localhost:8000/v1/models
返回的 JSON 里 id 字段就是你该填的 model name。
graph TD
A[确定部署方式] --> B{云端 or 开源?}
B -->|云端| C[base_url: open.bigmodel.cn/api/paas/v4/]
B -->|开源本地| D[base_url: localhost:8000/v1]
C --> E[鉴权: 平台 API Key - JWT 机制]
D --> F[鉴权: 无 / 自定义 --api-key]
E --> G[model: glm-4]
F --> H[model: THUDM/glm-4-9b-chat]
G --> I[调用成功 ✅]
H --> I
完整的开源版接入代码
把三处差异对齐后,完整代码其实很短:
from openai import OpenAI
client = OpenAI(
api_key="mytoken123",
base_url="http://localhost:8000/v1"
)
然后正常调用:
response = client.chat.completions.create(
model="THUDM/glm-4-9b-chat",
messages=[{"role": "user", "content": "你好"}]
)
流式输出也是标准写法:
stream = client.chat.completions.create(
model="THUDM/glm-4-9b-chat",
messages=[{"role": "user", "content": "写一段快排"}],
stream=True
)
逐块读取:
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
不同场景怎么选
个人开发者 / 快速验证想法:直接用云端 API。glm-4 的云端版注册就能用,免费额度够你跑通原型。本地部署 9B 模型至少要一张 24G 显存的卡,折腾环境的时间够你把功能写完了。
团队生产环境 / 数据不能出网:开源版本地部署。走 vLLM 起服务,前面套一层 Nginx 做负载均衡,鉴权用 --api-key 参数配合内网网关。
多模型混用 / 想同时调 GLM-4 + Claude + GPT:这种场景建议走聚合 API 网关。比如 OpenRouter、ofox.io 这类平台,改一个 base_url 就能切不同模型,不用每个模型单独维护一套鉴权逻辑。对团队来说省的是运维成本不是那几毛钱 token 费。使用前建议在对应平台确认所需 model ID 的实际名称,各平台命名规范不尽相同。
接入 Cursor / Cline 等编辑器:如果是本地部署的开源版,在编辑器设置里填 http://localhost:8000/v1 作为 base_url,model name 填 THUDM/glm-4-9b-chat,API Key 随便填或者填你启动时设的那个。
踩坑记录 / 常见问题 FAQ
Q: 开源版用 zhipuai SDK 能调吗?
不能。zhipuai 这个包是专门对接云端平台的,内部写死了 JWT 签名逻辑和 open.bigmodel.cn 的域名。本地部署只能用 openai SDK 或者裸 HTTP 请求。
Q: vLLM 启动后调 /v1/chat/completions 返回 404?
先确认 vLLM 版本,建议使用较新的稳定版本。另外确认你启动时没加 --disable-frontend-multiprocessing 之类影响路由的参数。
Q: 本地部署的 GLM-4 能用 Function Calling 吗?
能,但有前提:需要使用支持该功能的较新稳定版 vLLM,且启动时加 --enable-auto-tool-choice(该参数在 vLLM 0.4.x 即已引入,具体最低版本要求建议查阅 vLLM 官方 changelog)。我测下来 9B 版本的 tool use 准确率比云端 GLM-4 差一截,毕竟参数量摆在那。复杂的多步 tool calling 建议还是走云端大参数版。
Q: model name 填错了会报什么错?
返回 HTTP 404,body 是 {"error": {"message": "The model 'xxx' does not exist."}}。不是 401 也不是 500,别往鉴权方向排查。
Q: 云端版的 API Key 格式是什么样的?怎么区分?
云端 Key 格式是 xxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyy,中间有个点分隔。如果你的 Key 里没有点,那大概率是你自己设的本地 token,别往云端传。
小结
GLM-4 开源版接入本身不难,难的是文档把两套体系混在一起写。记住三个差异点:base_url 没有 /api/paas/ 这层、鉴权不走 JWT 而是纯字符串匹配、model name 要用 HuggingFace 风格的路径名。搞清楚这三点后,接入本身不复杂。
我目前的做法是本地开发用开源 9B 版本快速迭代(响应快、不花钱),上线前再切到云端大参数版本做质量验证。两套代码唯一的区别就是一个 config 文件里的三个字段,切换成本几乎为零。
更多推荐



所有评论(0)