On this page
- What problem were we solving?
- How does the setup work?
- What does a good brief look like?
- What broke when we set it up?
- Old way vs new way
- When should you not delegate?
- A small experiment to try
- The files
- 1. The wrapper: ~/.local/bin/glm-claude
- 2. The dispatcher: ~/.claude/agents/glm-worker.md
- 3. The instruction for Claude: add to ~/.claude/CLAUDE.md
- Could this work for your team?
Last updated: 22 October 2026
Short answer: We let Claude do the thinking and a cheaper model do the typing. Claude reads the code, decides the fix and writes a brief. GLM, running on a flat-rate coding plan, makes the edits and runs the tests. Claude then reviews the diff before anything ships. It keeps our Claude usage for the parts that need judgment, and the whole setup is three small files you can copy below.
Key points
- One AI plans and reviews, another one executes. Same tools, different bill.
- The hand-off is a written brief. If you can't write a clear brief, you don't understand the task well enough to hand it off yet.
- The executor's report is not proof. Claude checks the real diff and runs the tests itself.
- We hit three silly failures setting this up. They're all listed below so you don't have to.
What problem were we solving?
Most of our client work now happens with Claude Code: reading a codebase, fixing a live bug, writing the tests, shipping. Claude is very good at this. It is also the thing we run out of.
A subscription has limits, and a lot of what eats those limits is not hard thinking. It's typing: applying an edit across six files, writing twenty test cases, renaming things. The judgment happened earlier, when someone decided what to change.
So the question became: can the expensive model keep the judgment and give away the typing?
How does the setup work?
There are four pieces, and the chain looks like this:
Claude (lead) ββbriefβββΆ glm-worker βββΆ glm-claude βββΆ Claude Code running on GLM
β² β
βββββ report + git diff βββββ relayed back βββββββββββββββββ
1. Claude, as the lead. A line in our global instructions tells Claude: understand the request, read the code you need, decide the approach, then hand the hands-on work to the worker. Claude writes a brief with the goal, the exact files, the approach, the constraints and how we'll know it's done.
2. A tiny dispatcher agent. glm-worker is a Claude Code subagent on the smallest, cheapest Claude model. It doesn't do the task. It saves the brief to a file, starts GLM, waits, and passes back GLM's report plus a git diff. If GLM fails, it says so and stops. It never quietly does the work itself.
3. A wrapper script. glm-claude launches the normal Claude Code CLI, but points it at Z.ai's Anthropic-compatible endpoint with a Z.ai key. Same program, same tools, same permission system. Every request just goes to GLM instead.
4. GLM does the work. It reads the files, makes the edits, runs the tests it's allowed to run, and writes a report: what changed, which checks passed, what blocked it.
Then it comes back to Claude, who reads the actual diff, runs the acceptance commands again, and either fixes small things or sends a second brief.
What does a good brief look like?
The executor has no memory of your conversation. Everything it needs has to be on the page. Ours always have six parts:
- Goal, including why. "Forwarded supplier emails are being dropped" beats "update the parser".
- Exact files, with the functions or lines that matter.
- Approach, and the obvious alternative we rejected, so it doesn't drift back to it.
- Constraints: what must not change, which style to match, never deploy or commit.
- Acceptance criteria: commands to run and what they must print. We always include the real input that broke, as a test case.
- Report format: files changed, criteria met or unmet, command output, blockers.
Writing this takes a few minutes. It's also a useful test of your own thinking. A vague brief usually means the plan is still vague.
What broke when we set it up?
Honest list. Each of these cost us time on a real job, mid-task, on the day we wrote this.
The key lived in two places. We put a new API key in the project's .env file. The wrapper reads its own key file, so it kept using the old one. The fix is boring: one source of truth, written down in the script's header.
The wrong kind of key. Z.ai rejected the next key with error 1113 Insufficient balance or no resource package, on every endpoint and every model. The account had a plan. The key just wasn't attached to it. A third key worked. If you see 1113 and you know you've paid, check the key before you check the endpoint.
The prompt got swallowed. The CLI's --allowedTools flag takes a list, and it kept reading our prompt as one more tool name. Error: "Input must be provided either through stdin or as a prompt argument". Putting the prompt straight after -p fixed it.
It couldn't reach the server. The job was on a remote box we reach over SSH, and ssh wasn't on the executor's allowed list. So the brief was fine, but it could never be done.
On that day, with the executor down, Claude simply did the fix itself and we sorted the plumbing afterwards. That's the right fallback. The worker should fail loudly, not do the task on the expensive model behind your back.
Old way vs new way
| Old way | New way | |
|---|---|---|
| Who writes the code | The expensive model, start to finish | The cheap model, from a brief |
| Who decides the approach | Same model, mid-typing | Claude, before any edit |
| What gets reviewed | Often nothing, it "looked right" | The real diff, with tests re-run |
| When usage runs out | Mid-task | Much later, because typing doesn't count against it |
| Knowledge of the plan | In the chat, lost later | In a written brief you can reread |
When should you not delegate?
- Tiny edits. If it's three lines, writing the brief costs more than the edit.
- Unknown bugs. If you don't yet know why something fails, that's thinking, not typing. Keep it with the lead.
- Design choices. Let the executor implement a decision, not make one.
A small experiment to try
Pick one task you'd normally ask Claude Code to do end to end: adding tests to an existing module is perfect. Before running it, ask Claude to write the brief only, using the six parts above. Read it.
If the brief is clear, you've found work you can hand to a cheaper model. If it's fuzzy, you've found where the real thinking still needs to happen. Either way you've learnt something about the task.
The files
Three files. Install takes about five minutes if you already use Claude Code and have a Z.ai GLM Coding Plan.
1. The wrapper: ~/.local/bin/glm-claude
#!/usr/bin/env bash
# glm-claude: a Claude Code session powered by GLM on the Z.ai Coding Plan.
# Key: $ZAI_API_KEY, else ~/.config/zai/api_key (chmod 600).
# This file is the source of truth. A key in a project .env is NOT read.
# URL: $GLM_BASE_URL, default https://api.z.ai/api/anthropic
# Model: $GLM_MODEL to pin one. Unset means Z.ai picks server-side.
set -euo pipefail
KEY_FILE="${ZAI_KEY_FILE:-$HOME/.config/zai/api_key}"
if [[ -z "${ZAI_API_KEY:-}" && -r "$KEY_FILE" ]]; then
ZAI_API_KEY="$(tr -d '[:space:]' < "$KEY_FILE")"
fi
if [[ -z "${ZAI_API_KEY:-}" ]]; then
echo "glm-claude: no Z.ai key. Set ZAI_API_KEY or write it to $KEY_FILE" >&2
exit 1
fi
unset ANTHROPIC_API_KEY
export ANTHROPIC_BASE_URL="${GLM_BASE_URL:-https://api.z.ai/api/anthropic}"
export ANTHROPIC_AUTH_TOKEN="$ZAI_API_KEY"
# Pin a model if asked, and remap the aliases so subagents stay on GLM too.
if [[ -n "${GLM_MODEL:-}" ]]; then
export ANTHROPIC_MODEL="$GLM_MODEL"
export ANTHROPIC_DEFAULT_OPUS_MODEL="$GLM_MODEL"
export ANTHROPIC_DEFAULT_SONNET_MODEL="$GLM_MODEL"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="$GLM_MODEL"
fi
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
export API_TIMEOUT_MS=3000000
CLAUDE_BIN="${CLAUDE_BIN:-$(command -v claude || true)}"
[[ -n "$CLAUDE_BIN" ]] || { echo "glm-claude: claude CLI not found" >&2; exit 1; }
exec "$CLAUDE_BIN" "$@"
Then:
chmod 755 ~/.local/bin/glm-claude
mkdir -p ~/.config/zai
printf '%s' 'YOUR_ZAI_KEY' > ~/.config/zai/api_key
chmod 600 ~/.config/zai/api_key
glm-claude -p "reply with OK" --max-turns 1 # should print OK
2. The dispatcher: ~/.claude/agents/glm-worker.md
---
name: glm-worker
description: Executes a well-defined implementation task (edit code, refactor, add tests, boilerplate, docs) on GLM via the Z.ai Coding Plan, so it costs almost no Claude usage. Use once the approach is decided. Give it a complete, self-contained brief: it has no memory of the conversation. Not for research, planning, or decisions that need judgment.
tools: Bash, Read, Write
model: haiku
---
You are a thin dispatcher. You do NOT do the task yourself. GLM does.
1. Preflight: run `glm-claude -p "reply with OK" --max-turns 1`. If it does not print OK, report the error and stop.
2. Write the brief you were given, verbatim, to `.glm-task.md` in the working directory. Do not rewrite or summarise it. If it has no acceptance criteria, add: "Acceptance: the change works and nothing else is modified."
3. Run GLM (Bash timeout 600000; run in background if longer). The prompt goes straight after -p, because --allowedTools takes a list and would swallow it:
glm-claude -p "Read .glm-task.md and execute it fully. Work through the acceptance criteria one by one. Finish with a report: files changed, criteria met/unmet, commands run and their result, blockers." \
--permission-mode acceptEdits \
--allowedTools "Read,Edit,Write,Glob,Grep,Bash(ls:*),Bash(cat:*),Bash(git status:*),Bash(git diff:*),Bash(npm test:*),Bash(npm run:*),Bash(pytest:*),Bash(python:*),Bash(go test:*),Bash(tsc:*)"
If the brief says the code is on a remote host, add ,Bash(ssh:*),Bash(scp:*) to the list.
4. Delete `.glm-task.md`. If it's a git repo, run `git status --short` and `git diff --stat`.
5. Return GLM's report and the diff stat. Do not review or fix the code: the caller does that. If glm-claude failed, say so with the error and stop. Never do the task yourself.
3. The instruction for Claude: add to ~/.claude/CLAUDE.md
## Claude usage budget
- You (Claude) are the lead: understand the request, read the code you need,
decide the approach, then review the result.
- Hand hands-on implementation to the `glm-worker` subagent instead of doing
large edits yourself. Give it a complete brief: goal, exact files, approach,
constraints, acceptance criteria.
- After it returns, review the diff yourself and fix small issues directly;
re-delegate anything large.
- Do it yourself when the edit is tiny or the task needs judgment throughout.
That's it. Next time you ask Claude Code to build something, it will plan, hand off and review.
Could this work for your team?
If your developers already use Claude Code and keep hitting usage limits, probably yes. The bigger win is not the cost though. It's that every change now starts with a written plan and ends with a real review, which is a habit most teams want anyway.
If you'd like help setting up an AI workflow like this around your own systems, get in touch.
One email a month, no noise
Practical AI notes for Australian businesses. Unsubscribe anytime.

