> For the complete documentation index, see [llms.txt](https://docs.tensorx.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tensorx.ai/api-reference/reasoning.md).

# Reasoning

Several models expose a separate reasoning (thinking) step. When it runs, the response carries the reasoning in `reasoning_content` on the message and a `reasoning_tokens` count under `usage`, alongside the normal `content`.

The control differs by model family, so the table below is the quick reference. The sections that follow show each family in full.

| Model family             | Reasoning by default | How to turn on / off                                                                 | Depth control                                                         |
| ------------------------ | -------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
| GLM 5.3, GLM 5.3-Flash   | On                   | `reasoning_effort: "none"` or `chat_template_kwargs: {"enable_thinking": false}`     | `reasoning_effort: "low"` or `"high"`; omitted uses maximum depth     |
| GLM 5.2                  | On                   | `chat_template_kwargs: {"enable_thinking": true / false}`                            | `reasoning_effort: "high"` or `"max"`                                 |
| GLM 5.1, GLM 5-Turbo     | On                   | `chat_template_kwargs: {"enable_thinking": true / false}`                            | No effort levels                                                      |
| DeepSeek V4 (Flash, Pro) | Off                  | `chat_template_kwargs: {"thinking": true}` or any `reasoning_effort` except `"none"` | `reasoning_effort: "high"` or `"max"`                                 |
| DeepSeek V4.1 Flash      | Off                  | `chat_template_kwargs: {"thinking": true}` or any `reasoning_effort` except `"none"` | `reasoning_effort: "low"`, `"high"` or `"max"`                        |
| MiniMax M3.1 Flash       | Adaptive             | `chat_template_kwargs: {"thinking_mode": "disabled"}` or `reasoning_effort: "none"`  | `reasoning_effort`: `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"` |
| Kimi K2.7 Code           | On (always)          | Not toggleable                                                                       | None                                                                  |
| Qwen 3.8                 | On (always)          | Not toggleable                                                                       | `reasoning_effort: "xhigh"` (default), `"medium"`, `"low"`            |

DeepSeek V4 and V4.1 reasoning is **off by default on TensorX**. Enable it per request with `chat_template_kwargs: {"thinking": true}` or by setting `reasoning_effort`.

{% hint style="info" %}
The key name is per family: GLM uses `enable_thinking`, DeepSeek V4 and V4.1 use `thinking` and MiniMax M3.1 Flash uses `thinking_mode`. Sending the wrong key is silently ignored, which looks like the parameter "does nothing". The one exception is MiniMax M3.1 Flash, where `enable_thinking: false` or `thinking: false` is also read as `thinking_mode: "disabled"`.
{% endhint %}

## GLM 5.3 and GLM 5.3-Flash

Both models use maximum reasoning depth by default.

{% hint style="danger" %}
**`max_tokens` is a budget for reasoning&#x20;*****and*****&#x20;the answer.** GLM 5.3 and GLM 5.3-Flash default to maximum reasoning depth, which on even a trivial prompt can consume 400 to 750 tokens before the answer starts. If your `max_tokens` is smaller than that, the request ends with `finish_reason: "length"` and **`content` comes back empty** while you are still billed for the reasoning.

A `finish_reason` of `"length"`, empty `content`, and `reasoning_tokens` close to `max_tokens` indicate that the response budget was exhausted during reasoning.
{% endhint %}

Measured on `z-ai/glm-5.3` with `max_tokens: 400`, asking for a short Python function:

| Request                                            | `reasoning_tokens` | `finish_reason` | `content`         |
| -------------------------------------------------- | ------------------ | --------------- | ----------------- |
| No effort set (defaults to `max`)                  | 402                | `length`        | **empty**         |
| `reasoning_effort: "low"`                          | 1                  | `stop`          | returned normally |
| `reasoning_effort: "high"`                         | 4                  | `stop`          | returned normally |
| `reasoning_effort: "medium"`                       | 402                | `length`        | **empty**         |
| `chat_template_kwargs: {"enable_thinking": false}` | 0                  | `stop`          | returned normally |

Use one of these controls:

1. **Set `reasoning_effort`** to `"low"` or `"high"` to retain reasoning with a lower depth.
2. **Leave `max_tokens` unset** unless the application requires an explicit response budget. Query `GET /v1/model/info` for the model's `max_output_tokens` before setting one.
3. **Turn thinking off** with `chat_template_kwargs: {"enable_thinking": false}`.

### `reasoning_effort` mapping

SGLang handles `"none"` before the chat template and disables thinking. The template has explicit depth branches for `"low"` and `"high"`. Other accepted effort values use the maximum-depth branch, which is also the default when the parameter is omitted. Values outside the API's accepted enum are rejected during request validation.

| Value sent                                              | What the model gets |
| ------------------------------------------------------- | ------------------- |
| `"low"`                                                 | Low                 |
| `"high"`                                                | High                |
| `"none"`                                                | Thinking disabled   |
| `"minimal"`, `"medium"`, `"xhigh"`, `"max"`, or omitted | Max                 |

{% hint style="warning" %}
`"medium"` is accepted but selects the maximum-depth template branch rather than an intermediate depth. Use `"low"` or `"high"` when a bounded reasoning depth is required.
{% endhint %}

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.tensorx.ai/v1"
)

