Adjust reasoning effort

Set effort in each protocol and read actual thinking token usage.

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

Open Console → 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.

APIThinking controlUsage read in this guide
Chat Completionsreasoning_effort; also accepts a reasoning objectusage.completion_tokens_details.reasoning_tokens
Anthropic Messagesthinking selects the mode; output_config.effort selects the levelusage.output_tokens_details.thinking_tokens
Google generateContentthinkingBudget or thinkingLevel inside generationConfig.thinkingConfigusageMetadata.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, Messages, and Google.

1. Prepare your terminal

Use Python 3.10+ and uv. Put your Praxis cloud API Key in PRAXIS_API_KEY; do not put it in source code or logs.

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

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.

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

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.

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

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.

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

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

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 → · Cookbook →

Export

On this page