Skip to content

GLM-5.2 Chat Template: Test Thinking and Tool Formatting

Independent research — not an official Z.ai publication.Identity and provider disclosure

GLM-5.2 messages branch into thinking, tool, history and media template checks before reaching a self-hosted server

Original editorial diagram of the tested serialization gate. It is not a Z.ai, Hugging Face, vLLM, SGLang, RunPod or GPU product screen.

Pin the GLM-5.2 tokenizer revision and render representative conversations before you load the 753B checkpoint. At official revision b4734de4facf877f85769a911abafc5283eab3d9, the template defaults to Reasoning Effort: Max, recognizes exact lowercase high, closes an empty think block when thinking is off, formats tools in GLM-specific XML, clears old reasoning by default and turns media items into a text-only reminder.

Those details are not cosmetic. A chat model receives one token sequence, not your original list of role dictionaries. The Hugging Face template guide warns that the wrong control tokens can materially degrade behavior. A server can start successfully while still feeding the model an unintended effort branch, retaining reasoning you meant to clear, or producing tool markup that its parser cannot recover.

This guide gives you a cheap preflight: reproduce the exact template, compare the ten observed branches, and promote the result only when your engine adds the matching reasoning and tool parsers.

  1. Pin the template before allocating GPUs
  2. Compare the thinking controls
  3. Verify the assistant generation suffix
  4. Inspect GLM tool serialization
  5. Choose whether history keeps reasoning
  6. Treat media conversion as a stop signal
  7. Reproduce the tokenizer-only probe
  8. Connect the template to server parsers
  9. Turn the protocol into a release gate
  10. Buy compute only after the gate passes
  11. Audit sources and limitations
  12. Resolve common template questions

A model repository can change while its friendly name stays the same. Pin both the repository revision and the template hash, then fail when either moves:

Load the pinned tokenizer only
from transformers import AutoTokenizer
import hashlib
MODEL = "zai-org/GLM-5.2"
REVISION = "b4734de4facf877f85769a911abafc5283eab3d9"
EXPECTED = "172dc74a35e1752df75ecfb2b2cf9326d2852bb1379868ebeec9571654489679"
tokenizer = AutoTokenizer.from_pretrained(
MODEL,
revision=REVISION,
trust_remote_code=False,
)
actual = hashlib.sha256(tokenizer.chat_template.encode()).hexdigest()
if actual != EXPECTED:
raise SystemExit(f"chat template changed: {actual}")

This loads tokenizer files, not the model weights. Our isolated run saw 18 cache files totaling 40,496,743 bytes and no .safetensors, .bin, .pt, .pth, .ckpt or model-weight index. That makes template validation a far smaller first gate than the resource plan in the GLM-5.2 local hardware guide.

The pinned source receipts are:

Official file Bytes SHA-256 prefix Why it is gated
chat_template.jinja 5,076 172dc74a35e1752d… Controls role, thinking, tool, history and media serialization
tokenizer_config.json 761 98b1271574f41abf… Declares the template, 1,048,576 maximum length, left padding and token IDs
generation_config.json 194 ac76b43d8683d3b9… Declares generation stop IDs and the Transformers version

The one-million-token value is metadata, not a promise that your server has enough KV-cache memory. Keep context-capacity testing separate from this protocol check.

For the same user message—Plan a bounded cache migration.—we varied only the template keyword. The observed prompt prefixes were:

Input control Rendered effort Ending before generation Tokens Gate result
Omit reasoning_effort Max <|assistant|><think> 18 Pass: documented default branch
reasoning_effort="high" High <|assistant|><think> 18 Pass: exact High branch
reasoning_effort="medium" Max <|assistant|><think> 18 Negative control: Medium is not implemented
enable_thinking=False none <|assistant|><think></think> 12 Pass: empty closed block

The medium row is the useful surprise. The Jinja template does not reject the keyword; it falls through to Max. That means a permissive client schema can silently request a different mode than its UI label suggests. Allowlist high and max for this pinned template, and treat any other value as a local error.

This is lower-level evidence than the site’s reasoning-effort decision guide. That page helps choose an API-facing effort for a task. This page proves only what the official tokenizer emits at one revision. It does not measure whether Max uses more generated tokens or solves harder tasks.

