opencode agents: setting up roles, models and tools
A custom agent in opencode is a role, a model and a set of permissions. A working config where a cheap model handles routine work and a stronger one edits code.
5 min · · агенты · экономия
By default opencode works as one general-purpose assistant that can do everything: read, edit files, run commands. That is convenient until you notice that writing a commit message burns the same expensive model as a hard refactor. Here we cover how opencode agents are structured, how to define your own, and how to hand it only the permissions it needs.
The parameters were checked against the Agents section of the opencode.ai/docs documentation as of October 18, 2026. The project carries a note about a second version, so if your version behaves differently, open the documentation for that version.
Which agents opencode has
Agents come in two types.
Primary agents are the ones you talk to. You switch between them with Tab. Two are built in: Build (all tools enabled) and Plan (restricted: edits and bash require approval by default, and it is meant for analysis and plans).
Subagents are helpers that a primary agent calls for a separate task, or that you call with an @name mention. Built in: General (general purpose, can edit files), Explore (fast, read-only) and Scout (read-only, for external docs and dependency sources).
There are also hidden system agents: one compacts long context, another generates session titles, a third produces summaries. You cannot pick them in the UI, but they also call a model. More on that in the cost section below.
Two ways to define an agent
The first is the agent block in opencode.json. The key is the agent name:
{
"$schema": "https://opencode.ai/config.json",
"agent": {
"reviewer": {
"description": "Code review without edits",
"mode": "subagent",
"model": "anthropic/claude-opus-5-5",
"prompt": "You are a reviewer. Look at security, performance and readability.",
"permission": { "edit": "deny" }
}
}
}The second is a markdown file. Put it in ~/.config/opencode/agents/ (all projects) or .opencode/agents/ (the current one). The file name becomes the agent name: review.md creates an agent called review. Settings go in the front matter, and the text after it is the system prompt.
The description field is required. Without a description the primary agent will not know when to call that subagent.
A quick way to scaffold one is opencode agent create: it asks where to save it and what the agent is for, then lets you pick permissions, denying everything you do not select.
What you can set
- model in
provider/modelformat. If omitted, a primary agent uses the global model, and a subagent uses the model of the primary agent that called it. - permission is what the agent may do:
read,edit,bash,task,webfetchand others. Values areallow,ask,deny; foreditandbashyou can pass an object with patterns. - mode is
primary,subagentorall(the default). - steps caps the number of agent steps. At the limit the agent must wrap up with a text answer. It is a simple guard against expensive loops.
- temperature, top_p control randomness. If unset, model defaults apply.
- prompt is text or a file via
{file:./prompts/review.txt}, with the path relative to the config location. - hidden hides a subagent from the
@suggestions (subagents only).
The tools field is marked deprecated in the docs; for new configs they recommend permission.
Example: a cheap model for routine work
Say claude-sonnet-5 does the main work, claude-opus-5-5 builds plans, and commit messages and docs edits go to an inexpensive model. For Claude we use the built-in anthropic provider (so the gateway sees the cache), and for cheap models we add an OpenAI-compatible provider. The address in both cases is https://api.zukko.pro/v1; details are in the opencode documentation.
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-5",
"small_model": "zukko/glm-5.3-flash",
"provider": {
"anthropic": {
"options": { "baseURL": "https://api.zukko.pro/v1", "apiKey": "{env:ZUKKO_API_KEY}" },
"models": { "claude-sonnet-5": {}, "claude-opus-5-5": {} }
},
"zukko": {
"npm": "@ai-sdk/openai-compatible",
"name": "Zukko",
"options": { "baseURL": "https://api.zukko.pro/v1", "apiKey": "{env:ZUKKO_API_KEY}" },
"models": {The docs describe small_model as a separate model for lightweight tasks such as session titles. If unset, opencode tries to find something cheaper at your provider, otherwise it uses the main model. Better to set it explicitly so you are not guessing where those requests go.
Now the file .opencode/agents/changelog.md:
---
description: Writes commit messages and CHANGELOG entries from git diff
mode: subagent
model: zukko/deepseek-v4.1-flash
temperature: 0.2
steps: 8
permission:
edit:
"*": deny
"CHANGELOG.md": allow
bash:
"*": deny
"git diff*": allow
"git log*": allow
"git status*": allow
---
You maintain the change history. Read the diff, group changes by meaning
and write briefly, in past tense. Do not invent anything that is not in the diff.
Edit only CHANGELOG.md.In permission rules the last matching rule wins, so the blanket "*": deny comes first and the exceptions after it. Swap the order and the deny overrides the allows.
Using the agent is simple: write @changelog prepare an entry for the last three commits. The primary agent can also call it on its own, guided by description.
Limiting who an agent can call
An orchestrator has the task permission. With it you can list which subagents it may invoke:
{
"agent": {
"orchestrator": {
"mode": "primary",
"permission": {
"task": { "*": "deny", "changelog": "allow", "reviewer": "ask" }
}
}
}
}A denied subagent disappears from the tool description, so the model does not even try to call it. You can still call any of them manually through @.
What it saves
Zukko prices on October 18, 2026, $ per 1M tokens, cache ignored. An illustrative routine agent run: 50,000 input tokens and 5,000 output tokens.
deepseek-v4.1-flash(0.013 input / 0.038 output): 0.05 × 0.013 + 0.005 × 0.038 = 0.00065 + 0.00019 = $0.00084.claude-sonnet-5(0.4 / 2): 0.05 × 0.4 + 0.005 × 2 = 0.02 + 0.01 = $0.03.
Over a hundred runs that is about $0.08 versus $3.00. The gap matters when routine work happens every day. But do not hand everything to a cheap model: it will not always be enough for commits and docs, so test it on your own tasks. Current prices and the model list are in GET https://api.zukko.pro/v1/models.
Checking it
- Start
opencodeand run/models: models from both providers should be listed. - Call
@changelogand confirm it cannot edit anything exceptCHANGELOG.md. - Look at the "Usage" section in the Zukko dashboard: requests should go to the model you assigned to the agent.
Create a separate key with a daily limit for the agent: then a looping agent hits the limit rather than your whole balance. You can make one on the API keys page.
FAQ
How is an agent different from a subagent?
You use a primary agent directly, switching with Tab. A subagent is called by a primary agent or by you via @, and it performs a separate task in its own session.
How do I connect MCP to just one agent?
Servers are declared in the mcp block, and access to their tools is limited with permissions or patterns like server_name_*. Details and examples are in the MCP servers section of the opencode docs.
How is this similar to agents in Cline?
The idea is shared: a role, a set of allowed actions and its own model. The settings differ between tools, so a config does not carry over from one to the other. Check each tool's documentation.
The agent does not see the model from my config. What now?
Check that the model name in agent.<name>.model matches the key in the provider's models block and that the provider is right: zukko/deepseek-v4.1-flash, not just deepseek-v4.1-flash.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- Plan mode in Claude Code: plan first, then edit the codeIn plan mode Claude Code reads your code and proposes a plan but edits nothing until you agree. How to enable it, use it and what it costs.
- How much an AI agent costs: a step-by-step model spend calculationAgent cost is set by the number of steps, context growth, cache and the model. A formula, three examples with arithmetic and a calculator you can plug your own numbers into.
- Saving tokens in opencode: a checklist of settings and habitsopencode spend comes from habits and a few lines of config. A checklist you can verify: what to turn on, what to remove, and how to see the result in the dashboard.
- Project rules in Qwen Code: context files and token savingsHow to explain project rules to Qwen Code once: QWEN.md, path-conditional rules, skills and MCP, and how many tokens each such file costs.