07 -Build your own
Writing an agent
An agent is a single YAML or Markdown file with a name, a persona, and a
prompt. Drop it into .agent-swarm/agents/ and the registry picks
it up automatically - no code wiring required.
Two formats, one schema
You can author agents as plain .yml files or as
.md files with YAML frontmatter. Both are validated against
the same Zod schema at load time. Choose whichever fits your workflow -
Markdown is handy when you want the prompt to read naturally in a text
editor or code review.
YAML agent (.yml)
# .agent-swarm/agents/security-reviewer.yml
name: security-reviewer
description: Reviews code and architecture changes for security vulnerabilities and trust-boundary drift.
persona: You are a paranoid but practical security engineer. You look for real exploitable
issues, not theoretical edge cases, and you always propose a concrete fix alongside
each finding.
prompt: |
You are the security-reviewer agent in a swarm.
Focus on authentication gaps, injection vectors, broken trust boundaries,
insecure defaults, and secrets in the wrong place.
Prefer concrete failure modes over vague risk language.
Return only the shared swarm JSON contract with these fields:
agent, round, stance, recommendation, reasoning, objections, risks,
changesFromPriorRound, confidence, openQuestions
Markdown agent with YAML frontmatter (.md)
<!-- .agent-swarm/agents/data-steward.md -->
---
name: data-steward
description: Evaluates proposals for data-privacy compliance and retention risk.
persona: You are a data-governance specialist who reads every schema change through
the lens of GDPR, CCPA, and internal retention policy.
harness: opencode
model: claude-opus-4-5
---
You are the data-steward agent in a swarm.
Focus on PII exposure, retention periods, consent signals, and cross-border
data flow. Call out any field that could identify a user even after anonymisation.
Return only the shared swarm JSON contract with these fields:
agent, round, stance, recommendation, reasoning, objections, risks,
changesFromPriorRound, confidence, openQuestions
In a Markdown agent the text after the closing --- of the frontmatter becomes the prompt. You can still use an explicit prompt: key in the frontmatter if you prefer everything in one block; the frontmatter key wins when both are present.
Agent fields
Every field is validated by AgentDefinitionSchema in src/schemas/agent-definition.ts. Unknown keys are passed through, but the fields below are the only ones the runtime acts on.
| Field | Required | Type | Description |
|---|---|---|---|
name |
Yes | string |
Unique identifier for the agent. Must match ^[a-z0-9][a-z0-9_-]*$ - lowercase letters, digits, hyphens, and underscores; must start with a letter or digit. Used as the key in presets and run artifacts. |
description |
Yes | string |
One-line human-readable summary of the agent's role. Shown in agent-swarm doctor output and in the agent registry listing. |
persona |
Yes | string |
The agent's identity and disposition. Written in second person ("You areā¦"). Frames how the agent interprets its task before the prompt is applied. |
prompt |
Yes | string or { file: string } |
The task instructions sent to the harness. Either an inline string (including YAML block scalars with |) or a file reference - { file: "path/to/prompt.txt" } - resolved relative to the agent file's location. |
backend |
No | claude | codex |
The run-level backend to request for this agent. Defaults to claude. Used when no harness is set and the run has no backend override. Note that backend and harness are distinct: backend is the coarse run-level dial; harness is the per-agent dispatch surface. |
harness |
No | claude | codex | opencode | rovo |
The specific harness CLI this agent should run on. When set, it takes precedence over the run-level --backend flag and the agent's own backend value. Use this to pin an agent to a particular harness regardless of what the rest of the swarm uses. |
model |
No | string |
Model identifier to pass to the harness CLI (e.g. claude-opus-4-5). The exact flag used depends on the resolved harness: claude --model, codex -m, opencode --model, or acli rovodev run --model. Omit to let the harness use its default. |
Start with just name, description, persona, and prompt. Add harness or model only when you have a specific reason to diverge from the swarm's default execution surface.
Registry resolution
When the runtime loads agents it searches six roots in order and stops at the first match for a given name. This means a project-level agent silently overrides a bundled one of the same name - a deliberate affordance for customisation.
| Priority | Scope | Root |
|---|---|---|
| 1 (highest) | Project - current | .agent-swarm/agents/ |
| 2 | Project - legacy | .swarm/agents/ |
| 3 | User - current | ~/.agent-swarm/agents/ |
| 4 | User - legacy | ~/.swarm/agents/ |
| 5 | Bundled | dist/agents/bundled/ |
Resolution rules to keep in mind:
- First match wins. The registry stops at the first root where an agent with the requested name is found.
- Same-name override is allowed across scopes. A project agent named
product-managershadows the bundledproduct-managerwithout error. - Duplicates inside one root are an error. Two files in the same directory that resolve to the same agent name will fail at load time.
- Legacy roots are read-only fallbacks. The
.swarm/paths are searched after their.agent-swarm/counterparts during the migration window; new agents should always be written to the.agent-swarm/root.
Agents in subdirectories (e.g. .agent-swarm/agents/product/product-manager.yml) are discovered recursively. The agent's name field - not its filename - is the registry key.
Prompt file references
For longer prompts, or when you want to version a prompt separately from its
metadata, use the file reference form of prompt:
# .agent-swarm/agents/legal-reviewer.yml
name: legal-reviewer
description: Flags contractual and regulatory risk in product decisions.
persona: You are an in-house counsel who reads every launch proposal for
indemnification exposure, IP risk, and regulatory tripwires.
prompt:
file: prompts/legal-reviewer.txt
The path is resolved relative to the agent file's location, so
prompts/legal-reviewer.txt would sit at
.agent-swarm/agents/prompts/legal-reviewer.txt.
Overriding a bundled agent
Bundled agents like product-manager and code-reviewer
are starting points, not constraints. To customise one, copy its YAML to your
project root and edit it - the project-scope copy takes over automatically:
# Copy the bundled agent into your project
mkdir -p .agent-swarm/agents
cp "$(npm root -g)/@calvinnwq/agent-swarm/dist/agents/bundled/product/product-manager.yml" \
.agent-swarm/agents/product-manager.yml
# Edit persona, prompt, harness, model - the project copy wins
The override is keyed on the name field, not the filename. Your file can be named anything as long as the name: value matches the bundled agent you want to replace.
Where next
- Composing a swarm - wire your agents into a preset and choose rounds, decision vocabulary, and resolution mode.
- Harnesses and backends - understand the
backendvs.harnessdistinction and how the runtime resolves which CLI each agent runs on. - CLI reference - every flag, including per-run backend overrides.