add_generation_prompt=True tells this template to append the assistant role and open the next think block. With it disabled, our rendered string ended on the user text and contained 16 tokens instead of 18:

Generation-prompt boundary
true: …<|user|>Plan a bounded cache migration.<|assistant|><think>
false: …<|user|>Plan a bounded cache migration.

Use True for ordinary inference where the model should start a fresh assistant response. Use False when preprocessing completed conversations for training or when another step owns the response boundary. Hugging Face’s documentation makes the same training distinction: adding the start of a new assistant answer is not useful at the end of a complete supervised example.

Do not format to text and then add special tokens a second time. Either ask apply_chat_template(..., tokenize=True) for the input IDs directly, or pass add_special_tokens=False when you later tokenize the rendered string. The template already begins with [gMASK]<sop>.

The template does more than insert a generic JSON Schema. In our tool-visibility case it:

  • kept the active lookup_status function;
  • omitted deferred_inventory because its function object set defer_loading=true;
  • removed the OpenAI-style strict property;
  • emitted the tool block before the custom system message; and
  • expanded the prompt from 18 tokens to 168 tokens.

The assistant tool-call round trip then used this protocol shape:

Sanitized GLM tool round trip
<tool_call>lookup_status
<arg_key>job_id</arg_key><arg_value>demo-17</arg_value>
</tool_call>
<|observation|><tool_response>{"state":"ready"}</tool_response>

That complete case rendered 187 tokens. The count is not tool cost or generated output; it is the tokenized prompt after the active function definition, assistant call and synthetic tool result were serialized.

Do not infer that strict=True was enforced because the client accepted it. The template deliberately removes the key. Validate arguments in application code before executing a function, as shown in the site’s tested GLM-5.2 tool-calling loop.

We supplied a synthetic earlier assistant turn with reasoning_content="synthetic-old-reasoning" and visible content marker one. The default output removed the reasoning string but retained the visible answer as <think></think>marker one. Setting clear_thinking=False retained the old reasoning inside the serialized history.

History mode Old reasoning present Visible answer present Tokens
Default clearing no yes 26
clear_thinking=False yes yes 32

Default clearing reduces prompt tokens and avoids replaying a previous hidden trace. Retention may be useful for a controlled continuation experiment, but it also changes privacy, context-budget and behavior boundaries. Treat it as an explicit, tested policy—not a convenience toggle passed through every request.

The probe uses an obviously synthetic reasoning marker and archives only a short prefix, suffix and SHA-256. It never stores a user’s private chain of thought or a live model response.

The GLM-5.2 base tokenizer accepted a content list containing text plus an image_url object, but the template did not serialize the URL. It replaced the media item with a reminder that the model lacks multimodal input ability. The case rendered 40 tokens and both assertions passed: the reminder was present and invalid.example was absent.

That behavior is a safety net, not vision support. A request being accepted by the template says nothing about pixels being decoded. Route image workloads to a compatible model or reject them before tokenization; the site’s GLM-5.2 image-support guide covers that product-level decision.

Also avoid logging the whole rendered prompt merely to prove the URL vanished. For production evidence, keep a bounded synthetic fixture, a boolean assertion and a digest.

The checked-in evidence wrapper pins Python, Transformers, Jinja2, the model revision and each source hash:

Run the bounded reproduction
bash docs/evidence/glm-5-2-chat-template-2026-08-10/run-probe.sh

The wrapper refuses to overwrite its result, so choose a fresh task result path or remove only your own previous temporary output before rerunning. On this host, ordinary Docker bridge HTTPS failed with the already documented Snap DNS/fake-IP symptom. The final trusted, digest-pinned container used the approved outbound-only host-network exception, opened no listener, published no port and mounted the repository read-only.

The full result is available as sanitized JSON. Its summary is:

Receipt field Observed value
Cases 10
Assertions 24 passed / 24 total
Token range 12–187
Loaded model weights false
Live model request false
GPU run false
Listener / published port false / false
Repository mount read-only

An earlier setup receipt exposed a token-counting bug: Transformers 5 returned a mapping, and counting that mapping measured keys instead of input_ids. We deleted that invalid temporary result, corrected the shape check and reran all ten cases. The archived receipt is only the corrected run. Keeping this failure in the method record is important—the test must validate its own measurement path as well as the model template.

