kimik3.io/报错/空响应

Kimi K3 为什么返回空响应

调用返回 HTTP 200,content 是空字符串,账单却一分不少。原因就在下面——2026-07-16,我们用六组预算逐一复现。

一句话答案:你的 max_completion_tokens 设得太低。K3 回答之前一定先推理,而推理和回答共用同一份 token 预算。上限压得比 K3 想思考的量还低,思考就会把预算整个吃光——content 一个字都轮不到。你拿到的是 finish_reason: "length"、一个空字符串,外加每个推理 token 的账单。解决办法:调高 max_completion_tokens,或者干脆让它保持 131,072 的默认值。

2026-07-16 实测于 api.moonshot.ai,模型 kimi-k3——测量方法

六组实测

我们只问 K3 一个短问题——“Explain why the sky is blue”——换六组预算各跑一次,其余什么都不改:

预算给多少,推理就吃多少

每次运行的输出 token · 只有 2,048 那组返回了回答 · 实测于 2026-07-16

0 512 1,024 1,536 2,048 预算 64——61 个推理 token,content 为空 预算 128——125 个推理 token,content 为空 预算 256——253 个推理 token,content 为空 预算 512——509 个推理 token,content 为空 预算 1024——1021 个推理 token,content 为空 预算 2048——1308 个推理 token 预算 2048——740 个回答 token:终于有 content 了 61 · 空 125 · 空 253 · 空 509 · 空 1,021 · 空 回答 ✓ 64 128 256 512 1024 2048 max_completion_tokens
每组预算各跑一次,接口为 api.moonshot.ai。低于 2,048 时,整个预算都被推理耗尽——每个 token 照常付费,拿到手的却是空字符串。完整数字见下表。
每组预算各跑一次,kimi-k3,2026-07-16。
max_completion_tokens finish_reason 推理 token 返回内容 按输出计费
64length61什么都没有61
128length125什么都没有125
256length253什么都没有253
512length509什么都没有509
1024length1021什么都没有1021
2048stop13081,954 个字符2048

规律一眼可见:预算低于 2048 的每一组,推理消耗都逼到离上限不足三个 token,回答一个字都没开始。最后一行揭示了原因:就这么一个短问题,K3 在动笔之前花了 1,308 个 token 思考。上限设在这个数以下,等于付了全款、拿了张白纸。

还要注意,这个失败是静默的。不报错、不警告——HTTP 200,响应体格式完好,只是 content 恰好是 ""。如果你的代码写的是 response.choices[0].message.content.strip() 然后就往下走,这个坑会跟着你一起上线。

为什么会这样

在大多数 API 上,token 上限限的是回答。在 K3 上,它限的是思考加回答,而且思考先花钱。

K3 的推理没有开关——它不是一个可以打开的模式,而是这个模型本身的工作方式。每个响应都带 reasoning_content 字段,其中每个 token 都按 $15.00 / 百万 token 的输出价计费,和回答一模一样。所以你设的预算,会在回答的第一个字符出现之前先被思考花掉一截。

这也让「推理预算陷阱」专坑迁移过来的代码。在别家 API 上运行良好的写法——那里 max_tokens: 512 的意思是「给我个短回答」——到这里含义完全变了:「最多思考 512 个 token 就停,不管有没有说出一个字。」

怎么修

max_completion_tokens 保持 131,072 的默认值,除非你有非改不可的具体理由。K3 说完自然会停;这个上限是安全阀,不是长度控制。

如果你确实要控制开销,预算就得按推理回答来给——并且用断言盯住失败特征,别轻信响应:

choice = response.choices[0]
if choice.finish_reason == "length" and not choice.message.content:
    raise RuntimeError(
        f"Reasoning consumed the whole budget "
        f"({response.usage.completion_tokens_details.reasoning_tokens} reasoning tokens). "
        f"Raise max_completion_tokens."
    )

如果你真正想要的是一个短回答,在提示词里直接要。别拿 token 上限去凑——在 K3 上它控制的是模型能想多久,不是能说多长。

余量留多少?

我们在三条提示词上实测到推理占总输出 token 的 43–77%,而上面那个短问题单独就花了 1,308 个 token。推理最多会用掉多少,我们没有摸清,也不打算拿三个数据点编出一条规则。老实的建议是:默认值的存在自有道理;真要设上限,就设成你预估回答长度的好几倍。这对账单意味着什么,见推理成本拆解

同一个 bug 的流式版本

流式输出同样会中招,而且看上去更糟——流直接结束,从头到尾没吐出一个 content delta。在一条极简提示词、128 token 上限下的五次流式实测里,有三次一个 content token 都没出现。推理 delta 照常到达,流随即关闭,只盯着 delta.content 的消费端看到的就是一个毫无解释的空结果。

如果你在用流式输出,记得看最后一个 chunk 的 finish_reason,并传 stream_options: {"include_usage": true},这样才能看到你被扣了多少推理 token。细节见 API 指南

K3 还有两种不报错的失败方式,都实测过:reasoning_effort: "low" 在只支持 max 的情况下被静默接受,返回 HTTP 200max_completion_tokens: 2000000——两倍于上下文窗口——同样返回 200。全套真实错误响应体见错误速查

自己跑一遍

本页每个数字都能在一分钟左右复现。EvoLink 在 OpenAI 兼容接口上承载 kimi-k3——注册即送 10 个免费额度。

获取 EvoLink API key