GLM-5.2 Chat Template: Test Thinking and Tool Formatting
Independent research — not an official Z.ai publication.Identity and provider disclosure
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.
Navigate the chat-template gate
Section titled “Navigate the chat-template gate”- Pin the template before allocating GPUs
- Compare the thinking controls
- Verify the assistant generation suffix
- Inspect GLM tool serialization
- Choose whether history keeps reasoning
- Treat media conversion as a stop signal
- Reproduce the tokenizer-only probe
- Connect the template to server parsers
- Turn the protocol into a release gate
- Buy compute only after the gate passes
- Audit sources and limitations
- Resolve common template questions
Pin the template before allocating GPUs
Section titled “Pin the template before allocating GPUs”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:
from transformers import AutoTokenizerimport 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.
Compare the thinking controls
Section titled “Compare the thinking controls”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.
Verify the assistant generation suffix
Section titled “Verify the assistant generation suffix”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:
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>.
Inspect GLM tool serialization
Section titled “Inspect GLM tool serialization”The template does more than insert a generic JSON Schema. In our tool-visibility case it:
- kept the active
lookup_statusfunction; - omitted
deferred_inventorybecause its function object setdefer_loading=true; - removed the OpenAI-style
strictproperty; - 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:
<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.
Choose whether history keeps reasoning
Section titled “Choose whether history keeps reasoning”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.
Treat media conversion as a stop signal
Section titled “Treat media conversion as a stop signal”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.
Reproduce the tokenizer-only probe
Section titled “Reproduce the tokenizer-only probe”The checked-in evidence wrapper pins Python, Transformers, Jinja2, the model revision and each source hash:
bash docs/evidence/glm-5-2-chat-template-2026-08-10/run-probe.shThe 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.
Connect the template to server parsers
Section titled “Connect the template to server parsers”Passing the tokenizer gate is necessary but insufficient. The current vLLM GLM-5.2 recipe adds three server controls:
--tool-call-parser glm47 \--reasoning-parser glm45 \--enable-auto-tool-choiceThe 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:
- the client forwards the intended template keyword;
- the rendered prompt matches the pinned fixture;
- the reasoning parser separates thinking from visible content; and
- 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.
Turn the protocol into a release gate
Section titled “Turn the protocol into a release gate”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.
Buy compute only after the gate passes
Section titled “Buy compute only after the gate passes”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.
Audit sources and limitations
Section titled “Audit sources and limitations”Primary and implementation sources checked on August 10, 2026:
- Z.ai’s GLM-5.2 release page for model identity, open-weight access, flexible effort and supported local-serving routes;
- the official GLM-5.2 model repository and the pinned template source;
- Hugging Face Transformers chat-template documentation
for
apply_chat_template, tokenization and generation-prompt semantics; and - the vLLM GLM-5.2 recipe for the current tool parser, reasoning parser and template-keyword path.
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.
Resolve common template questions
Section titled “Resolve common template questions”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.
