Reasoning models

The public chat models reason by default. Read the reasoning, control its effort, turn it off, and avoid an empty answer.

The public chat models on Munito AI, such as qwen/qwen3.8-27b and zai-org/glm-5.3-flash, reason before they answer by default. google/gemma-4-12b reasons only when a request turns its reasoning on. The API returns the reasoning in its own field, apart from the answer. Reasoning tokens are output tokens: they count in the output usage, and you pay the output price for them.

The OpenAI SDK uses the base URL https://api.munito.ai/inference/v1, and the Anthropic SDK uses https://api.munito.ai/inference. Both read the key from MUNITO_API_KEY.

Effort levels and the off switch

Modelreasoning_effortTurn reasoning off
qwen/qwen3.8-27blow, medium, xhighreasoning_effort: "none", or chat_template_kwargs: {"enable_thinking": false}
zai-org/glm-5.3-flashlow, high, maxNot available. reasoning_effort: "none" runs as low.
deepseek-ai/deepseek-v4-flashlow, high, maxreasoning_effort: "none", or chat_template_kwargs: {"thinking": false}
deepseek-ai/deepseek-v4.1-flash-1017low, high, maxreasoning_effort: "none", or chat_template_kwargs: {"enable_thinking": false}
aleph-alpha/kolibri-1none, low, medium, highreasoning_effort: "none", or chat_template_kwargs: {"enable_thinking": false}
google/gemma-4-12b-Off by default. chat_template_kwargs: {"enable_thinking": true} turns it on.

A level that a model does not list moves to the nearest level that it lists. On a tie, it moves to the lower level. For example, high on qwen/qwen3.8-27b runs as medium. none turns reasoning off with the switch of the model. A model that always reasons runs its lowest level instead. none with a switch that the same request turns on returns 400, and so does a value that is not an effort level:

{
  "error": {
    "message": "'reasoning_effort' is not supported: choose one of: low, medium, xhigh",
    "type": "invalid_request_error",
    "param": "reasoning_effort",
    "code": null
  }
}

A chat_template_kwargs option that the model does not list returns 400 with 'chat_template_kwargs' is not supported: unsupported template option or value.

Read the reasoning

pip install openai
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
response = client.chat.completions.create(
    model="zai-org/glm-5.3-flash",
    messages=[{"role": "user", "content": "A train leaves at 09:40 and arrives at 13:15. How long is the trip?"}],
    reasoning_effort="low",
    max_tokens=2048,
)
message = response.choices[0].message
print("Reasoning:", (message.model_extra or {}).get("reasoning"))
print("Answer:", message.content)
print("Output tokens:", response.usage.completion_tokens)
APIWhere the reasoning isReasoning tokens
Chat Completionsmessage.reasoning, and delta.reasoning in a streamIn usage.completion_tokens
ResponsesAn output item of type reasoning, with reasoning_text partsIn usage.output_tokens. usage.output_tokens_details.reasoning_tokens gives the count.
MessagesA thinking block before the text blockIn usage.output_tokens

In a Chat Completions stream, the usage chunk also gives the count in usage.completion_tokens_details.reasoning_tokens. See Streaming.

The empty answer trap

The model writes its reasoning first and its answer after it. max_tokens limits both together. When the limit is too small, the output stops during the reasoning. content is then null, and finish_reason is length.

{
  "message": {
    "role": "assistant",
    "content": null,
    "reasoning": "The user asks for 17 * 23. Let me"
  },
  "finish_reason": "length"
}

To prevent it:

  • Set max_tokens to 2048 or more. The model stops when it is done, and you pay only for the tokens that it makes.
  • Lower the effort with reasoning_effort: "low".
  • Turn the reasoning off where the model allows it.
  • Check finish_reason. If it is length, send the request again with a higher limit.

Turn reasoning off

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
response = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[{"role": "user", "content": "Translate 'good morning' into German."}],
    extra_body={"chat_template_kwargs": {"enable_thinking": False}},
    max_tokens=512,
)
print(response.choices[0].message.content)

The OpenAI SDK has no chat_template_kwargs argument, so send it in extra_body. With curl, put it in the JSON body.

Responses

On Responses, set the level with reasoning: {"effort": "low"}. The levels are the same as for reasoning_effort.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
response = client.responses.create(
    model="qwen/qwen3.8-27b",
    input="A train leaves at 09:40 and arrives at 13:15. How long is the trip?",
    reasoning={"effort": "low"},
    max_output_tokens=2048,
)
print(response.output_text)
print("Reasoning tokens:", response.usage.output_tokens_details.reasoning_tokens)

Messages

On Messages, thinking: {"type": "disabled"} turns the reasoning off. On zai-org/glm-5.3-flash, which always reasons, it selects the low level. thinking: {"type": "enabled"} and {"type": "adaptive"} turn it on. Set the level with output_config.effort.

pip install anthropic
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.munito.ai/inference",
    api_key=os.environ["MUNITO_API_KEY"],
)
message = client.messages.create(
    model="qwen/qwen3.8-27b",
    max_tokens=2048,
    messages=[{"role": "user", "content": "What is 17 * 23?"}],
    thinking={"type": "disabled"},
)
for block in message.content:
    print(block.type, ":", getattr(block, "text", None) or getattr(block, "thinking", ""))

thinking.budget_tokens is accepted from 1024 up to below max_tokens, but the model does not keep to it. max_tokens is the only limit on the output.

See Models and pricing for the output price of each model.