免费大模型 API 怎么调,坑在哪
我把智谱 8 个免费模型逐个真调了一遍:glm-4-flashx 名字带 flash 但报余额不足,glm-4.7-flash 十次里六次被限流,glm-4.5-flash 调通了却返回空——是 max_tokens 被思考过程吃光了。还测出限流是按模型算不按账号,报错信息会骗你。附最小可跑代码和复现脚本。
我自己的项目里一直挂着免费大模型 API 做兜底。前几天为了另一件事去调智谱的免费模型,随手多试了几个,结果发现好几处跟公开说法对不上——有的模型名字带 flash 但根本不免费,有的调通了却返回空,有的十次里有六次直接被限流。
干脆花了一下午,把它家的免费模型挨个真调了一遍,把额度、限流、返回格式、报错全记下来。
这篇是调用手册,不是评测。下面所有数字都是 2026 年 8 月 10 日实测出来的,脚本我贴在文末,你可以自己跑一遍复现。
先说清楚范围:我手上只有智谱一家的可用 key,所以只有它是真调的。另外两家的状态也顺手记了,在文末。别家我没测,不替它们打包票。

先看哪些是真的免费
一上来就有个坑:智谱的 /models 接口列不出免费模型。
curl https://open.bigmodel.cn/api/paas/v4/models \
-H "Authorization: Bearer $KEY"
返回的是 glm-4.5、glm-4.6、glm-4.7、glm-5、glm-5-turbo、glm-5.1、glm-5.2 这一串,全是付费主力,一个 flash 都没有。你要是照着这个接口找免费模型,会一无所获。免费模型的 ID 只能从文档里翻。
我把公开资料里提到过的免费模型 ID 全试了一遍,实测结果:
| 模型 ID | 能不能调 | 耗时 | 说明 |
|---|---|---|---|
glm-4-flash | ✓ | 0.7–1.7s | 最稳,日常主力 |
glm-4-flash-250414 | ✓ | 0.7s | 同上,带日期的版本号 |
glm-4-flashx | ✗ | — | 报余额不足,不免费 |
glm-4.5-flash | ✓ | 18–42s | 旧 ID 仍能调通 |
glm-4.7-flash | ⚠ | 7–10s | 能用,但十次六次被限 |
glm-z1-flash | ✓ | 5.5–6s | 推理模型 |
glm-4v-flash | ✓ | 1.1s | 图像理解 |
glm-4.1v-thinking-flash | ✓ | 1.9s | 图像推理 |
glm-4-flashx 这个要单独拎出来说。名字长得跟 flash 一模一样,很多汇总文章把它列进免费清单,实际调它返回的是:
{"error":{"code":"1113","message":"余额不足或无可用资源包,请充值。"}}
多一个 x,就要钱。我账户里没余额,所以它一次都没跑通。
最坑的一个:调通了,但返回是空的
这个坑我们自己的项目里踩过,而且踩了之后得出了一个错误结论,一直挂到今天。
现象是这样:调 glm-4.5-flash 或 glm-4.7-flash,HTTP 200,不报错,但 choices[0].message.content 是空字符串。当时的结论是"这个思考模型有问题,别用,换 glm-4-flash"。
这次挨个试才发现,模型没问题,是我们自己给的参数不对。
看这组对照,同一个模型、同一个问题,只改 max_tokens:
| max_tokens | content 长度 | reasoning 长度 | finish_reason | 补全 tokens |
|---|---|---|---|---|
| 200 | 0 | 403 | length | 200 |
| 800 | 31 | 369 | stop | 215 |
| 3000 | 44 | 355 | stop | 210 |
看懂了吗——max_tokens 是"思考 + 回答"的总预算,不是只给回答的。
这类思考模型会先在肚子里推理一遍,推理本身就吃掉两三百个 token。你给 200,它光思考就用光了,轮到写答案时预算已经归零,于是 content 返回空,finish_reason 是 length(意思是"被长度截断了"),而不是 stop。
判据很清楚:content 为空 + finish_reason 是 length,就是 max_tokens 给少了,不是模型坏了。
glm-4.7-flash 的思考更长,我实测它的 reasoning_content 能到 1300–1600 个字符,所以给它至少留 1500,才稳定能拿到答案。

