Install
$ agentstack add skill-agentworkforce-relay-choosing-swarm-patterns ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Choosing Swarm Patterns
Overview
The Agent Relay workflow engine (@relayflows/core) supports 24 swarm patterns via a single swarm.pattern field. Patterns are configured declaratively in YAML or programmatically via the workflow() fluent builder — there are no standalone fanOut(...) / hubAndSpoke(...) helpers. Pick the simplest pattern that solves the problem; add complexity only when the system proves it's insufficient.
Two ways to run a pattern
1. YAML (portable):
import { runWorkflow } from '@relayflows/core';
const run = await runWorkflow('workflows/feature-dev.yaml', {
vars: { task: 'Add OAuth login' },
});
2. Fluent builder (programmatic):
import { workflow } from '@relayflows/core';
const run = await workflow('feature-dev')
.pattern('hub-spoke')
.channel('swarm-feature-dev')
.agent('lead', { cli: 'claude', role: 'lead' })
.agent('developer', { cli: 'codex', role: 'worker', interactive: false })
.step('plan', { agent: 'lead', task: 'Plan {{task}}' })
.step('implement', { agent: 'developer', task: 'Implement: {{steps.plan.output}}', dependsOn: ['plan'] })
.run();
Both paths hit the same WorkflowRunner.
Quick Decision Framework
Is the task independent per agent?
YES → fan-out (parallel workers, hub collects)
Does each step need the previous step's output?
YES → Is it strictly linear?
YES → pipeline
NO → dag (parallel where possible, `dependsOn` edges)
Does a coordinator need to stay alive and adapt?
YES → hub-spoke (single-level hub + workers)
hierarchical (structurally identical in current impl; use for naming/intent)
Is the task about making a decision?
YES → Do agents need to argue opposing sides?
YES → debate (adversarial, full mesh)
NO → consensus (cooperative, full mesh + coordination.consensusStrategy)
Does the right specialist emerge during processing?
YES → handoff (sequential chain, one active at a time)
Do all agents need to freely collaborate?
YES → mesh (full peer-to-peer edges)
Is cost the primary concern?
YES → cascade (chain of increasingly capable agents; each step's prompt
decides whether to pass through or redo the prior output)
Pattern Reference (Core 10)
| # | Pattern | Topology (actual edges) | Best For | | --- | ---------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | 1 | fan-out | Hub broadcasts to N workers; workers reply to hub only | Independent subtasks (reviews, research, tests) | | 2 | pipeline | Linear chain (agenti → agent{i+1}) | Ordered stages (design → implement → test) | | 3 | hub-spoke | Hub ↔ spokes (bidirectional); no spoke-to-spoke | Dynamic coordination, lead reviews/adjusts | | 4 | consensus | Full mesh; decision via coordination.consensusStrategy | Architecture decisions, approval gates | | 5 | mesh | Full mesh (every agent ↔ every other) | Brainstorming, collaborative debugging | | 6 | handoff | Chain; passes control forward | Triage, specialist routing | | 7 | cascade | Chain of dependsOn steps; all run on success, downstream skipped on upstream failure (no built-in "fall through") | Cost optimization: cheap first, each step's prompt passes through or redoes | | 8 | dag | Edges from step dependsOn | Mixed dependencies, parallel where possible | | 9 | debate | Full mesh (same topology as mesh; roles drive behavior) | Rigorous adversarial examination | | 10 | hierarchical | Hub + subordinates (single-level in current impl) | Large teams; semantic distinction from hub-spoke |
> Heads up: hierarchical resolves to the same edge structure as hub-spoke in coordinator.ts:313-319. Multi-level tree topology is not currently implemented — use pattern name for intent, but expect the same runtime graph.
Additional Patterns (role-driven)
These 14 additional patterns exist in SwarmPattern (types.ts:114-139). The coordinator has role-based auto-selection heuristics (coordinator.ts:51-165), but they only fire when swarm.pattern is omitted — YAML validation requires it (runner.ts:2105-2117), so auto-selection is effectively a programmatic-API feature. In YAML, set swarm.pattern explicitly.
Topology is still resolved per-pattern once selected; the "Triggering roles" column reflects what the coordinator looks for to shape edges (per coordinator.ts:250-450):
| Pattern | Roles the topology keys off | Topology | | ----------------- | ------------------------------------------------------- | ---------------------------------------------- | | map-reduce | mapper + reducer | coordinator → mappers → reducers → coordinator | | scatter-gather | — | hub → workers → hub | | supervisor | supervisor | supervisor ↔ workers | | reflection | critic or reviewer (auto-select uses critic only) | producers → critic → producers (loop) | | red-team | attacker/red-team + defender/blue-team | adversarial mesh with optional judges | | verifier | verifier | producers → verifiers → back to producers | | auction | auctioneer | auctioneer → bidders → auctioneer | | escalation | tier-* | tiered chain, escalate up / report down | | saga | saga-orchestrator, compensate-handler | orchestrator ↔ participants | | circuit-breaker | primary + fallback/backup | try primary, fallback on failure | | blackboard | blackboard / shared-workspace | shared state hub | | swarm | hive-mind / swarm-agent | stigmergy-style | | competitive | — (declared explicitly) | independent parallel implementations + judge | | review-loop | implement* + 2+ reviewer* | implementer ↔ reviewers |
Structured Squad Review Loop
For serious implementation work, especially workflow generation or product-contract changes, prefer a composite squad-review-loop recipe over a plain single implementer plus final reviewer. This is a workflow authoring recipe built from existing patterns, not a separate SDK enum unless the local runner has added one.
Use this when the fastest reliable path is small teams of 2-3 agents working in parallel with live feedback:
- Split the work into bounded implementation squads. Each squad owns a non-overlapping file or subsystem scope.
- Give each squad an implementer plus a shadow/review partner. The shadow follows the implementer in real time, checks alignment with the spec, and posts concise feedback before the work drifts.
- Require the implementer to self-reflect before external review: compare the final diff against the spec, AGENTS.md / CLAUDE.md, recent local conventions, tests, and declared non-goals.
- Run an independent self-review/fresh-eyes agent that reads the actual files and recent repo context, not just the chat transcript.
- Send that review back to the implementer for one repair round.
- After squads converge, run a final two-agent review team, usually one Claude reviewer and one Codex reviewer, independently. They compare notes, merge findings, and produce one final verdict.
- Spawn fresh fix agents for final-review findings. Those fix agents self-reflect, then the final reviewers re-check the post-fix state until the spec is fully satisfied or a blocker is documented.
Pattern selection for this recipe:
- Use
supervisororhub-spokewhen a lead needs to coordinate live squads. - Use
review-loopwhen the main risk is code quality and feedback iteration. - Use
reflectionwhen critic feedback should loop directly back to producers. - Use
verifierwhen completion evidence matters more than design debate. - Use
competitiveonly when independent alternative implementations are useful; otherwise split by ownership scope.
Keep squads small. Two or three agents per squad is usually the useful limit: implementer, shadow/reviewer, and optionally test/validation owner. More agents belong in separate squads or in the final review team.
Pattern Details
All examples below use real API shapes (WorkflowBuilder / YAML), verified against @relayflows/core's builder.d.ts and schema.d.ts.
> YAML fragments vs complete configs: The per-pattern YAML snippets below are fragments that show only the pattern-relevant shape. A runnable YAML file also requires version: "1.0" and name: at the top (runner.ts:2105-2117). See the [Complete YAML Example](#complete-yaml-example) for the full structure. > > Topology edges exclude interactive: false agents. resolveTopology (coordinator.ts:218-237) drops non-interactive agents from the message graph — they run as one-shot subprocesses with no relay connection. Topology claims like "hub ↔ spokes" describe the interactive-agent edges; workers marked interactive: false are spawned and collected via stdout, not via relay messages.
1. fan-out — Parallel Workers
await workflow('review')
.pattern('fan-out')
.agent('lead', { cli: 'claude', role: 'lead' })
.agent('auth-rev', { cli: 'claude', role: 'worker', interactive: false })
.agent('db-rev', { cli: 'claude', role: 'worker', interactive: false })
.step('review-auth', { agent: 'auth-rev', task: 'Review auth.ts' })
.step('review-db', { agent: 'db-rev', task: 'Review db.ts' })
.run();
Workers run independently; hub aggregates. No inter-worker edges.
2. pipeline — Sequential Stages
swarm: { pattern: pipeline }
agents:
- { name: designer, cli: claude }
- { name: implementer, cli: codex, interactive: false }
- { name: tester, cli: codex, interactive: false }
workflows:
- name: build
steps:
- {
name: design,
agent: designer,
task: 'Design the API schema',
verification: { type: output_contains, value: DONE },
}
- {
name: implement,
agent: implementer,
dependsOn: [design],
task: 'Implement: {{steps.design.output}}',
}
- { name: test, agent: tester, dependsOn: [implement], task: 'Write integration tests' }
Each stage receives the previous stage's output via {{steps..output}}. Halts on step failure unless onError: retry / continue.
3. hub-spoke — Persistent Coordinator
await workflow('api-build')
.pattern('hub-spoke')
.channel('swarm-api')
.agent('lead', { cli: 'claude', role: 'lead' })
.agent('db-worker', { cli: 'claude', role: 'worker' }) // interactive by default — hub DMs it
.agent('api-worker', { cli: 'claude', role: 'worker' }) // interactive by default — hub DMs it
.step('models', { agent: 'db-worker', task: 'Build database models' })
.step('routes', { agent: 'api-worker', task: 'Build route handlers', dependsOn: ['models'] })
.step('review', { agent: 'lead', task: 'Review everything', dependsOn: ['routes'] })
.run();
Hub (picked via role: lead or first agent) stays on the channel and direct-messages interactive workers via the flat send_dm MCP tool, often exposed by workflow prompts as mcp__relaycast__send_dm.
> Don't set interactive: false on a hub-spoke worker if you want it to receive coordination DMs — resolveTopology strips non-interactive agents from the message graph (coordinator.ts:218-237). Use interactive: false only when the worker is a one-shot subprocess whose stdout you collect via {{steps.X.output}} without any mid-run coordination.
4. consensus — Cooperative Voting
swarm: { pattern: consensus }
agents:
- { name: perf, cli: claude, role: reviewer }
- { name: dx, cli: claude, role: reviewer }
- { name: sec, cli: claude, role: reviewer }
coordination:
consensusStrategy: majority # declarative marker: majority | unanimous | quorum
votingThreshold: 0.66
workflows:
- name: decide
steps:
- { name: evaluate-perf, agent: perf, task: 'Evaluate perf of Fastify migration' }
- { name: evaluate-dx, agent: dx, task: 'Evaluate DX of Fastify migration' }
- { name: evaluate-sec, agent: sec, task: 'Evaluate security of Fastify migration' }
Full-mesh topology. Caveat: coordination.consensusStrategy and votingThreshold are declared in CoordinationConfig (types.ts:768-772) but the runner has no built-in vote-tallying logic — the fields only influence coordinator auto-selection (coordinator.ts:63-64). To implement voting, aggregate the step outputs in a downstream lead/judge step that reads {{steps.evaluate-*.output}}.
5. mesh — Peer Collaboration
await workflow('debug-auth')
.pattern('mesh')
.channel('swarm-debug')
.agent('logs', { cli: 'claude' })
.agent('code', { cli: 'claude' })
.agent('repro', { cli: 'claude' })
.step('logs', { agent: 'logs', task: 'Check server logs' })
.step('code', { agent: 'code', task: 'Review auth code' })
.step('repro', { agent: 'repro', task: 'Write repro test' })
.run();
Every agent ↔ every other agent. Use for collaborative exploration without hierarchy.
6. handoff — Dynamic Routing
swarm: { pattern: handoff }
agents:
- { name: triage, cli: claude }
- { name: billing, cli: claude }
- { name: tech, cli: claude }
workflows:
- name: support
steps:
- { name: triage, agent: triage, task: 'Triage: {{request}}' }
- { name: billing, agent: billing, dependsOn: [triage], task: 'Handle billing' }
- { name: tech, agent: tech, dependsOn: [triage], task: 'Handle tech issues' }
Chain passes control forward. Note: The runner doesn't support "route to one branch and skip the others" declaratively — dependsOn steps all run when their dependencies complete, and skipping is only triggered by upstream failure (runner.ts:7057-7088). For true pick-one routing, have the triage step emit a routing token in its output and let each downstream step's prompt check {{steps.triage.output}} and no-op if it doesn't match.
7. cascade — Cost-Aware Fallthrough
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [AgentWorkforce](https://github.com/AgentWorkforce)
- **Source:** [AgentWorkforce/relay](https://github.com/AgentWorkforce/relay)
- **License:** Apache-2.0
- **Homepage:** https://agentrelay.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.