Squads
Teams of agents collaborating over a shared blackboard.
What it is
A Squad is a named team of agents with an ordered pipeline of tasks and
an execution strategy. Agents collaborate through a shared blackboard — each task writes its
result to an output_key that downstream tasks read — with every write recorded in an audit
trail. Think of it as a project team where each member has a role and everyone shares a
whiteboard.
For when to reach for a squad versus a single agent or a workflow, see the decision guide.
When to use it
Use a squad when no single agent can hold the whole job — when you'd otherwise overload one agent with several unrelated responsibilities. Split them into specialists: research → write → review, or evidence → coverage → valuation → offer → compliance.
How it works
Process flow — sequential vs hierarchical:
Call flow — kickoff to result:
Under the hood the sequential processor topologically sorts the tasks (Kahn's algorithm), then
runs each in order. A task only sees blackboard entries written by its depends_on tasks (plus the
initial kickoff inputs) — unrelated branches are filtered out. Root tasks (no depends_on) receive
the raw kickoff context. Hierarchical squads instead run a single manager agent that is given
the agent roster and task list and delegates via a delegate tool.
Sub-features
- Process types — Sequential (dependency order) and Hierarchical (manager delegates).
- Task pipeline builder — per-task id, description, assigned agent, depends-on, output_key, expected output.
- Real-time validation — circular-dependency, duplicate-id, and invalid-agent detection.
- Run tab — JSON kickoff inputs; results show per-task status, answer, tools used, iterations, final output, audit trail, and the full blackboard.
Configuration parameters
These map directly to the squad content type. agents and tasks are JSON arrays of objects
(shapes below).
| Parameter | Type | Notes |
|---|---|---|
name | string (required) | Squad identity. |
slug | string (unique, read-only) | Auto-generated URL-safe id. |
description | text | Human-readable purpose. |
process | enum: sequential | hierarchical | Defaults to sequential. |
manager_agent | relation → agent | Required for hierarchical squads; ignored for sequential. |
agents | JSON array | Squad members. Defaults to []. |
tasks | JSON array | The task pipeline. Defaults to []. |
max_total_iterations | integer | Squad-wide budget, default 30 — not per-task (see below). |
active | boolean | Defaults to true; inactive squads cannot be kicked off. |
Agent object (each entry in agents[]):
{ "agent_slug": "researcher", "role": "Research topics thoroughly using available tools" }Task object (each entry in tasks[]):
{
"id": "write",
"description": "Write a detailed report from the research findings",
"agent_slug": "writer",
"depends_on": ["research"],
"output_key": "draft",
"expected_output": "A 600-word article with headings"
}output_key defaults to the task id when omitted, and expected_output is optional guidance
appended to the agent's goal.
max_total_iterations is squad-wide, not per-task. It is a single budget shared across the
whole pipeline. Each task consumes the agent's iteration count from this pool, and each agent's own
max_iterations is additionally capped to whatever budget remains. If the budget runs out, the
remaining tasks are written to the blackboard as (skipped — iteration limit reached) with status
skipped.
Dependencies
- Agents — squad members are existing agents referenced by
agent_slug(and amanager_agentfor hierarchical). An agent referenced by a task must exist and be active. - DMS Squad controller/service — CRUD, validation, slug generation, kickoff→poll.
- Squad processor — sequential/hierarchical execution, blackboard, audit trail, agent orchestration.
Tips & best practices
- Sequential vs hierarchical. Choose sequential when the order is known up front (research → write → edit) — it is more predictable and every dependency is explicit. Choose hierarchical only when the right order genuinely depends on intermediate results and you want a manager to decide at runtime; you trade determinism for flexibility.
- Name
output_keys for what they hold, not the step.findings,draft,final_copyread better downstream thantask1/task2. A clear key is what the next agent actually sees on the blackboard. - Wire
depends_ondeliberately. A task only receives blackboard entries from its declared dependencies (plus the kickoff inputs). Forget to list a dependency and the agent won't see that upstream output — even if the task ran earlier. - Keep the pipeline small. Three to five focused tasks beats a sprawling graph. More tasks means
more iterations against the shared
max_total_iterationsbudget and more places to fail. - Set roles tightly. Each
roleshould be a one-line job description ("Edit for clarity and accuracy"), not a second prompt. Overlapping roles make agents redo each other's work. - Manager-agent design (hierarchical). Pick a strong-reasoning agent as the manager and keep its
worker roster short with crisp roles — the manager only knows agents by their slug and role text.
Give workers the tools they need; the manager itself only gets
delegateandgenerate_text.
Anti-patterns
- One mega-task that asks a single agent to "research, write, and edit" — that's just an agent, not a squad. Split it or use Agents directly.
- Deep dependency chains where every task depends on every prior task — collapse them or you'll burn the iteration budget.
- Reusing the same
output_keyacross tasks — the later write silently overwrites the earlier one on the blackboard.
Concrete examples
A sequential research → write → edit squad. Members:
{
"process": "sequential",
"max_total_iterations": 30,
"agents": [
{ "agent_slug": "researcher", "role": "Research topics thoroughly using available tools" },
{ "agent_slug": "writer", "role": "Write clear, well-structured content from research" },
{ "agent_slug": "editor", "role": "Review and improve content for clarity and accuracy" }
],
"tasks": [
{
"id": "research",
"description": "Research {{context}} comprehensively",
"agent_slug": "researcher",
"depends_on": [],
"output_key": "findings"
},
{
"id": "write",
"description": "Write a detailed report from the research findings",
"agent_slug": "writer",
"depends_on": ["research"],
"output_key": "draft",
"expected_output": "A 600-word article with headings"
},
{
"id": "edit",
"description": "Polish the draft for clarity and accuracy",
"agent_slug": "editor",
"depends_on": ["write"],
"output_key": "final_copy"
}
]
}Kick it off with {"topic": "Benefits of AI in healthcare"}. An abridged kickoff response:
{
"data": {
"job_id": "squad_1710859200_a1b2c3",
"squad": "research-team",
"result": {
"squad": "Research & Writing Team",
"process": "sequential",
"final_output": "## research (by researcher)\n...\n\n## write (by writer)\n...\n\n## edit (by editor)\n...",
"task_results": {
"research": {
"status": "completed",
"agent": "researcher",
"answer": "Key findings on AI in healthcare...",
"tools_used": ["search_documents", "fetch_url"],
"iterations": 3
},
"write": {
"status": "completed",
"agent": "writer",
"answer": "Draft article...",
"tools_used": ["generate_text"],
"iterations": 2
},
"edit": {
"status": "completed",
"agent": "editor",
"answer": "Polished article...",
"tools_used": [],
"iterations": 1
}
},
"blackboard": {
"topic": "Benefits of AI in healthcare",
"findings": "Key findings on AI in healthcare...",
"draft": "Draft article...",
"final_copy": "Polished article..."
},
"audit_trail": [
{ "task_id": "_input", "agent_slug": "_system", "key": "topic", "timestamp": 1710859200.1 },
{ "task_id": "research", "agent_slug": "researcher", "key": "findings", "timestamp": 1710859210.4 },
{ "task_id": "write", "agent_slug": "writer", "key": "draft", "timestamp": 1710859230.8 },
{ "task_id": "edit", "agent_slug": "editor", "key": "final_copy", "timestamp": 1710859245.3 }
],
"processing_time": 45.2
}
}
}Note the final_output is the per-task answers stitched together under ## <task> (by <agent>)
headings, the blackboard holds the last value written under each output_key (initial inputs
included), and the audit_trail records every write as {task_id, agent_slug, key, timestamp}.
Limitations
- More moving parts than a single agent — less deterministic; bound execution with
max_total_iterations. - Save is blocked while validation errors (circular/duplicate/invalid-agent) exist.
- Live per-task progress monitoring during a run is coming soon — today you kick off, poll, and
inspect the final
task_results/audit_trail.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Save is disabled, red "Circular" badge | Tasks form a dependency cycle (A → B → A). The processor's topological sort would reject it (Circular dependency detected). | Break the cycle — dependencies must flow one direction. |
| Red "Duplicate ID" badge | Two tasks share the same id. | Rename one; id must be unique within the squad. |
| Red "Invalid agent" badge | A task's agent_slug is not a squad member. | Add that agent to the squad, or reassign the task to a listed member. |
Task status error, "Agent '…' not found or inactive" | The assigned agent was deleted or deactivated after the squad was built. | Re-activate the agent or reassign the task; the pipeline continues with that task marked error. |
| A downstream agent ignores upstream work / "blackboard variable not found" | The task's depends_on doesn't list the upstream task, so its output_key is filtered out of context. | Add the upstream task id to depends_on so its output_key reaches this task. |
Remaining tasks show skipped, reason iteration_limit | The squad-wide max_total_iterations budget was exhausted earlier in the pipeline. | Raise max_total_iterations, shorten the pipeline, or lower per-agent max_iterations. |
When a member agent fails mid-pipeline, the squad does not abort: the processor records that
task's status as error, writes an (error: …) marker to its output_key, and continues to the
next task. Check task_results for the failing task and the audit_trail to see what was written.
How to test
Happy path (sequential):
- Create two agents —
researcherandwriter— and activate them. - Create a Sequential squad, add both as members with roles, and define two tasks:
research(agent = researcher, no deps,output_key: findings) andwrite(agent = writer,depends_on: [research],output_key: draft). - On the Run tab, kick off with
{"topic": "Benefits of AI in healthcare"}; poll until complete. - Inspect the result:
task_results.write.answershould build onfindings; theblackboardshould containtopic,findings, anddraft; theaudit_trailshould list a_inputwrite plus one write per task in dependency order.
Negative path (circular dependency):
- In the Tasks tab, set
research.depends_on = [write]whilewrite.depends_on = [research]. - Confirm the red "Circular" warning appears and Save is blocked — the squad cannot be
persisted (and the processor would reject the graph with
Circular dependency detected).
Cross-links & roadmap
- Agents — squad members are individual agents.
- Workflows, agents & squads — when to choose each.
- Roadmap: live squad-progress monitoring (per-task status streamed during a run) is coming soon.
APIs used
| Method | Path | Purpose |
|---|---|---|
GET / POST | /api/squads | List / create squads |
GET / PUT / DELETE | /api/squads/:id | Read / update / delete |
POST | /api/squads/:id/kickoff | Execute the squad |