GLM-5.3 Hands-on Guide: Always-on Thinking, Three Effort Levels, and the API Support Matrix

AIHubMix7 min read
GLM-5.3 Hands-on Guide: Always-on Thinking, Three Effort Levels, and the API Support Matrix

Title: GLM-5.3 Hands-On Guide: Always-On Thinking, Three Effort Levels & API Support Matrix

Description: August 2026 GLM-5.3 guide: always-on thinking with three reasoning_effort levels, reasoning summaries, parallel tool calls, structured output, and auto caching — with verified AIHubMix Chat / Responses / Messages examples.


This article covers the key API changes and usage notes for GLM-5.3. GLM-5.3 is Z.ai's flagship model released on 2026-08-14 — it uses the exact same base model as GLM-5.2, with every gain coming from post-training. On AIHubMix the model ID is coding-glm-5.3 (currently a limited-time preview route), available through the Chat Completions, Responses, and Claude-compatible Messages APIs. See also: the official Z.ai release blog.

The "Verified" conclusions and sample responses in each section come from actual calls made on 2026-08-14 through the AIHubMix APIs (Chat Completions / Responses / Messages).

1. Model Specs at a Glance

Item Value
Context window 1M tokens (official exact value: 1,048,576)
Max output 128K (max_tokens verified ceiling: 131,072 — exceeding it returns 400)
Input modalities Text
Thinking Always on, cannot be disabled; reasoning_effort has three levels — low / high / max, default max
Relationship to GLM-5.2 Same base model, upgraded via post-training: much stronger coding and long-horizon task performance, plus emergent cyber capabilities
AIHubMix model ID coding-glm-5.3 (limited-time preview route; we will follow up as soon as the official commercial API launches)
Verified: max_tokens: 999999 returns 400 with the valid range spelled out in the error body — the ceiling is genuinely validated, not silently truncated.
# max_tokens=999999 -> HTTP 400
"max_tokens parameter invalid: value must be within [1,131072]"

2. GLM-5.3 vs GLM-5.2: Always-On Thinking, Intensity via reasoning_effort

Item GLM-5.2 GLM-5.3
Base model Identical to 5.2 (all gains from post-training)
thinking.type enabled / disabled — can be turned off enabled only — cannot be turned off
reasoning_effort 7-value compatibility mapping (effective levels: max/high) Three levels low / high / max, default max
Positioning General-purpose flagship Strengthened for coding and long-horizon agentic tasks, with emergent cyber capabilities

These are the two most important API changes in GLM-5.3 relative to GLM-5.2:

  1. thinking.type no longer supports disabled — thinking cannot be turned off. Official migration advice: applications that used to send {"type": "disabled"} should switch to {"type": "enabled"} and set reasoning_effort to "low".
  2. reasoning_effort narrows to three levels: low (light) / high (enhanced) / max (deep, the default). The GLM-5.2-era 7-value compatibility mapping no longer applies; Z.ai recommends max for coding tasks.
Verified: sending thinking: {"type": "disabled"} through AIHubMix returns 200 and thinking still happens (reasoning_content is returned as usual) — the value is converted automatically per the official channel semantics rather than rejected. If your client relied on "turn off thinking to save tokens", switch to reasoning_effort: "low".

Verified: out-of-enum values for reasoning_effort also return 200 without an error (falling back to the default max per the official docs); low vs max shows the expected lighter-thinking trend (27 vs 39 reasoning tokens on the same arithmetic question).

Chat Completions

Thinking content is returned in the reasoning_content field; in streaming it arrives as delta.reasoning_content.

from openai import OpenAI

client = OpenAI(
    base_url="https://aihubmix.com/v1",
    api_key="<AIHUBMIX_API_KEY>",
)

completion = client.chat.completions.create(
    model="coding-glm-5.3",
    reasoning_effort="max",          # low / high / max, default max
    extra_body={"thinking": {"type": "enabled"}},
    messages=[
        {"role": "user", "content": "Compute the square root of (17*23-19*11), rounded down. Digits only."}
    ],
)

