# Adjust reasoning effort (/en/docs/developers/model/guides/reasoning)



The same “low” setting uses different fields in Chat, Messages, and Google. Choose a supported protocol and level, then inspect usage. Effort is a hint; actual consumption comes from usage.

## Choose a protocol and level [#choose-a-protocol-and-level]

Open [Console → Models](https://console.deepraxis.ai/models), select a model, and find “协议与思考档位” (Protocols and reasoning levels). Expected: supported APIs and thinking options are visible. If disabling is not offered, do not send a setting that disables thinking.

Confirm protocols with `supported_apis` from `GET /model/v1/models`. For programmatic Chat checks, use `reasoning.supported_efforts` and `reasoning.mandatory` from `GET /openai/v1/models?api=chat`. On October 13, 2026, the Chat catalog marked `glm-5.3`, `glm-5.3-flash`, and `kimi-k3` as `mandatory=true`: thinking cannot be disabled. Recheck the catalog before calling. Not every model supports every level. The usage fields below were returned by the models used here; other models may omit them.

| API                    | Thinking control                                                             | Usage read in this guide                           |
| ---------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------- |
| Chat Completions       | `reasoning_effort`; also accepts a `reasoning` object                        | `usage.completion_tokens_details.reasoning_tokens` |
| Anthropic Messages     | `thinking` selects the mode; `output_config.effort` selects the level        | `usage.output_tokens_details.thinking_tokens`      |
| Google generateContent | `thinkingBudget` or `thinkingLevel` inside `generationConfig.thinkingConfig` | `usageMetadata.thoughtsTokenCount`                 |

Chat levels range from `none` to `max`, subject to model support. `none` disables thinking; it does not mean “low.” Messages uses `enabled`, `adaptive`, and `disabled` for budgeted, adaptive, and disabled thinking. The effort field is not `thinking.effort`. Google budget and level controls depend on the model; do not send both together.

See the field definitions for [Chat](/en/docs/api/compatible/openai/createChatCompletion), [Messages](/en/docs/api/compatible/anthropic/createMessage), and [Google](/en/docs/api/compatible/google/generateContent).

## 1. Prepare your terminal [#1-prepare-your-terminal]

Use Python 3.10+ and [uv](https://docs.astral.sh/uv/getting-started/installation/). Put your [Praxis cloud API Key](/en/docs/developers/account/api-keys) in `PRAXIS_API_KEY`; do not put it in source code or logs.

```bash
test -n "$PRAXIS_API_KEY"
```

Expected: exit code 0. Exit code 1 means the variable is missing. Examples default to `https://api.deepraxis.com`. To switch environments, set `PRAXIS_API_BASE` to the API origin without a trailing slash or API path.

## 2. Chat: select low and read usage [#2-chat-select-low-and-read-usage]

`deepseek-flash` supports Chat and `low`.

Save as `reasoning-chat.py` and run `uv run -q --no-project --with openai --with anthropic --with google-genai python reasoning-chat.py`.

```python
import os
from openai import OpenAI

client = OpenAI(api_key=os.environ['PRAXIS_API_KEY'],
    base_url=os.environ.get('PRAXIS_API_BASE', 'https://api.deepraxis.com') + '/openai/v1')
response = client.chat.completions.create(
    model='deepseek-flash', reasoning_effort='low', max_tokens=2048,
    messages=[{'role': 'user', 'content': 'What is 17 times 23? Answer briefly.'}])
assert response.choices[0].finish_reason == 'stop'
assert '391' in (response.choices[0].message.content or '')
details = response.usage.completion_tokens_details
assert details is not None and details.reasoning_tokens is not None, 'Reasoning usage was not reported'
print('X-Request-Id:', response._request_id)
print('answer:', response.choices[0].message.content)
print('reasoning_tokens:', details.reasoning_tokens)
```

Expected: the answer contains `391`, the finish reason is `stop`, and the script prints actual `reasoning_tokens`. Exit code 0. Counts vary between calls.

## 3. Messages: select low and read usage [#3-messages-select-low-and-read-usage]

This example uses `claude-opus-5` because it returned thinking token details during verification. The Messages response from `deepseek-flash` omitted them. Missing is not zero; `output_tokens` is not a substitute.

Save as `reasoning-messages.py` and run `uv run -q --no-project --with openai --with anthropic --with google-genai python reasoning-messages.py`.

```python
import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ['PRAXIS_API_KEY'],
    base_url=os.environ.get('PRAXIS_API_BASE', 'https://api.deepraxis.com') + '/anthropic')
raw = client.messages.with_raw_response.create(
    model='claude-opus-5', max_tokens=2048,
    thinking={'type': 'adaptive'}, output_config={'effort': 'low'},
    messages=[{'role': 'user', 'content': 'What is 17 times 23? Answer briefly.'}])
response = raw.parse()
answer = ''.join(block.text for block in response.content if block.type == 'text')
assert response.stop_reason == 'end_turn' and '391' in answer
usage = response.usage.model_dump()
details = usage.get('output_tokens_details') or {}
assert details.get('thinking_tokens') is not None, 'Thinking usage was not reported'
print('X-Request-Id:', raw.headers.get('x-request-id'))
print('answer:', answer)
print('thinking_tokens:', details['thinking_tokens'])
```

Expected: the answer contains `391`, the stop reason is `end_turn`, and the script prints actual `thinking_tokens`. Exit code 0.

## 4. Google: select a budget or level by model [#4-google-select-a-budget-or-level-by-model]

This calls two models: `gemini-2.5-flash` with a budget, then `gemini-3.1-flash-lite-preview` with low effort. HTTP exposes Google's field names directly.

Save as `reasoning-google.py` and run `uv run -q --no-project --with openai --with anthropic --with google-genai python reasoning-google.py`.

```python
import json
import os
import httpx

base = os.environ.get('PRAXIS_API_BASE', 'https://api.deepraxis.com')
with httpx.Client(timeout=120) as client:
    for model, thinking in [
        ('gemini-2.5-flash', {'thinkingBudget': 1024}),
        ('gemini-3.1-flash-lite-preview', {'thinkingLevel': 'low'}),
    ]:
        response = client.post(base + '/google/v1beta/models/' + model + ':generateContent',
            headers={'Authorization': 'Bearer ' + os.environ['PRAXIS_API_KEY']},
            json={'contents': [{'role': 'user', 'parts': [{'text': 'What is 17 times 23? Answer briefly.'}]}],
                  'generationConfig': {'maxOutputTokens': 2048, 'thinkingConfig': thinking}})
        print('X-Request-Id:', response.headers.get('x-request-id'))
        response.raise_for_status()
        data = response.json()
        candidate = data['candidates'][0]
        answer = ''.join(part.get('text', '') for part in candidate['content']['parts'])
        assert candidate['finishReason'] == 'STOP' and '391' in answer
        assert 'thoughtsTokenCount' in data['usageMetadata'], 'Thinking usage was not reported'
        print(model, answer, json.dumps(data['usageMetadata']))
```

Expected: both answers contain `391`, both finish reasons are `STOP`, and each prints `thoughtsTokenCount`. Exit code 0.

## Compare results [#compare-results]

Keep the model and question constant. Sample multiple calls and compare actual thinking tokens, complete answers, latency, and quality. A budget is not a universal hard cap across models. “Low” does not guarantee fewer tokens than “high” on every call or faster responses. Do not infer a monotonic relationship from one response. Preserve missing usage as “not reported,” never zero.

## Observed failure and recovery [#observed-failure-and-recovery]

Setting `reasoning_effort="none"` on `glm-5.3` returned HTTP 400 with code `thinking_disable_unsupported`:

> glm-5.3 cannot disable thinking; omit the thinking setting or choose a level.

Omit the disabling setting or choose a supported level, then retry. Changing to another protocol's disabling field does not remove this restriction.

[API reference →](/en/docs/api/compatible/openai) · [Cookbook →](/en/docs/cookbook)
