09 -Build your own
Harnesses & backends
Agent Swarm separates the run-level backend dial from the
per-agent dispatch surface. Understanding the difference lets you mix
harnesses in a single swarm, pin a specific agent to a specific CLI, and know
exactly what agent-swarm doctor is checking.
Two concepts, two schemas
The codebase uses two distinct types for dispatch. They look similar but control different things:
| Type | Values | What it controls |
|---|---|---|
BackendId |
claude | codex |
The run-level dial set by --backend or config.backend. Used for run metadata and the wrapperName field; does not directly shell out. |
HarnessId |
claude | codex | opencode | rovo |
The per-agent dispatch surface - the CLI that actually shells out for a given agent. Set by agent.harness in the agent definition. |
BackendId and HarnessId share two values
(claude and codex) but they are separate schemas.
Do not conflate them: opencode and rovo are valid
harnesses but are not valid backends. A run-level --backend codex
does not prevent an individual agent from dispatching via the
opencode harness.
BackendId is defined in src/schemas/backend-id.ts; HarnessId is defined in src/schemas/harness-id.ts. Both are Zod z.enum schemas - the source of truth for valid values.
How a harness is resolved for each agent
When a round runs, every agent gets its own harness resolved independently. The resolver walks this priority order - first that is set wins:
agent.harness- aHarnessIdset directly in the agent definition file. This is the strongest override and bypasses the run-level backend entirely.- Run-level
--backend/config.backend- theBackendIdfrom the CLI flag or project config, mapped to the matching harness. agent.backend- aBackendIdset in the agent definition. Weaker than a run-level override; mapped to the matching harness when neither of the above is set.
If none of the three is set, the agent dispatches via the claude
harness (the default). An agent with an explicit harness field
always uses that harness regardless of what --backend is passed
at the command line.
Prefer harness over backend in agent definitions when you want to pin a specific CLI. The harness field is unambiguous and does not depend on how BackendId maps to HarnessId.
Per-harness model flags
Every agent definition accepts an optional model string. When
set, it is passed to the harness CLI using that harness's own flag. The
mapping is:
| Harness | CLI binary | Model flag | Example |
|---|---|---|---|
claude |
claude |
--model |
claude --print --model claude-opus-4-5 - |
codex |
codex |
-m |
codex exec ... -m o3-mini - |
opencode |
opencode |
--model |
opencode run --model anthropic/claude-sonnet-4-5 |
rovo |
acli |
--model |
acli rovodev run --shadow -y --model rovo-default |
When model is omitted from the agent definition, the harness
uses its own default model. The model string is harness-specific - check the
documentation for each CLI to see valid model identifiers.
Pinning a harness in an agent definition
The bundled principal-engineer-opencode agent shows the pattern:
set harness: opencode in the agent definition and the agent will
always dispatch via OpenCode, regardless of the run-level
--backend flag.
# .agent-swarm/agents/principal-engineer-opencode.yml
name: principal-engineer-opencode
description: Engineering agent that dispatches via OpenCode.
persona: You are a principal engineer optimizing for correctness, maintainability, and practical execution.
harness: opencode
model: anthropic/claude-sonnet-4-5
prompt: |
You are the principal-engineer-opencode agent in a swarm.
Focus on implementation approach, system boundaries, and delivery feasibility.
Return only the shared swarm JSON contract.
You can also use backend: codex instead of
harness: codex if you want the agent-level preference to
participate in the run-level backend mismatch checks that
agent-swarm doctor reports. Use harness when you
want to pin opencode or rovo, since those are not
valid BackendId values.
To run a mixed-harness swarm - for example, two Claude agents and one OpenCode agent - select all three agents in your preset or config. Each dispatches independently via its own harness:
# agent-swarm run against a mixed preset
agent-swarm run 2 "Should we adopt the new data layer?" \
--agents product-manager,principal-engineer,principal-engineer-opencode
What doctor checks
agent-swarm doctor always probes all four harnesses -
Claude, Codex, OpenCode,
and Rovo - for availability and authentication, even when no
project config exists. This is the Harness inventory section
of the doctor report.
Each harness probe produces one of three outcomes:
| Status | Condition |
|---|---|
OK |
The harness CLI is found on PATH and authentication probes succeed. |
WARN |
The harness is missing or unauthenticated, but it is not required by any agent in your current config. The run can still proceed without it. |
FAIL |
The harness is missing or unauthenticated, and at least one configured agent requires it. The detail line shows required by: <agent-name>. |
Agent Swarm does not globally require any harness. A single-harness setup
passes doctor as long as the one harness its agents use is working - the
other three will show as WARN, not FAIL.
# probe all four harnesses and check your config
agent-swarm doctor
# example output (Harness inventory section)
Harness inventory
[OK] Claude Code: authenticated (claude 1.x.x)
[WARN] OpenAI Codex: not found (not required by current config)
[WARN] OpenCode: not found (not required by current config)
[WARN] Rovo Dev: not found (not required by current config)
Doctor exits 0 when all checks pass (warnings are non-fatal),
1 when any check fails, and 2 on an internal error.
Run agent-swarm doctor after adding a new agent that pins a different harness - it will tell you immediately whether that harness is installed and authenticated, and which agents depend on it.
Where next
- Agents & roles - the full agent definition schema, including the
harness,backend, andmodelfields. - Quickstart - install a harness CLI and verify it with doctor before your first run.
- CLI reference - the
--backendflag and all other run options. - Architecture - the harness adapter layer and how dispatch is wired through the pipeline.