How to Code with GLM 5.2 on OpenCode
Coding with GLM 5.2 on OpenCode is a bet on your own engineering. Decide the architecture and interfaces first, let the cheap model write the code on a fixed twenty-dollar Ollama plan, and bring a str
If you want to code with GLM, plan to lean on your own engineering. A cheap model turns decisions into working code, and it turns missing decisions into confident messes. The architecture, the component boundaries, the interfaces between them — those have to exist before the first prompt, because GLM will not supply them. You decide, the model types, and where your trust runs out, a stronger model checks the work.
Worked that way, the arrangement pays for itself twice over. My agent — OpenCode driving GLM 5.2 on Ollama Cloud, wrapped in a generate-and-audit loop — does production work for a fixed twenty dollars a month, around twenty-nine Canadian the day I am writing this, and the code it committed last month to a public repository is real, with real tests. A metered frontier agent has no such ceiling; I once instrumented a single session and watched it pass thirty dollars before it finished [1]. The plan caps the bill, and the discipline underneath it is what makes a cheap model safe to point at production code.
Why this stack
None of the code depends on Claude the model. What everything depends on is the workflow you build around whatever models you run, and the workflow decides what each model is trusted with.
Two separate choices sit underneath. One is the plan you run on, which decides what you pay. The other is the model, which decides what the agent can do.
The plan: budget certainty
Ollama Cloud bills by GPU time on a subscription, with session and weekly windows, not by the token [2]. Its shape is close to an Anthropic plan: a fixed monthly price, usage metered against time windows, and a hard stop when you reach them instead of an open invoice. Twenty dollars a month, and the number cannot surprise you.
A token-metered provider works the other way. Run the very same GLM model through OpenRouter [5] and you pay per token, with no subscription and no ceiling, so heavy use simply costs more.
Vendor pricing keeps drifting toward consumption, and the tools built on top have grown more expensive, not less. A plan fixes your exposure to a number you can read in advance.
Context grows as a project does, and on a metered API every extra token costs more on every call. On one pipeline, the gap between caching the project docs and not caching them was thirty-three dollars against a hundred and eighty [1]. On a plan billed by time, that pressure is gone.
Currency is the force almost nobody mentions, because almost everybody writing about AI cost is paid in the same dollars they spend. I pay a US-priced plan in Canadian dollars. When the loonie weakens, a metered bill multiplies, because it already scales with usage, while a time-windowed plan barely moves.
The model: cheap, made reliable
GLM 5.2 is the model, the current flagship from Z.ai, on Ollama Cloud as glm-5.2 [3]. It costs a fraction of a frontier model and does real production work, on one condition. You run the workflow around it. Left to range over a whole project, a cheaper model keeps each file consistent and drops the connections between them. The loop closes that gap.
GLM through a metered provider would still be cheap per token, but with no ceiling. Ollama gives you both: the cheap model and the capped bill.
Figure 1. Two stacks, one workflow. Claude wraps Opus 4.8, a frontier model. OpenCode wraps GLM 5.2, a cheaper model on a flat plan with a fixed one. Underneath, the techniques — self-contained issues, context resets, an audit pass — are what let you move from the expensive stack to the cheap one without losing the work.
The setup, in the background
The plumbing takes half an hour and none of it is the interesting part. You need a Git repository for a Go project with git and gh authenticated, an Ollama account on the Pro plan with the glm-5.2 cloud model enabled [2][3], OpenCode, and Claude Code. Two prompts to Claude Code do the wiring. Spend the expensive agent on setup now and keep it for judgment later. First the provider config:
Configure OpenCode in this repo to use Ollama Cloud as its model provider.
Add a provider entry that points at the Ollama Cloud endpoint, reads my
OLLAMA_API_KEY from the environment, and sets glm-5.2 as the default model.
Read the current OpenCode configuration docs to get the exact file location
and field names right. Show me the diff before you write anything.
Then the command set, from coding-skills [4]:
From the public repository github.com/petar-djukic/coding-skills, copy
the OpenCode command files in .opencode/commands/ — make-work, gh-issue-push,
gh-issue-show, gh-issue-pop, do-work — into my OpenCode commands directory, so
they load in every project. Copy only files that exist in the source, and list
everything you copied.
Verify with a throwaway prompt to OpenCode; if the reply comes back and the Ollama dashboard shows GPU time ticking up, you are on the flat rate. Five commands, installed once, available in every project. Everything after this point is about how you work, not what you installed.
Decide before you generate
The seams GLM drops are the ones you have to own up front. Before anything is generated, decide the architecture, cut the components, and write the interfaces down: what each piece exposes, what it may depend on, what done means for it. I keep those decisions in vision and architecture notes at the repository root, the same architecture-first discipline I used long before any of this ran on a cheap model. make-work reads those notes, so every issue it proposes inherits your decisions instead of inventing its own.
The sample issue later in this article shows the division of labor in one line. ParseDuration(string) (time.Duration, error) is not something GLM chose; it is a signature I decided, written into the requirements, and the model’s job was to fill the body and make the tests pass. Interfaces are decisions, and bodies are volume. A frontier model can sometimes rescue a vague specification with judgment of its own. GLM will not, and treating that as a constraint rather than a defect is what makes the twenty-dollar plan workable — the judgment was always supposed to be yours.
Run the loop
Here is one task, start to finish.
Figure 2. One task, one loop. An issue becomes a self-contained prompt, a fresh agent generates against it, a second agent audits the result in a clean context, and any findings become new issues.
Planning is a judgment call, so it goes to the stronger model. In a Claude Code session in your repository, run make-work. It reads your vision and architecture notes and the open issue list, then proposes a set of self-contained issues, each with required reading, a file list, requirements, and acceptance criteria. It creates nothing until you approve the breakdown.
When you approve, gh-issue-push files each one as a GitHub issue. The push is the step that writes the loop’s memory. Everything a later session will need — the files to read, the requirements, the acceptance criteria — now lives on GitHub, outside any context window and outside any one model. The plan was Claude’s work; from here the issue is just text, and the cheap model can execute it.
Switch to OpenCode, pick an issue, and pop it:
gh-issue-pop 42
This creates a git worktree at ../gh-42-parse-duration on its own branch and leaves your main checkout on main, untouched. The agent that works the task starts in that worktree, seeing only the issue.
Next, run do-work. It reads the issue’s required reading, implements against the requirements, runs the tests, logs what it spent on the issue, closes it, and commits. You are watching it work one bounded task with nothing else in its context.
Then audit, back in Claude, in a fresh session that never saw the code get written. Judgment work goes to the stronger reader. Give it this:
You are auditing work you did not write. You see the final state of the
repository, nothing about how the code was produced. Read the changed files
against the requirements and the project's rules. Find: cross-document
references that no longer match, status or summary fields that contradict the
files they describe, documented rules the code does not follow, and commit
messages that describe intent rather than the diff. For each finding, write a
GitHub issue with the file, the line, and the fix. Do not change anything.
Only report.
The audit reports findings without touching the code. File each as a fix issue and clear them with another do-work. When the work comes back clean, open and merge the PR; gh-issue-pop tears the worktree down for you.
That is the loop: issue, generate, audit, merge. Run it once and the shape is yours.
Two models, three jobs
The loop splits its work between the two models by the kind of work it is, and the split follows the money. Planning reads the whole project and decides what to build, which is judgment. Auditing reads finished work against the rules and says no, which is judgment again. Writing code against a bounded issue with the acceptance criteria attached is volume. Claude gets the two judgment jobs. GLM gets the volume.
The economics come out the right way around. The judgment jobs are short and infrequent, one planning session per batch of issues and one audit per finished task, so they fit comfortably inside a Claude subscription without straining its windows. The volume job runs long and constant, which is exactly what the flat Ollama plan absorbs. Each model works where its price shape fits, and the GitHub issue is the handoff between them: written by the planner, executed by the generator, checked by the auditor, readable by all three.
Why the loop is shaped this way
Three choices in that loop keep a cheaper model from drifting. Run it enough and you feel why each one is there. I learned them by watching GLM break all three.
Self-contained issues
Each task is a GitHub issue that carries everything the agent needs: the files to read, the requirements, and the acceptance criteria that decide when it is done. Starting cold, the agent sees only that issue, with no memory of your planning conversation and no access to the rest of the backlog. make-work drafts issues in this shape, and gh-issue-push files them. A small one looks like this:
## Required Reading
- internal/config/config.go (existing Loader — extend it, do not replace)
- internal/config/config_test.go (table-test pattern to follow)
## Files to Create/Modify
- internal/config/duration.go
- internal/config/duration_test.go
## Requirements
- ParseDuration(string) (time.Duration, error) accepting "10s", "5m", "2h" (R1)
- Empty string returns a zero duration and a nil error (R2)
- An unrecognized unit returns an error naming the offending token (R3)
## Acceptance Criteria
- [ ] ParseDuration handles the s, m, h suffixes per R1
- [ ] Empty input returns (0, nil) per R2
- [ ] go test ./internal/config/... passes; one case per requirement
Every requirement has an identifier, and every acceptance criterion maps back to one. An agent that has never seen the rest of the project can read this and know exactly what done means.
This feels like overhead until you see what the alternative costs. When I let the model hold a whole project in its head, it kept each file internally consistent and broke the references between them. In one run, the architecture document pointed at a component by one name while the file on disk carried another. An index listed three authored documents while the summary field directly below it still read “no documents authored yet.” Every file was correct alone. The errors lived in the relationships between files, which is what a model loses when it tries to track everything at once. These are seam errors, and writing the issue this way makes the relationships explicit, on paper, before the agent ever runs.
The context reset
When an issue is done, start the next one in a fresh session. gh-issue-pop mechanizes this with a new git worktree per task, on its own branch, so the agent that runs do-work there starts from the issue and nothing else.
On a metered API the reason would be cost. On this plan the bill is fixed, so the reason is quality and headroom. GLM 5.2 degrades as its context window fills, and it degrades faster than a frontier model does. Five tasks deep, a session reasons worse on the sixth than a clean one would. Resetting also keeps each run short, which keeps you inside the plan’s session limits instead of burning a window on a conversation that should have been five separate ones. Each issue is a boundary, and the reset stops the drift.
The audit, in a fresh context
The audit you ran in Step 3 has one rule that makes it work. The auditor must not inherit the generator’s context. An auditor that watched the code get written will bless the same blind spots that produced it. A cold reader, seeing only the result and the rules it is supposed to meet, catches what the writer could not see. That is why you open a new session for it, and why a stronger reader helps here if you have one.
Most of my fixes start in that pass. I run it as a recurring issue. Each round produces a list of seams the generator missed, I file them as fix issues, and the next do-work clears them. Over a project that history becomes a sequence of “fix pass-N audit findings” issues, each one a list of things that were wrong before a cold reader looked. In my setup the cold reader is also the stronger reader — GLM writes, Claude audits. The fresh context does most of the separation work, and the sharper model catches the seams a cheaper reader would bless.
When it breaks
A few things will bite you, and they are the cost of the method.
GLM misses things a frontier model catches, almost always at the seams between files, where a reference no longer matches or a status field contradicts the file it describes. That is what the audit is for. Skip it and the seams ship, so watch for them by name.
The discipline is labor. Writing a good issue takes longer than typing a prompt, and you have to read the audit findings and file the fixes. A change that resists decomposition into a clear, bounded issue will fight you the whole way, because the method depends on drawing a line around the work before the agent starts.
That is the trade, structure up front in exchange for a monthly number you can state before the month begins. You build the workflow once. The model is a setting you change when something cheaper comes along; the loop is what you keep.
REFERENCES
[1] Djukic, P. (2026). What Does $33 of AI Code Generation Buy You? Mesh Intelligence. https://meshintelligence.substack.com/p/what-does-33-of-ai-code-generation
[2] Ollama (2026). Pricing. https://ollama.com/pricing
[3] Ollama (2026). glm-5.2. https://ollama.com/library/glm-5.2
[4] Djukic, P. (2026). coding-skills: spec-driven development commands and rule documents for coding agents. GitHub. https://github.com/petar-djukic/coding-skills
[5] OpenRouter (2026). Models. https://openrouter.ai/models