顺带说,这三个思考模型的返回格式还不一样,写代码的得分开处理:
glm-4.5-flash、glm-4.7-flash:思考过程放在message.reasoning_content字段,content里是干净的答案。glm-z1-flash:思考过程直接混在content里,用<think>标签包着。我实测拿到的 content 长这样:
<think>
嗯,用户让我用一句话说明什么是API。首先,我需要确认...
</think>
API 是不同软件之间约定好的接口...
你要是直接把 content 丢给用户看,就会把它的内心戏一起显示出去。得自己按 </think> 切一刀取后半段。
第二个坑:限流是按模型算的,报错信息会骗你
前几天我调生图接口,并发发了 6 个请求,4 个立刻返回 429,错误信息写着:
您的账户已达到速率限制,请您控制请求频率
"您的账户"——看到这句我当时的理解是,整个账号被限速了,那这会儿别的模型也别想调。
这次专门做了个对照实验,同一个账号、同一个时间段,两种模型各并发 6 个请求:
| 并发 6 个 | 成功 | 耗时 |
|---|---|---|
glm-4-flash(文本) | 6 / 6 | 2.4s |
cogview-3-flash(生图) | 1 / 6 | 8.3s |
文本全过,生图只过一个。同一个账号,同一时刻。
所以那句"您的账户已达到速率限制"是误导——限的是那个模型,不是你的账号。生图模型的并发额度紧得多,文本模型宽松得多。
这个区别很实际:如果你的程序里图文混着调,生图被限的时候,文本任务完全可以继续跑,不用整个流程停下来等。
还有个相关的发现,响应头里没有任何限流字段。我把返回的 header 全翻了一遍,没有 X-RateLimit-Remaining 这类东西。也就是说你无法提前知道自己还剩多少配额,只能撞上 429 才知道。程序里必须自己写重试。
glm-4.7-flash 单独说:能用,但你得接受它十次里有六次不理你
这个模型公开资料给的评价很高——30B、200K 上下文、免费。实际调用体验是另一回事。
我按 2 秒间隔连续调了 10 次,max_tokens 给足 1500:
#1 ✗ 1305 该模型当前访问量过大
#2 ✗ 1305
#3 ✓ 9158ms content=33 reasoning=1329
#4 ✓ 9734ms content=44 reasoning=1224
#5 ✗ 1305
#6 ✗ 1305
#7 ✗ 1305
#8 ✓ 7301ms content=44 reasoning=988
#9 ✗ 1305
#10 ✓ 9695ms content=69 reasoning=1346
成功 4 次,被限 6 次,成功时平均 8.9 秒。
错误码 1305 跟前面那个 1302 不是一回事:1302 是"你调太快了",1305 是"这个模型现在大家都在抢"。后者跟你的调用频率无关,是模型侧的公共资源不够——所以你降低频率也没用,只能重试。
我的判断是:它不适合放在任何需要即时响应的地方。九秒的响应时间加上四成的成功率,用户在前面等着的场景直接排除。它适合的是离线批处理——夜里跑个任务,失败就重试,反正不赶时间,正好白嫖它的 200K 上下文。
要是你想稳定拿到结果,重试逻辑得这么写(1305 要退避重试,不是直接失败):
async function callWithRetry(model, messages, maxTokens = 1500) {
for (let i = 0; i < 6; i++) {
const r = await fetch('https://open.bigmodel.cn/api/paas/v4/chat/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ZHIPU_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ model, messages, max_tokens: maxTokens }),
})
const j = await r.json()
// 1305 模型侧繁忙 / 1302 自己调太快,都退避重试
if (j.error && (j.error.code == 1305 || j.error.code == 1302)) {
await new Promise((s) => setTimeout(s, 2000 * (i + 1)))
continue
}
if (j.error) throw new Error(`${j.error.code} ${j.error.message}`)
const msg = j.choices[0].message
// 空 content 一般是 max_tokens 不够,翻倍再来一次
if (!msg.content?.trim() && j.choices[0].finish_reason === 'length') {
maxTokens *= 2
continue
}
return msg.content
}
throw new Error('重试用尽')
}
最小可跑的调用
免费模型和付费的是同一个接口,换个 model 就行。base URL 是 https://open.bigmodel.cn/api/paas/v4。
curl 版本,复制就能跑:
curl https://open.bigmodel.cn/api/paas/v4/chat/completions \
-H "Authorization: Bearer $ZHIPU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-4-flash",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 800
}'
它兼容 OpenAI 的接口格式,所以现成的 OpenAI SDK 改个 base_url 就能直接用,不用换库:
from openai import OpenAI
client = OpenAI(
api_key="你的key",
base_url="https://open.bigmodel.cn/api/paas/v4",
)
r = client.chat.completions.create(
model="glm-4-flash",
messages=[{"role": "user", "content": "你好"}],
max_tokens=800,
)
print(r.choices[0].message.content)
这一点挺省事——你原来接 OpenAI 写的代码,基本不用动逻辑。
我自己会怎么选
按实测结果,我的分工是这样:
日常高频、要快的活,用 glm-4-flash。零点七秒返回,并发 6 个全过,是这一批里唯一能扛住批量的。我自己项目里的兜底就挂它。
要它动脑子的活,用 glm-4.5-flash,别用 4.7。4.5 虽然慢(十几到四十秒),但不像 4.7 那样十次限六次。记得 max_tokens 给足 800 以上。
离线批处理、需要长上下文,才轮到 glm-4.7-flash。配好重试,接受它的脾气。
看图用 glm-4v-flash。一点一秒,免费的图像理解,这个是真香。
别碰 glm-4-flashx。要钱。