Passing the tokenizer gate is necessary but insufficient. The current vLLM GLM-5.2 recipe adds three server controls:

Relevant vLLM protocol flags
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--enable-auto-tool-choice

The recipe passes High or non-thinking behavior through chat_template_kwargs. These flags are engine configuration, not properties of the tokenizer receipt. Before production, send one synthetic request per branch and verify four layers independently:

  1. the client forwards the intended template keyword;
  2. the rendered prompt matches the pinned fixture;
  3. the reasoning parser separates thinking from visible content; and
  4. the tool parser reconstructs a name and arguments that your application validates before execution.

If an engine release changes its parser names or payload schema, update the engine fixture without silently updating the pinned tokenizer baseline. A source change and an integration change deserve separate reviews and rollback points.

Prompt serialization is only the first half of the turn boundary. Before a GPU canary, use the GLM-5.2 stop-token audit to confirm that vLLM or SGLang preserves all three checkpoint EOS IDs and applies them only to newly generated tokens.

Store small synthetic conversations beside your deployment configuration. A useful fail-closed gate compares invariants rather than entire human prompts:

Layer Required check Stop condition
Source revision and three file hashes match any digest changes
Thinking default, High, negative control and off branches match unsupported value falls through unnoticed
Generation assistant suffix appears only when intended missing or duplicated response boundary
Tools active/deferred order, omitted strict, call/result markers parser and template disagree
History clearing policy is explicit old reasoning retained unexpectedly
Media unsupported input is rejected or converted without URL leakage request proceeds as if vision were available
Runtime repository read-only, no weights, no listener preflight scope expands silently

Hash exact output for regression detection, but diagnose a change semantically. A legitimate upstream fix may change whitespace or token counts. Review the diff, update fixtures intentionally, and rerun a live engine canary before promoting the new revision.

The site’s GigaToken test is the next gate if your problem is tokenizer parity or preprocessing throughput. This template probe does not benchmark either.

If the tokenizer and engine-parser fixtures pass, decide whether self-hosting is justified. The Coding Plan, API and self-hosting comparison separates product access, operational control and infrastructure cost. An API removes weight placement and server-parser maintenance from your workload; self-hosting gives you control but makes checkpoint storage, GPU topology, engine versions, safety checks and canaries your responsibility.

Primary and implementation sources checked on August 10, 2026:

Our independent evidence is the digest-pinned tokenizer render, not a first-party performance claim. The full methodology, setup corrections and cleanup receipt are in the research record and the local evidence directory. The GitHub repository is private, so the public JSON above is the durable reader-facing receipt.

Recheck the model revision, template hashes, Transformers version and engine recipe before copying these results. A future upstream change can make a currently correct assertion obsolete.

What is the GLM-5.2 chat template default reasoning effort?

Section titled “What is the GLM-5.2 chat template default reasoning effort?”

At the pinned revision, omitted effort renders Max. Exact lowercase high renders High. Our explicit medium control also rendered Max, so do not expose Medium as if this template implements it.

Does disabling thinking remove every think marker?

Section titled “Does disabling thinking remove every think marker?”

No. In the tested generation-prompt case, it removed the effort line but ended with an empty <think></think> block. Your reasoning parser should handle that shape without exposing an empty trace to users.

Does the official template enforce strict JSON Schema tools?

Section titled “Does the official template enforce strict JSON Schema tools?”

No conclusion of that kind is supported. The tested template removed the strict property before serializing the function definition. Validate tool arguments locally and use a live tool-loop test for application behavior.

Can GLM-5.2 process an image because the template accepts image_url?

Section titled “Can GLM-5.2 process an image because the template accepts image_url?”

No. The pinned base template converted the media item to a text-only reminder and omitted the URL. Template acceptance is not image decoding or multimodal model support.

Do these token counts predict serving cost or latency?

Section titled “Do these token counts predict serving cost or latency?”

No. They measure ten small prompt fixtures from the official tokenizer. They do not include generated output, KV-cache allocation, batching, network time, parser overhead or model inference.

Should I copy the template instead of using the model repository?

Section titled “Should I copy the template instead of using the model repository?”

Prefer the official template at a pinned revision. Keep a hash and regression fixtures in your deployment. Fork only when you have a documented protocol reason, matching training evidence, engine tests and a rollback path.