print(completion.choices[0].message.reasoning_content)
print(completion.choices[0].message.content)   # Observed: "13"
Verified: usage.completion_tokens_details.reasoning_tokens reports thinking usage — 27 with reasoning_effort="low", 39 with "max" on the same question.

Responses

Thinking content comes back as a reasoning output item, with the text inside the summary array as summary_text.

from openai import OpenAI

client = OpenAI(
    base_url="https://aihubmix.com/v1",
    api_key="<AIHUBMIX_API_KEY>",
)

response = client.responses.create(
    model="coding-glm-5.3",
    input="What is the capital of France? City name only.",
)

# Observed response.output item types: ["reasoning", "message"]
# reasoning item: {"type": "reasoning", "summary": [{"type": "summary_text", "text": "The user is asking..."}]}
# usage.output_tokens_details.reasoning_tokens: 80
Verified: the default request (no reasoning parameter at all) already includes the reasoning item with summary_text — no explicit opt-in needed.

Messages

Thinking content is returned as native thinking content blocks.

from anthropic import Anthropic

client = Anthropic(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com"
)

response = client.messages.create(
    model="coding-glm-5.3",
    max_tokens=4096,
    messages=[
        {"role": "user", "content": "What is the capital of France? City name only."}
    ],
)

# Observed response.content block types: ["thinking", "text"]
Verified: thinking blocks are returned by default; thinking: {"type": "disabled"} on this API likewise returns 200 with thinking still happening (consistent with the official "disabled converts to low, request continues" channel semantics).

3. Tool Calling and Parallel Tools

Function calling verified working on all three APIs; on the Responses API we also observed parallel tool calls within a single turn (Z.ai explicitly declares supports_parallel_tool_calls: true for GLM-5.3). Upstream limits: up to 128 functions in tools; tool_choice natively supports auto only.

Chat Completions

completion = client.chat.completions.create(
    model="coding-glm-5.3",
    messages=[{"role": "user", "content": "What's the weather in Beijing today?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
        },
    }],
)

# Observed: finish_reason "tool_calls", with a get_weather call in tool_calls
Verified: tool_choice: "none" works — the same weather question returns plain text with no tool call.

Responses

response = client.responses.create(
    model="coding-glm-5.3",
    input="Check today's weather in Shanghai and Beijing",
    parallel_tool_calls=True,
    tools=[{
        "type": "function",
        "name": "get_weather",
        "description": "Get weather for a city",
        "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
    }],
)

# Observed: a single turn returns 2 parallel function_call output items (one for each city)
Verified: 2 parallel tool calls in one turn, matching the official supports_parallel_tool_calls: true declaration.

Messages

response = client.messages.create(
    model="coding-glm-5.3",
    max_tokens=4096,
    tools=[{
        "name": "get_weather",
        "description": "Get weather for a city",
        "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
    }],
    messages=[{"role": "user", "content": "What's the weather in Beijing today?"}],
)

# Observed: stop_reason "tool_use"; content contains a tool_use block
Verified: on this API, the model still produces tool calls after tool_choice: {"type": "none"} — to disable tools, remove the tools parameter entirely, or use tool_choice: "none" on the Chat Completions API instead.

4. Structured Output

response_format supports text and json_object; the upstream does not list a json_schema mode. When you need strict schema conformance, embed the JSON Schema in the prompt and validate client-side.

Chat Completions

completion = client.chat.completions.create(
    model="coding-glm-5.3",
    messages=[
        {"role": "user", "content": "What is the capital of France? Answer in JSON with the key \"answer\"."}
    ],
    response_format={"type": "json_object"},
)

# Observed response content: {"answer": "Paris"}
Verified: output is valid JSON containing the requested key.

Responses

response = client.responses.create(
    model="coding-glm-5.3",
    input="What is the capital of France? Answer in JSON with the key \"answer\".",
    text={"format": {"type": "json_object"}},
)

# Observed output text: {"answer": "Paris"}

Messages

# Specify the JSON structure in the prompt; observed output is valid JSON
response = client.messages.create(
    model="coding-glm-5.3",
    max_tokens=4096,
    messages=[
        {"role": "user", "content": "What is the capital of France? Answer in JSON with the key \"answer\"."}
    ],
)

