Pass stream: true for SSE. Kimi puts usage inside the terminal choices[0] item next to finish_reason even when stream_options.include_usage was not requested.
json
{
"model": "k3",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 128,
"stream": true,
"stream_options": {"include_usage": true}
}- The terminal choice frame contains
finish_reasonandchoices[0].usage. It always arrives. - Only with
include_usage: truedoes a separate top-level frame withchoices: []andusagefollow it. - These are the same statistics. A client must not add them together.
Why usage must not be counted twice
Kimi through GUARD API
stream: trueResponse deltas
delta.contentFinal choiceAlways present
finish_reason: "stop"choices[0].usageAdditional frameinclude_usage: true
choices: []usageThe same statisticsCount once
12 + 8 = 20End of stream
data: [DONE]text
data: {"choices":[{"finish_reason":"stop","usage":{"prompt_tokens":12,"completion_tokens":8,"total_tokens":20}}]}
data: {"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":8,"total_tokens":20}}
data: [DONE]