How I Structure My Coding Agents: Separating Subagents from Skills
These days it seems like every one is sharing their coding agent setup, so why not :) if someone else can benefit from it, it’s well worth putting out there.
I mainly use OpenCode because I like to shop around models depending on what I’m building, but this setup is built to be completely portable—it works just as well in Claude Code if that’s your fancy.
You can find the entire configuration and the automation scripts in my repository: sorenmat/skills.
The Core Philosophy: Agents vs. Skills
To keep the AI focused and prevent context drift, I split my environment into two distinct primitives: Agents and Skills.
- Agents (Subagents): These run in completely isolated contexts. You invoke them explicitly to handle deep, parallelizable work, and they return a clean summary to the main session when they finish.
- Skills: This is procedural knowledge. The main agent dynamically loads a skill on-demand when a task matches the skill’s description. Think of them as “how-to” guardrails and workflows the AI must strictly follow while editing code.
The Workers: Dedicated Subagents
I use a handful of specialized subagents to offload repetitive or highly focused tasks from my primary development loop:
code-simplifier: Refines code for clarity and maintainability while strictly preserving runtime behavior.pr-check: Processes PR comments, automatically applies safe fixes, and drafts replies for the rest.review: Acts as a second pair of eyes checking for hidden bugs and performance bottlenecks before a commit.security: Handles secret detection and OWASP-style vulnerability scanning.
The Guardrails: On-Demand Skills
Skills prevent the AI from making structural assumptions. Instead of guessing how to interact with the project, the model pulls from these procedural files:
1. The Git Skill
Enforces strict Git flow rules. The agent is explicitly instructed to never push directly to master/main, never auto-merge PRs, always use branch-based development, and always plan out complex actions before executing them.
2. The Documentation Alignment Skill
Ensures the AI uses our project’s ubiquitous language, writes Architecture Decision Records (ADRs) for non-obvious engineering choices, and forces it to align on data relationships before writing actual logic.
The Secret Sauce: Dual-Dialect Frontmatter
The trick to making this setup fully cross-platform between OpenCode and Claude Code is combining both configuration dialects into a single Markdown file’s frontmatter.
Here is what a unified configuration looks like:
---
name: code-simplifier # Used by Claude Code
description: ... # Used by both platforms
mode: subagent # OpenCode specific
temperature: 0.1 # OpenCode specific
tools: # OpenCode specific strict permissions
write: false
edit: false
bash: true
---
A quick note on execution: OpenCode strictly enforces the
toolspermissions defined in the frontmatter. In Claude Code, subagents currently inherit the permissions of the parent session, so those constraints act more like strong prose guidelines there.
Tying It Together
To keep things synchronized across both tools, I use an idempotent install.sh script in the repo. It automatically backs up existing configurations and dynamically symlinks every agent and skill into both paths:
~/.claude/~/.config/opencode/
This means I can update my central repository, run the script, and instantly have my fine-tuned behaviors up to date in whichever CLI tool I decide to open.
The Bottom Line
Having a structured, model-agnostic approach saves countless hours of repetitive prompting. I can swap the underlying LLM to test the latest models in OpenCode while keeping my custom agent workflows entirely intact.
If you want to poke around or clone the setup, the repo is open: sorenmat/skills. Let me know if you end up adapting the subagent/skill split for your own workflow!