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
api.moonshot.ai。低于 2,048 时,整个预算都被推理耗尽——每个 token 照常付费,拿到手的却是空字符串。完整数字见下表。| max_completion_tokens | finish_reason | 推理 token | 返回内容 | 按输出计费 |
|---|---|---|---|---|
| 64 | length | 61 | 什么都没有 | 61 |
| 128 | length | 125 | 什么都没有 | 125 |
| 256 | length | 253 | 什么都没有 | 253 |
| 512 | length | 509 | 什么都没有 | 509 |
| 1024 | length | 1021 | 什么都没有 | 1021 |
| 2048 | stop | 1308 | 1,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 200;max_completion_tokens: 2000000——两倍于上下文窗口——同样返回 200。全套真实错误响应体见错误速查。