response = client.chat.completions.create(
    model="z-ai/glm-5.3",
    messages=[{"role": "user", "content": "Write a Python function that reverses a string."}],
    max_tokens=400,
    reasoning_effort="low"
)

print(response.choices[0].message.content)
print(response.usage.reasoning_tokens)
```

### Turning thinking off

```python
response = client.chat.completions.create(
    model="z-ai/glm-5.3-flash",
    messages=[{"role": "user", "content": "What is 15% of 240?"}],
    extra_body={"chat_template_kwargs": {"enable_thinking": False}}
)
```

The key must go inside `chat_template_kwargs`. A top-level `enable_thinking` is not part of the OpenAI schema and is ignored, which looks like the parameter doing nothing.

### Multi-turn: `clear_thinking`

On a multi-turn conversation these models **replay the reasoning from previous assistant turns** back into the prompt by default, which is what makes long tool-calling loops coherent. It also means your prompt grows faster than the visible message text suggests.

Set `clear_thinking: true` when prior reasoning should not be included in subsequent prompts.

```python
response = client.chat.completions.create(
    model="z-ai/glm-5.3",
    messages=conversation_so_far,
    extra_body={"chat_template_kwargs": {"clear_thinking": True}}
)
```

GLM 5.3-Flash is multimodal and accepts images on the same endpoint. Reasoning behaves identically on image requests.

## GLM (5.2, 5.1, 5-Turbo)

GLM models think **by default**. Turn thinking off with `enable_thinking: false` inside `chat_template_kwargs`:

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.tensorx.ai/v1"
)

# Thinking off (direct answer, no reasoning_content)
response = client.chat.completions.create(
    model="z-ai/glm-5.2",
    messages=[{"role": "user", "content": "What is 15% of 240?"}],
    extra_body={"chat_template_kwargs": {"enable_thinking": False}}
)
```

On **GLM 5.2**, `reasoning_effort` has two effective levels, `"high"` and `"max"`. It is passed at the top level (OpenAI-standard):

```python
response = client.chat.completions.create(
    model="z-ai/glm-5.2",
    messages=[{"role": "user", "content": "Prove that the square root of 2 is irrational."}],
    reasoning_effort="high"
)
```

`"high"` gives shorter reasoning, `"max"` gives the deepest. `"low"` and `"medium"` are accepted but map to `"high"`. To skip reasoning entirely, use `reasoning_effort: "none"` or `enable_thinking: false`. GLM 5.1 and GLM 5-Turbo support on/off but not effort levels.

## DeepSeek V4 (Flash, Pro)

DeepSeek V4 models default to **non-thinking** mode. Enable reasoning with `thinking: true` inside `chat_template_kwargs`:

{% hint style="warning" %}
**Moving from DeepSeek V4 to Qwen 3.8?** The `chat_template_kwargs: {"thinking": false}` key shown here is **accepted but ignored** on Qwen 3.8. The request returns 200, reasoning still runs, and you are still billed for it. Qwen 3.8 cannot have reasoning disabled.
{% endhint %}

```python
response = client.chat.completions.create(
    model="deepseek/deepseek-v4-pro-0813",
    messages=[{"role": "user", "content": "Prove that the square root of 2 is irrational."}],
    extra_body={"chat_template_kwargs": {"thinking": True}}
)

print(response.choices[0].message.reasoning_content)
print(response.choices[0].message.content)
```

Once thinking is on, control the depth with `reasoning_effort`, passed at the top level. There are two effective levels, `"high"` and `"max"`:

```python
response = client.chat.completions.create(
    model="deepseek/deepseek-v4-pro-0813",
    messages=[{"role": "user", "content": "Prove that the square root of 2 is irrational."}],
    extra_body={"chat_template_kwargs": {"thinking": True}},
    reasoning_effort="max"
)
```

`"high"` is the standard depth, `"max"` reasons the longest. `"low"` and `"medium"` are accepted but map to `"high"`. Setting `reasoning_effort` also turns thinking on, so `thinking: true` is optional when you set an effort. `chat_template_kwargs: {"thinking": false}` keeps thinking off even when `reasoning_effort` is set.

## DeepSeek V4.1 Flash

DeepSeek V4.1 Flash is available as `deepseek/deepseek-v4.1-flash` and `deepseek/deepseek-v4.1-flash-1017`. Both IDs are served by the 1017 checkpoint. Reasoning is **off by default**. A request without `reasoning_effort` returns no reasoning.

