Pre-submission checklist
| field |
value |
| Category |
Tool use / MCP (工具调用 / MCP) |
| Agent framework |
Claude Code |
| Severity |
Major, works but degraded (影响体验) |
| Reproducibility |
Always (必现) |
Description
The z.ai Anthropic-compatible endpoint (https://api.z.ai/api/anthropic), when a /v1/messages request carries the advanced-tool-use-2025-11-20 beta, defers tools that were sent with full schemas and no defer_loading flag. Per that beta, only tools with defer_loading: true should be deferred behind the tool_search tool. On z.ai the always-loaded core tools (Bash, Read, Edit, Write, …) are not presented to the model, so it has to make a tool_search round-trip to reach them. api.anthropic.com handles the byte-identical request correctly and keeps those tools loaded.
This surfaces through Claude Code with ENABLE_TOOL_SEARCH=true pointed at z.ai (GLM). Every core-tool call then costs an extra tool_search round-trip. Any tool that tool_search fails to resolve is lost entirely.
Steps to reproduce
- Point Claude Code at z.ai:
ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic, an Anthropic-compatible key, ENABLE_TOOL_SEARCH=true, plus at least one MCP server so tool search engages.
- Ask the model to run
Bash, for example echo test.
- The model reports
Bash is not directly available. It calls the tool_search tool first, then runs the command. It takes one extra turn versus the same setup on api.anthropic.com.
Provider-level repro (no Claude Code needed): POST /v1/messages with header anthropic-beta: advanced-tool-use-2025-11-20 and a tools array holding several tools with a full input_schema and no defer_loading, alongside one tool with defer_loading: true. The tools without the flag do not reach the model and have to be retrieved via tool_search.
Expected behavior
Honor defer_loading per tool. Tools without defer_loading (or with defer_loading: false) stay directly available in the tool set. Only tools carrying defer_loading: true are deferred behind tool_search.
Actual behavior
Tools sent without defer_loading are deferred anyway. The model must call tool_search to reach core tools like Bash / Read / Edit.
I captured the outgoing request off the wire for both endpoints under ENABLE_TOOL_SEARCH=true. The tools array is byte-identical: 10 core tools with full schemas and no defer_loading (Agent, Bash, Edit, Read, ReportFindings, ScheduleWakeup, Skill, ToolSearch, Workflow, Write), a single DeferredToolPlaceholder carrying defer_loading: true, and the advanced-tool-use-2025-11-20 beta. Functional check:
| endpoint |
Bash directly available |
turns |
api.anthropic.com (Opus) |
yes |
2 |
z.ai (glm-5.2) |
no |
3 |
Caveat: I logged the request bytes, not z.ai's response, so the re-defer is inferred from the model's round-trip rather than read from the response payload.
Version & environment
- Endpoint:
https://api.z.ai/api/anthropic (Anthropic-compatible), model glm-5.2.
- Client: Claude Code 2.1.217, Linux. This is the API endpoint reached through Claude Code, not ZCode.
Related upstream report on the Claude Code side: anthropics/claude-code#52121.
Pre-submission checklist
工具调用 / MCP)影响体验)必现)Description
The z.ai Anthropic-compatible endpoint (
https://api.z.ai/api/anthropic), when a/v1/messagesrequest carries theadvanced-tool-use-2025-11-20beta, defers tools that were sent with full schemas and nodefer_loadingflag. Per that beta, only tools withdefer_loading: trueshould be deferred behind thetool_searchtool. On z.ai the always-loaded core tools (Bash,Read,Edit,Write, …) are not presented to the model, so it has to make atool_searchround-trip to reach them.api.anthropic.comhandles the byte-identical request correctly and keeps those tools loaded.This surfaces through Claude Code with
ENABLE_TOOL_SEARCH=truepointed at z.ai (GLM). Every core-tool call then costs an extratool_searchround-trip. Any tool thattool_searchfails to resolve is lost entirely.Steps to reproduce
ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic, an Anthropic-compatible key,ENABLE_TOOL_SEARCH=true, plus at least one MCP server so tool search engages.Bash, for exampleecho test.Bashis not directly available. It calls thetool_searchtool first, then runs the command. It takes one extra turn versus the same setup onapi.anthropic.com.Provider-level repro (no Claude Code needed):
POST /v1/messageswith headeranthropic-beta: advanced-tool-use-2025-11-20and atoolsarray holding several tools with a fullinput_schemaand nodefer_loading, alongside one tool withdefer_loading: true. The tools without the flag do not reach the model and have to be retrieved viatool_search.Expected behavior
Honor
defer_loadingper tool. Tools withoutdefer_loading(or withdefer_loading: false) stay directly available in the tool set. Only tools carryingdefer_loading: trueare deferred behindtool_search.Actual behavior
Tools sent without
defer_loadingare deferred anyway. The model must calltool_searchto reach core tools likeBash/Read/Edit.I captured the outgoing request off the wire for both endpoints under
ENABLE_TOOL_SEARCH=true. Thetoolsarray is byte-identical: 10 core tools with full schemas and nodefer_loading(Agent, Bash, Edit, Read, ReportFindings, ScheduleWakeup, Skill, ToolSearch, Workflow, Write), a singleDeferredToolPlaceholdercarryingdefer_loading: true, and theadvanced-tool-use-2025-11-20beta. Functional check:Bashdirectly availableapi.anthropic.com(Opus)glm-5.2)Caveat: I logged the request bytes, not z.ai's response, so the re-defer is inferred from the model's round-trip rather than read from the response payload.
Version & environment
https://api.z.ai/api/anthropic(Anthropic-compatible), modelglm-5.2.Related upstream report on the Claude Code side: anthropics/claude-code#52121.