Week 6: Custom Agents¶
You've been using agents all week — the plan agent, the build agent. But did you know you can create your own? This week, we shift from using agents to authoring them. You'll learn what makes an agent an agent, how permissions work, and when to fork a new agent instead of just writing a command.
Agent Anatomy: What Makes an Agent?¶
An agent is defined by five things:
1. Mode — Is It a Boss or a Helper?¶
An agent's mode determines whether you interact with it directly or whether another agent calls it.
primary: You interact with this agent directly. You see its messages in the terminal. You press Enter to send it a prompt. Thebuildandplanagents are both primary.subagent: This agent is called by a primary agent (or by you with@mention). A subagent does focused work and reports back. The primary agent sees the subagent's output and can decide what to do next.
Why the distinction? A primary agent is the conversation partner. A subagent is the specialist on call.
2. Model — Which Brain?¶
Every agent runs on a model. The string looks like provider/model-name:
anthropic/claude-opus-4(powerful, thoughtful)anthropic/claude-sonnet-4(fast, versatile, cost-efficient default)anthropic/claude-haiku-4(very fast, for lightweight tasks)openai/gpt-4-turbo- Or a local model if you've configured one
A key principle: You can have a fast subagent that handles data wrangling, and a powerful primary agent that does judgment. This saves cost and context.
3. Prompt — The System Instructions¶
This is the agent's personality and role. A prompt tells the agent what it is, what it should do, and how to behave.
Example prompt for a "docs writer" agent:
You are a documentation expert. Your role is to write clear,
beginner-friendly API docs. Always include code examples.
Use a friendly tone. Ask clarifying questions if the spec is ambiguous.
Example prompt for a "test runner" subagent:
You are a test execution specialist. Your only job is to run tests,
parse the output, and report the results. Do not write code or
modify files. Be concise.
The prompt is how the agent thinks about the task. A well-written prompt is the difference between an agent that helps and one that wastes your time.
4. Permissions — What Can It Touch?¶
This is the boundary. Permissions answer the question: "What tools is this agent allowed to use?"
Available permissions:
| Tool | What it does |
|---|---|
bash |
Run commands (compile, test, deploy) |
read |
Read files |
edit |
Modify files |
glob |
Search files by pattern |
grep |
Search file contents |
webfetch |
Fetch URLs (docs, APIs) |
task |
Create/manage to-do items |
todowrite |
Write to-do files directly |
websearch |
Search the internet |
lsp |
Use language-server tools (code nav, type info) |
skill |
Discover and load skills |
For each permission, you set one of three rules:
allow: Do it without asking.ask: Ask me first.deny: Never, period.
Example: A "docs writer" agent might have:
- bash: deny (don't run commands)
- read: allow (read the source code freely)
- edit: allow (write the docs)
- webfetch: allow (fetch external docs)
Why? Because a docs writer doesn't need to run tests (that's not their job), but they need to read code and fetch references.
Example: A "test runner" subagent might have:
- bash: allow (run tests)
- read: allow (read test files)
- edit: deny (don't fix code, just report)
- Everything else: deny
Permissions are your safety net. They stop the agent from going off-road.
5b. Reasoning Effort — How Hard Does the Agent Think?¶
Not all tasks need the same amount of cognitive work. OpenCode lets you control this with reasoningEffort:
permissions:
read: allow
edit: deny
reasoningEffort: high
| Value | When to Use | Cost |
|---|---|---|
low |
Formatting, boilerplate, simple lookups | Cheapest, fastest |
medium |
General coding, test writing | Balanced |
high |
Security audits, complex refactors, ambiguous specs | Most expensive, slowest |
Rule of thumb: Use the lowest effort setting that reliably produces correct results. A low effort agent halved your cost per task and doubles your speed. Save high for the tasks where thoroughness matters — security review, production-sensitive changes, or unclear requirements.
Set it in the agent's YAML frontmatter or in opencode.jsonc under the agent's config entry.
5. Description — Who Is This? (For Subagents)¶
If the agent is a subagent, you write a short description so the primary agent knows when to invoke it. For example:
- "Runs test suites and reports results"
- "Reviews code for security issues and style violations"
- "Writes API documentation from type stubs"
The description is like a job posting. The primary agent reads it and decides, "Yeah, I need the test-runner subagent here."
Why Fork an Agent vs. Write a Command?¶
You've written commands. You know the pattern: define $ARGUMENTS, set the agent, write the prompt.
When do you write a command? - You do the same task 3+ times. - The prompt is a template with small variations. - Permissions don't need to change.
Example: /test <filename> — it's the same agent, same permissions, slightly different prompt each time.
When do you fork a new agent? - The agent needs a different permission profile. (A docs writer shouldn't run bash.) - The agent has a different role or different model. (A fast subagent vs. a slow one.) - You want to reuse this agent across multiple commands or in a workflow.
The key insight: Agents own a role. Commands are just templates for invoking that role.
If you find yourself writing bash: deny in a command prompt (telling the agent "don't run bash"), stop. That's a sign you should create a new agent. Because then every command using that agent inherits the constraint — you can't accidentally relax it.
The Code-Reviewer Pattern¶
Here's a pattern you'll use a lot: the code-reviewer subagent.
Goal: A primary build agent has done some work. Before accepting it, you want a read-only agent to audit it.
Setup:
- Create a
code-reviewersubagent: - Mode:
subagent - Permissions:
read: allow,grep: allow,glob: allow. Everything else:deny. -
Prompt: "You are a code reviewer. Your job is to audit code for correctness, style, and security. Report issues. Do not write code."
-
In the primary
buildagent, you'd write something like:
I've written the feature. Let me ask the code-reviewer
subagent to audit it.
@code-reviewer: Review the files I just edited.
Are there any bugs, style issues, or security concerns?
- The primary agent sees the review and can decide: "The reviewer found nothing. Shipping. Or, "The reviewer found a bug. Let me fix it."
Why this works:
- The reviewer can't accidentally edit code (it has edit: deny).
- The reviewer's context doesn't pollute the primary agent's context — they're separate agents.
- You can swap in a different reviewer without changing the primary agent's logic.
Why Subagents Protect Context¶
Here's a subtle but important point. When a primary agent calls a subagent, the subagent gets its own context window. The subagent's tool output (large test logs, verbose grep results) doesn't bloat the primary agent's memory.
Example: The test runner runs 500 tests. Logs are huge. The subagent processes them, extracts the key failure. It reports back: "3 tests failed, summary: X, Y, Z." The primary agent gets the summary, not the 50KB of logs.
This matters because: - Context is limited. A long conversation costs more and slows the model. - Attention matters. The primary agent stays focused on the high-level strategy. The subagent handles the low-level details.
So subagents aren't just role-based. They're also a context-protection mechanism.
Hands-On: Creating Your First Agent¶
You'll do this in the lab, but here's the overview:
opencode agent create
This drops you into an interactive prompt:
- Description: "What is this agent for?" (required for subagents)
- Mode: "Is it primary or a subagent?" (choose one)
- Model: "Which model? (default: claude-sonnet-4)"
- Prompt: "What are the system instructions?" (your role text)
- Permissions: For each tool, allow/ask/deny? (default: all allowed)
The command generates an agent file — a Markdown file with YAML frontmatter. It looks like:
---
name: "docs-writer"
mode: "primary"
model: "anthropic/claude-sonnet-4"
description: "Writes clear, beginner-friendly API documentation"
prompt: |
You are a documentation expert. Your role is to write clear,
beginner-friendly API docs...
permissions:
bash: deny
read: allow
edit: allow
webfetch: allow
# ... others: deny
---
That file lives in .opencode/agents/ (in your project or globally). Once you save it, you can invoke the agent with @docs-writer or set it as the default for a command.
Key Takeaways¶
- Agents are defined by mode, model, prompt, permissions, and description. Learn these five, and you can design any agent.
- Permissions are the boundary. Use them to prevent the agent from doing things it shouldn't.
- Fork an agent when the role or permissions are different. Otherwise, write a command.
- Subagents protect context. Their output doesn't bloat the primary agent's memory.
- The code-reviewer pattern is your template. Use it everywhere: a read-only subagent that audits, and a primary agent that acts on the feedback.
Next week, we'll combine multiple agents into workflows. But first, get comfortable creating an agent.