# Observed response text: {"answer": "Paris"}

5. Context Caching Is Automatic

Implicit caching is on by default with no parameters to pass; repeated long prefixes report cache hits in usage (the field name varies by API).

Chat Completions

# usage of the second call with an identical long prefix
"prompt_tokens_details": {"cached_tokens": 960}
Verified: the second of two back-to-back calls hit 960 cached tokens.

Responses

# usage of the second call with an identical long prefix
"input_tokens_details": {"cached_tokens": 960}

Messages

# hits are reported via usage.cache_read_input_tokens
"cache_read_input_tokens": 0
Verified: we did not reproduce a cache hit on this API in this round (caches warm per channel; a load-balancer switch can cause a miss). The hit-accounting field follows Anthropic semantics.

6. Sampling and Parameter Validation

Sampling follows the GLM family endpoint conventions: temperature range [0, 1] with default 1.0 (note — narrower than the OpenAI protocol's [0, 2]); top_p range [0.01, 1] with default 0.95. Z.ai recommends tuning only one of the two.

Verified: parameter validation differs across APIs — the Messages API rejects an out-of-range temperature: 3 with a 400 that spells out the valid range [0,1], while Chat Completions / Responses silently accept the same out-of-range value with 200. When migrating across APIs, do not rely on the gateway to catch out-of-range sampling values for you.
# Messages API with temperature=3 -> HTTP 400
"temperature parameter invalid: value must be within [0,1]"

7. Capability × API Support Matrix

Every cell below was verified with real calls through the AIHubMix live APIs on 2026-08-14; cells show the parameter/field spelling for each API.

Capability Chat Completions Responses Messages
Basic generation / streaming
Thinking content reasoning_content field reasoning output item (summary_text) thinking content block
Thinking intensity reasoning_effort (low/high/max, default max) ✅ same as left ✅ accepted with 200
Disable thinking ❗ Not possible: disabled returns 200 and thinking continues (converted-to-low semantics) ➖ no toggle parameter ❗ same as Chat
Function calling
Parallel tool calls ✅ 2 function_call items in one turn
Disable tool calls tool_choice: "none" works ✅ 200 (no calls observed) ❗ calls still produced after {"type": "none"}
Structured output (JSON mode) response_format: json_object text.format: json_object ✅ via prompt convention
json_schema strict mode ❗ not listed upstream — embed the schema in the prompt ❗ same as left ❗ same as left
Automatic cache accounting usage.prompt_tokens_details.cached_tokens usage.input_tokens_details.cached_tokens ✅ field present (no hit reproduced this round)
Max-output validation ✅ 400 with range [1,131072]
Out-of-range sampling validation ❗ silent 200 ❗ silent 200 ✅ 400 with range [0,1]

FAQ

What is the GLM-5.3 model ID on AIHubMix? Do I need the [1m] suffix?
The model ID is coding-glm-5.3 — use it as is. glm-5.3[1m] is Z.ai's model-name syntax for the Claude Code client and has nothing to do with AIHubMix calls; none of the three APIs needs any suffix.

Can I turn thinking off?
No. GLM-5.3 thinking is always on and thinking.type only supports enabled; in our tests, sending disabled returns 200 with thinking still happening (converted to the low level per official semantics). To save thinking tokens, send reasoning_effort: "low".

How does GLM-5.3 relate to GLM-5.2?
Same base model — all gains come from post-training (official wording: "It uses the same base model as GLM-5.2 — every gain comes from post-training"). Two hard API changes: thinking can no longer be disabled, and reasoning_effort narrows to three levels low/high/max (default max).

What if I need strict json_schema structured output?
The upstream does not list a response_format: json_schema mode. In our tests, json_object JSON mode produced valid JSON on all three APIs; for strict schemas, embed the JSON Schema in the prompt and validate client-side.

Is coding-glm-5.3 the production release?
It is currently a limited-time preview route (Z.ai's model API docs mark the official API as "coming soon"); AIHubMix will follow up as soon as the commercial API ships. See the model page for current pricing and status.


For pricing and real-time status, see the GLM-5.3 model page; for more models, visit the model gallery.