另外两家我顺手试的结果
硅基流动:我这个账号余额耗尽之后,调 Kolors 生图返回 {"code":30001,"message":"Sorry, your account balance is insufficient"}。这里有个容易误解的点——很多人以为平台上标着免费的模型不吃余额,实测是账户余额一空,整个 key 就调不动了。
Gemini:gemini-2.5-flash-image 返回 429,错误信息里明确写着 limit: 0——免费层在这个模型上的配额就是零,不是我用超了,是压根没给。它的模型列表里倒是有一长串图像模型(imagen-4.0、gemini-3-pro-image 等等),但免费能不能调是另一回事。
Kimi、DeepSeek、ModelScope 这些我没有可用 key,没测,不写。
你可以自己复现
上面所有结论都来自下面这段脚本,跑一遍大概两分钟。换成你自己的 key 就行:
const KEY = process.env.ZHIPU_API_KEY
const MODELS = ['glm-4-flash', 'glm-4-flash-250414', 'glm-4-flashx',
'glm-4.5-flash', 'glm-4.7-flash', 'glm-z1-flash', 'glm-4v-flash']
for (const model of MODELS) {
const t0 = Date.now()
const r = await fetch('https://open.bigmodel.cn/api/paas/v4/chat/completions', {
method: 'POST',
headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
messages: [{ role: 'user', content: '用一句话说明什么是 API。' }],
max_tokens: 1500,
}),
})
const j = await r.json()
const m = j.choices?.[0]?.message ?? {}
console.log(model.padEnd(24),
j.error ? '✗ ' + j.error.code + ' ' + j.error.message
: `✓ ${Date.now() - t0}ms content=${(m.content || '').length} reasoning=${(m.reasoning_content || '').length}`)
}
平台的免费额度和限流策略改得很勤,我这份数据的保质期大概就是几周。真要上线之前,自己跑一遍最保险——毕竟别人写的清单,包括这一篇,都可能已经过期了。