Turn reasoning on with `reasoning_effort`, passed at the top level. Any value except `"none"` turns it on. `chat_template_kwargs: {"thinking": true}` also turns it on.

```python
response = client.chat.completions.create(
    model="deepseek/deepseek-v4.1-flash",
    messages=[{"role": "user", "content": "Prove that the square root of 2 is irrational."}],
    reasoning_effort="high"
)

print(response.choices[0].message.reasoning_content)
print(response.choices[0].message.content)
```

The model has three depth levels: `"low"`, `"high"` and `"max"`. On `deepseek/deepseek-v4.1-flash` the other OpenAI values map to the nearest level, as on DeepSeek's own API:

| Value sent                        | What the model gets |
| --------------------------------- | ------------------- |
| `"none"` or omitted               | Thinking off        |
| `"minimal"` or `"low"`            | Low                 |
| `"medium"`, `"high"` or `"xhigh"` | High                |
| `"max"`                           | Max                 |

`deepseek/deepseek-v4.1-flash-1017` accepts the same values.

`reasoning_effort` takes only the string values above. A number such as `60` returns a 400. To keep reasoning off when your client always sends `reasoning_effort`, set `chat_template_kwargs: {"thinking": false}`. It takes priority over `reasoning_effort`.

## MiniMax M3.1 Flash

MiniMax M3.1 Flash uses adaptive thinking by default: the model decides whether to reason for each turn. It has three reasoning modes, set with `thinking_mode` inside `chat_template_kwargs`:

* `"enabled"`: always reason.
* `"adaptive"`: the model decides when to reason. This is the default.
* `"disabled"`: no reasoning, direct answer.

```python
# Reasoning off
response = client.chat.completions.create(
    model="minimax/minimax-m3.1-flash",
    messages=[{"role": "user", "content": "What is 15% of 240?"}],
    extra_body={"chat_template_kwargs": {"thinking_mode": "disabled"}}
)
```

M3.1 Flash uses `thinking_mode`, not `thinking` or `enable_thinking`, and the value is one of the three modes above. `reasoning_effort: "none"` or `"minimal"` also turns reasoning off, as does `enable_thinking: false` or `thinking: false` inside `chat_template_kwargs`. The model supports the reasoning effort levels `"low"`, `"medium"`, `"high"`, `"xhigh"` and `"max"`. Thinking mode controls whether the model reasons; effort steers the depth when it does, and is ignored when thinking is disabled. See the [MiniMax model card](https://huggingface.co/MiniMaxAI/MiniMax-M3.1-Flash#inference-settings).

## Kimi K2.7 Code

Kimi models reason **by default and cannot be toggled off**. There is no `enable_thinking` or `thinking` flag to set. `reasoning_content` is always populated.

## Qwen 3.8

Qwen 3.8 thinks on **every** request. Unlike the other families, reasoning **cannot be switched off**. The model rejects any attempt:

* `chat_template_kwargs: {"enable_thinking": false}` returns `400 Disabling thinking is not supported.`
* `reasoning_effort: "none"` returns the same error.

Depth is controlled with the standard top-level `reasoning_effort`, but the accepted values differ from other models on the platform:

| Value      | Effect                                                                                                        |
| ---------- | ------------------------------------------------------------------------------------------------------------- |
| `"xhigh"`  | **Default.** Asks the model to validate assumptions and weigh alternatives. Most thorough, most output tokens |
| `"medium"` | No additional reasoning-depth steering                                                                        |
| `"low"`    | Asks the model to keep thinking brief and reach the conclusion directly                                       |

{% hint style="warning" %}
**`reasoning_effort: "high"` returns a 400 on Qwen 3.8.** Use `"xhigh"`. `"high"` is the OpenAI-standard value and works on GLM 5.2, so ported code often sends it by default.
{% endhint %}

```python
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.tensorx.ai/v1"
)

response = client.chat.completions.create(
    model="qwen/qwen3.8-2.4t-a95b",
    messages=[{"role": "user", "content": "A bat and ball cost 1.10 in total. The bat costs 1.00 more than the ball. How much is the ball?"}],
    reasoning_effort="low"
)

print(response.choices[0].message.reasoning_content)  # the thinking
print(response.choices[0].message.content)            # the answer
print(response.usage.reasoning_tokens)                # billed as output
```

Reasoning arrives in `reasoning_content`, with no `<think>` tags left in `content`. When streaming, reasoning arrives as `delta.reasoning_content` deltas **before** the content deltas begin.

**Reasoning tokens are billed as output tokens.** They are counted inside `completion_tokens` and reported separately as `usage.reasoning_tokens`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.tensorx.ai/api-reference/reasoning.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
