GLM-5.3 is Z.ai's August 2026 flagship model for coding and long-horizon agentic work. It uses the same base model as GLM-5.2; the gains come from post-training.
On AIHubMix, the limited-time preview model ID is coding-glm-5.3. It is available through OpenAI-compatible Chat Completions, OpenAI Responses, and Claude-compatible Messages.
The important migration change is simple but consequential: thinking is always on. You can no longer disable it. Instead, you select one of three reasoning_effort levels: low, high, or max (the default).
The findings below come from live AIHubMix calls made on August 14, 2026. The full hands-on guide includes every request, observed response, and the complete verification notes.
Specs and migration changes
| Item | GLM-5.3 |
|---|---|
| Context window | 1,048,576 tokens |
| Maximum output | 131,072 tokens |
| Input | Text |
| Thinking | Always on |
| Reasoning effort |
low, high, max; default max
|
| AIHubMix model ID | coding-glm-5.3 |
The maximum output value is enforced. Sending max_tokens=999999 returned HTTP 400 with the valid range [1,131072].
Compared with GLM-5.2:
-
thinking.typesupportsenabledonly. The olddisabledbehavior is gone. -
reasoning_effortis now a three-level control instead of the previous compatibility mapping. - Z.ai recommends
maxfor coding tasks.
In our AIHubMix test, sending thinking: {"type": "disabled"} still returned 200, but thinking continued and reasoning_content was present. Treat it as converted behavior, not a successful off switch. To reduce reasoning tokens, use reasoning_effort="low".
1. Thinking output across the three APIs
Chat Completions
Thinking text is returned in reasoning_content; in streaming responses 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
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) # 13
On the same arithmetic question, usage reported 27 reasoning tokens with low and 39 with max.
Responses
Responses returns a reasoning output item. The visible reasoning summary is a summary_text entry inside its summary array.
response = client.responses.create(
model="coding-glm-5.3",
input="What is the capital of France? City name only.",
)
# Observed item types: ["reasoning", "message"]
# The reasoning item contains:
# {"type": "reasoning", "summary": [{"type": "summary_text", ...}]}
No opt-in is required. The default request, with no reasoning parameter, already returned the reasoning item and 80 reasoning tokens in this test.
Messages
The Claude-compatible Messages API returns native thinking content blocks before the text block.
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?"}],
)
# Observed content block types: ["thinking", "text"]
2. Tool calls and parallel execution
Function calling worked on all three APIs. The Responses API also produced two parallel calls in one turn when asked for weather in two cities.
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: two function_call output items in one turn
Two practical details matter:
- The upstream accepts up to 128 function definitions and documents
tool_choice: autoas the native mode. - Chat Completions correctly honors
tool_choice: "none". On Messages,tool_choice: {"type": "none"}still produced a tool call in testing. Remove thetoolsparameter entirely when tools must be disabled on Messages.
3. JSON output
Chat Completions supports response_format: json_object:
completion = client.chat.completions.create(
model="coding-glm-5.3",
messages=[{
"role": "user",
"content": "What is the capital of France? Answer in JSON with key answer.",
}],
response_format={"type": "json_object"},
)
# {"answer": "Paris"}
Responses uses text.format:
response = client.responses.create(
model="coding-glm-5.3",
input="What is the capital of France? Answer in JSON with key answer.",
text={"format": {"type": "json_object"}},
)
The upstream does not list a strict json_schema mode. For schema-critical applications, include the schema in the prompt and validate the result client-side. Messages produced valid JSON when prompted, but has no equivalent dedicated field in this test.
4. Automatic context caching
Caching is implicit; there is no parameter to enable. Two consecutive requests sharing an identical long prefix produced 960 cached tokens on Chat Completions and Responses.
- Chat:
usage.prompt_tokens_details.cached_tokens - Responses:
usage.input_tokens_details.cached_tokens - Messages:
usage.cache_read_input_tokens
The Messages field was present, but we did not reproduce a hit in this round. Caches warm per channel, so a load-balancer switch can produce a miss.
5. Sampling validation differs by API
GLM endpoints use temperature in [0,1] with default 1.0, and top_p in [0.01,1] with default 0.95. Z.ai recommends tuning only one.
The API surfaces do not validate these values consistently. Messages rejected temperature=3 with HTTP 400 and explicitly reported [0,1]. Chat Completions and Responses silently accepted the same out-of-range value with 200.
Validate sampling values in your client instead of relying on the gateway.
Capability x API matrix
| Capability | Chat Completions | Responses | Messages |
|---|---|---|---|
| Generation / streaming | Yes | Yes | Yes |
| Thinking content | reasoning_content |
reasoning item / summary_text
|
thinking block |
| Thinking intensity | reasoning_effort |
reasoning_effort |
Accepted with 200 |
| Disable thinking | No; disabled still thinks |
No toggle | No; same behavior as Chat |
| Function calling | Yes | Yes | Yes |
| Parallel tool calls | Not verified | Yes; 2 calls observed | Not verified |
| Disable tool calls | tool_choice: "none" |
No calls observed | Remove tools; typed none failed |
| JSON mode | response_format |
text.format |
Prompt convention |
Strict json_schema
|
Not listed upstream | Not listed upstream | Not listed upstream |
| Cache accounting | prompt_tokens_details.cached_tokens |
input_tokens_details.cached_tokens |
Field present; no hit reproduced |
| Max-output validation | 400 with [1,131072]
|
Not tested | Not tested |
| Out-of-range sampling | Silently accepted | Silently accepted | 400 with [0,1]
|
Production checklist
- Remove any code path that assumes thinking can be disabled.
- Use
reasoning_effort="low"when you need lower reasoning spend. - Read thinking from the protocol-specific response field.
- Remove
toolsentirely to disable tools on Messages. - Validate JSON Schema client-side.
- Validate
temperatureandtop_pbefore sending requests. - Normalize the three cache-accounting field names in observability code.
GLM-5.3's model behavior is consistent in its core capabilities, but protocol compatibility is not field-for-field. Treat Chat Completions, Responses, and Messages as three adapters around the same model, especially for thinking, tools, JSON output, and usage accounting.
Current pricing and availability are on the AIHubMix model page. For all examples and observed responses, read the complete GLM-5.3 hands-on guide.

Top comments (0)