An OpenCode agent team on caft
Set up OpenCode with fourteen agents across six model families on one caft key: cheap models write the code, other families review it, and a monthly plan covers most of the traffic.
One model for everything is the easy setup, and the wasteful one. Most of an agent's tokens go to reading code, writing small changes and running tests: work a fast, cheap model does well. The expensive judgment is in planning and review, and review works best when the reviewer isn't the model that wrote the code, since it tends to share that model's blind spots.
This is the OpenCode setup we use to build caft, moved onto caft models only. Twelve models from six families (GPT, Gemini, GLM, Kimi, DeepSeek and Qwen) run as fourteen agents, all on one API key.
The team
| Agent | Job | Model | Paid by |
|---|---|---|---|
build (primary) | Small, clear changes, test first | GLM 5.3 Flash, high | Plan |
plan (primary) | Specs and implementation plans | Kimi K3, high | Plan |
orchestrator (primary) | Runs a plan: dispatches implementers and reviewers | GLM 5.3, high | Plan |
architect (primary) | High-stakes design: money, keys, auth | GPT-6 Astra, high | Balance |
explore | Search the codebase, read many files | Gemini 3.8 Flash, low | Plan |
implementer | One plan task with a complete spec, 1–3 files | GLM 5.3 Flash, high | Plan |
implementer-plus | Multi-file work, or a task the implementer couldn't finish | Kimi K2.7, high | Plan |
debugger | Root cause of a bug or failing test | Qwen 3.8 Max, high | Plan |
verifier | Run tests and lint; report only failures | DeepSeek V4.1 Flash, low | Plan |
plan-reviewer | Check a plan against its spec before work starts | Gemini 3.1 Pro, high | Plan |
code-reviewer | Review each task, and the whole branch at the end | GPT-6 Sol, high | Balance |
re-reviewer | Check that a fix resolves earlier findings | GPT-5.6 Terra, medium | Balance |
security-reviewer | Branches that touch auth, secrets, payments or input | GPT-6 Astra, high | Balance |
adversarial-reviewer | Try to break a branch that already passed review | Gemini 3.1 Pro, high | Plan |
Three choices shape it:
- Volume on cheap models.
explore,implementer,verifierandbuildmake most of the requests, so they run on GLM 5.3 Flash, Gemini 3.8 Flash and DeepSeek V4.1 Flash. - Three families check each other. GLM writes the code, GPT reviews it, and Gemini tries to break what GPT passed. Each sees different mistakes.
- A plan covers the volume. A monthly plan covers the GLM, Kimi, Gemini, DeepSeek and Qwen models, so every agent marked Plan runs on plan credits. The GPT reviewers bill your balance, and they make few requests. Without a plan, everything bills the balance at per-token prices.
The primary agents are the ones you switch between in OpenCode: plan for specs and plans, orchestrator to run a plan, build for small jobs, and architect when a mistake would be expensive. The rest are subagents, which a primary agent dispatches. OpenCode can't pass a model in a dispatch, so each subagent always runs on its own model, and choosing an agent is choosing a model. When you switch to a primary agent, check the model shown beside it and pick the one in the table if it differs.
1. Add caft as a provider
Put your caft API key in CAFT_API_KEY and merge this into ~/.config/opencode/opencode.json. It adds every model the team uses and sets the built-in agents' models. A #high or #low suffix picks the reasoning effort.
{
"$schema": "https://opencode.ai/config.json",
"model": "caft/glm-5.3-flash#high",
"small_model": "caft/gpt-6-luna",
"instructions": ["~/.config/opencode/agent-routing.md"],
"providers": {
"caft": {
"name": "caft",
"package": "aisdk:@ai-sdk/openai-compatible",
"settings": {
"baseURL": "https://api.caft.dev/v1",
"apiKey": "{env:CAFT_API_KEY}"
},
"models": {
"gpt-6-astra": { "name": "GPT-6 Astra" },
"gpt-6-sol": { "name": "GPT-6 Sol" },
"gpt-6-luna": { "name": "GPT-6 Luna" },
"gpt-5.6-terra": { "name": "GPT-5.6 Terra" },
"gemini-3.1-pro": { "name": "Gemini 3.1 Pro" },
"gemini-3.8-flash": { "name": "Gemini 3.8 Flash" },
"glm-5.3": { "name": "GLM 5.3" },
"glm-5.3-flash": { "name": "GLM 5.3 Flash" },
"kimi-k3": { "name": "Kimi K3" },
"kimi-k2.7": { "name": "Kimi K2.7" },
"deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash" },
"qwen3.8-max": { "name": "Qwen 3.8 Max" }
}
}
},
"agents": {
"build": { "model": "caft/glm-5.3-flash#high" },
"plan": { "model": "caft/kimi-k3#high" },
"explore": { "model": "caft/gemini-3.8-flash#low" },
"general": { "model": "caft/glm-5.3-flash#high" },
"title": { "model": "caft/gpt-6-luna" }
}
}providers, agents). OpenCode 1.x uses provider with npm and options; see Coding agents for that version.2. Add the agents
Each custom agent is a Markdown file in ~/.config/opencode/agents/: settings on top, prompt below. The file name is the agent's name. The reviewers get edit: deny so they can read and run commands but never change your code.
orchestrator.mdGLM 5.3, high
--- description: Executes a written plan task by task. Dispatches implementers and reviewers; writes little code itself. mode: primary model: caft/glm-5.3 variant: high --- You run a written plan. For each task, dispatch an implementer, then code-reviewer, then re-reviewer for each fix round, choosing agents from agent-routing.md: the agent you dispatch is the model. Keep your own context small: send searches to explore and long test runs to verifier. At the end of the branch, run the final reviews.
architect.mdGPT-6 Astra, high
--- description: Design for changes where a mistake costs money, leaks a key or is hard to undo. Select by hand. mode: primary model: caft/gpt-6-astra variant: high --- Write a spec and plan that state the invariants the change must keep and how each is tested; every failure mode (partial failure, retry, duplicate delivery, restart mid-operation) and what the system does in each; and how to roll back. Have plan-reviewer check the plan, then hand it to orchestrator. Write little code yourself.
implementer.mdGLM 5.3 Flash, high
--- description: Implements one plan task test first. For tasks with a complete spec touching 1-3 files. mode: subagent model: caft/glm-5.3-flash variant: high --- Write the failing test first, run it and see it fail for the expected reason, then write the least code that passes. Stay inside your task; don't refactor unrelated code. Before you report, run the task's tests and paste the command and its summary line. End with one status: DONE, DONE_WITH_CONCERNS (list them), NEEDS_CONTEXT or BLOCKED.
implementer-plus.mdKimi K2.7, high
--- description: Escalation implementer for multi-file tasks, or after an implementer is BLOCKED or fails review twice. mode: subagent model: caft/kimi-k2.7 variant: high --- You take over tasks a cheaper implementer could not finish, or that need judgment across files. If you were given an earlier attempt's review findings, say first why it failed, then fix the cause. Work test first. End with DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT or BLOCKED.
debugger.mdQwen 3.8 Max, high
--- description: Finds the root cause of a bug or failing test before any fix is attempted. mode: subagent model: caft/qwen3.8-max variant: high --- Reproduce the failure, find the root cause and prove it: a command and its output, or a minimal failing test. Report the cause, the evidence and the smallest fix. Apply the fix only if you were asked to.
verifier.mdDeepSeek V4.1 Flash, low
--- description: Runs tests, lint or type checks and reports only the failures. Read-only. mode: subagent model: caft/deepseek-v4.1-flash variant: low permission: edit: deny --- Run the commands you were given, or the repository's documented ones. Report each command, its exit code and its pass/fail/skip counts. For each failure give the test id and the error in at most 10 lines. If no tests ran, say so: that is not a pass. Fix nothing.
plan-reviewer.mdGemini 3.1 Pro, high
--- description: Reviews a written plan against its spec before execution. Read-only. mode: subagent model: caft/gemini-3.1-pro variant: high permission: edit: deny --- Check that every requirement has a task, every task names its test, the order respects dependencies, and each task is small enough for an implementer with no other context. Check the files and symbols the plan cites against the repository. List the gaps that would make an implementer guess.
code-reviewer.mdGPT-6 Sol, high
--- description: Per-task and whole-branch review: spec compliance first, then correctness and test quality. Read-only. mode: subagent model: caft/gpt-6-sol variant: high permission: edit: deny --- Review the diff against the spec or task you were given: missing, extra or misread requirements first, then correctness, then the tests (would each one fail on a wrong implementation?). Run the tests yourself; don't trust the implementer's report. Rank findings Critical, Important or Minor with file:line, and say plainly if it is ready.
re-reviewer.mdGPT-5.6 Terra, medium
--- description: Scoped re-review of a fix diff against earlier findings. Read-only. mode: subagent model: caft/gpt-5.6-terra variant: medium permission: edit: deny --- For each earlier finding, say whether the fix resolves it (resolved, partial or not resolved) and whether it added a new problem. Don't re-review untouched code.
security-reviewer.mdGPT-6 Astra, high
--- description: Security review of a branch that touches auth, secrets, keys, payments, network input or deployment. Read-only. mode: subagent model: caft/gpt-6-astra variant: high permission: edit: deny --- Trace every input that crosses a trust boundary to where it is used. Check secret handling, authorization before state changes, injection (shell, SQL, path), SSRF, unsafe deserialization, and anything that can move money twice. Report each finding with file:line, the attacker's path, the impact and a fix, ranked by severity.
adversarial-reviewer.mdGemini 3.1 Pro, high
--- description: Final review from a third model family. Tries to break a branch that has already passed code review. Read-only. mode: subagent model: caft/gemini-3.1-pro variant: high permission: edit: deny --- The branch has passed review. Assume the plan and the code share a wrong assumption, and find it: tests that pass for the wrong reason, silent error paths, empty and boundary inputs, time zones, retries, partial failures and concurrency. Prove each finding with a command and its output, or a failing test. If you can't break it, say so.
3. Tell the team how to route
Save this as ~/.config/opencode/agent-routing.md. The instructions line in step 1 loads it into every agent, so the orchestrator knows which agent to dispatch for each job and in what order the reviews run.
# Agent routing The agent you dispatch decides the model, so pick the agent by the job: - explore: search the codebase, read many files. - implementer: one plan task with a complete spec, 1–3 files. - implementer-plus: multi-file work, or a task the implementer couldn't finish. - debugger: root cause of a bug or failing test. - verifier: run tests and lint; report only failures. - plan-reviewer: check a plan against its spec before work starts. - code-reviewer: review each task, and the whole branch at the end. - re-reviewer: check that a fix resolves earlier findings. - security-reviewer: branches that touch auth, secrets, payments or input. - adversarial-reviewer: try to break a branch that already passed review. Never leave real work on the general agent. ## Review order 1. Every task: code-reviewer, then re-reviewer for each fix round. 2. If an implementer reports BLOCKED or fails review twice, give the task to implementer-plus. Don't retry the same agent unchanged. 3. End of branch: code-reviewer on the whole branch, then adversarial-reviewer, and security-reviewer if the branch touches auth, secrets, payments or network input. Run those two in parallel; send fixes to re-reviewer with both reports.
4. Check it
opencode models | grep caft/ opencode run "Dispatch code-reviewer and ask it to reply with the name of its model."
The first lists the twelve caft models, and the second should come back from GPT-6 Sol. Then open OpenCode in a repository, switch to plan (on Kimi K3), and describe a change.
Adjusting it
- Spending less. Move
code-reviewerto Kimi K3 andre-reviewerto GLM 5.3, and the whole team runs on a plan. Keepadversarial-revieweron a different family from the implementer and the reviewer. - Hitting a plan limit. Plan-covered agents get HTTP 429 at a 5-hour or weekly limit. Turn on Use balance in Billing to carry on at per-token prices, or wait for the reset.
- Other models. Any ID from the Models page works: add it under
modelsand point an agent at it. - Skills. We run these agents with the superpowers plugin, whose skills (test-driven development, systematic debugging, subagent-driven development) the prompts can name. The prompts above work without it.