Quick Reference
Modules Covered
| Module | Source | Version |
|---|---|---|
| Team Templates | src/teams/templates.ts | v1.4 |
| GSD Templates | src/teams/gsd-templates.ts | v1.4 |
| Team Validator | src/teams/team-validator.ts | v1.4 |
| Team Store | src/teams/team-store.ts | v1.4 |
| Team Wizard | src/teams/team-wizard.ts | v1.4 |
| Agent Generator | src/teams/team-agent-generator.ts | v1.4 |
| Cost Estimator | src/teams/cost-estimator.ts | v1.4 |
| Inter-Team Bridge | src/teams/inter-team-bridge.ts | v1.4 |
Prerequisites
- GS-1: Installation & Setup
- GS-2: Core Concepts
- Skills vs Agents vs Teams
- GSD initialized in project (
.planning/directory exists)
Topologies at a Glance
| leader-worker | 1 lead delegates to N parallel workers |
| pipeline | Sequential stages with blockedBy dependencies |
| swarm | Workers self-claim tasks from shared queue |
| router | 1 router classifies and directs to specialists |
| map-reduce | Orchestrator splits work, workers process, results consolidated |
| custom | User-defined topology |
Storage Locations
Team configs:
.claude/teams/{team-name}/config.json # project scope
~/.claude/teams/{team-name}/config.json # user scope
Agent files:
.claude/agents/{agent-id}.md # always project scope
Technical Specifications
| Topologies | 6 (leader-worker, pipeline, swarm, router, map-reduce, custom) |
| Member Roles | 7 (leader, worker, reviewer, orchestrator, specialist, router, reducer) |
| Models | 3 (haiku, sonnet, opus) |
| Backends | 3 (in-process, tmux, iterm2) |
| Validation Checks | 7 (VALID-01 through VALID-07 + inter-team) |
| Max Workers per Template | 10 |
| Name Format | Lowercase alphanumeric + hyphens, max 64 chars |
Related Capabilities
Getting Started: What Are Agent Teams?
An agent team is a group of Claude Code agents that coordinate on a shared task. Instead of a single agent doing everything, teams split work across specialized members — a coordinator delegates, workers execute in parallel, and results are synthesized into a unified output.
When to use teams:
- Parallel research — multiple dimensions investigated simultaneously
- Adversarial debugging — competing hypotheses explored by independent investigators
- Pipeline processing — sequential stages where each transforms the output of the previous
- Classification and routing — incoming work sorted and dispatched to domain specialists
- Large-scale decomposition — a problem too big for one agent split into parallel chunks
When NOT to use teams:
- Simple, self-contained tasks that one agent handles well
- Tasks where coordination overhead exceeds the parallelism benefit
- Exploratory work where the problem is not yet well-defined enough to decompose
For students: Multi-agent collaboration is a pattern from distributed systems. Think of it like a group project where each person has a defined role. The coordinator (lead agent) breaks the project into tasks. Workers pick up tasks, complete them, and report results. The key difference from a human group project: agents communicate through structured messages and task queues rather than chat, which makes coordination predictable and auditable.
Building Your First Team
The fastest way to create a team is the interactive wizard. Run it from the CLI:
skill-creator team create
The wizard walks you through five steps:
- Select a pattern — choose from leader-worker, pipeline, swarm, router, or map-reduce
- Name your team — lowercase alphanumeric with hyphens (e.g.,
my-research-team) - Add a description — what the team does (optional, defaults provided per pattern)
- Set worker count — how many workers/stages/specialists (1–10, default: 3)
- Choose scope — project (
.claude/teams/) or user (~/.claude/teams/)
The wizard generates two things:
- A team config at
.claude/teams/{name}/config.json— the team definition - Agent files at
.claude/agents/{agent-id}.md— one per member, with role-aware prompts
Non-interactive creation for scripts and CI:
skill-creator team create \
--name my-research-team \
--pattern leader-worker \
--members 4 \
--scope project \
--description "Parallel research across technology dimensions"
Both paths produce identical output. The non-interactive path throws on validation errors rather than prompting for correction.
Anatomy of a Team Config
Every team config is a JSON file with this structure:
{
"name": "my-research-team",
"description": "Parallel research across technology dimensions",
"leadAgentId": "my-research-team-lead",
"createdAt": "2026-02-24T10:00:00.000Z",
"members": [
{
"agentId": "my-research-team-lead",
"name": "Lead",
"agentType": "coordinator",
"tools": ["Read", "Write", "Bash", "Glob", "Grep",
"TaskCreate", "TaskList", "TaskGet", "TaskUpdate",
"SendMessage", "TeammateTool"]
},
{
"agentId": "my-research-team-worker-1",
"name": "Worker 1",
"agentType": "worker",
"tools": ["Read", "Write", "Edit", "Bash", "Glob", "Grep",
"WebFetch", "WebSearch",
"TaskGet", "TaskUpdate", "SendMessage"]
}
],
"version": 1,
"topology": "leader-worker"
}
Key constraints enforced by the schema:
leadAgentIdmust match exactly one member'sagentIdmembersmust have at least one entry- All
agentIdvalues must be unique within the team - If
topologyis set, topology-specific rules are validated (e.g., leader-worker requires a coordinator/orchestrator lead)
Topology Selection Guide
Choosing the right topology is the most important design decision for a team. Each topology suits a different kind of work:
Leader-Worker
Pattern: 1 coordinator + N parallel workers
Best for: Independent tasks that can run in parallel with a single point of synthesis
Example: Research across four dimensions (stack, features, architecture, pitfalls) where each researcher works independently and a synthesizer combines findings
// Generates: 1 lead (coordinator) + N workers
const team = generateLeaderWorkerTemplate({
name: 'my-team',
workerCount: 4
});
Coordination tools: Lead gets TaskCreate, TaskList, TaskGet, TaskUpdate, SendMessage, TeammateTool. Workers get TaskGet, TaskUpdate, SendMessage plus file/web tools.
Pipeline
Pattern: 1 orchestrator + N sequential stages
Best for: Multi-step transformations where each stage depends on the output of the previous
Example: Code review pipeline — Stage 1: static analysis, Stage 2: security audit, Stage 3: performance review
// Generates: 1 lead (orchestrator) + N stages with blockedBy chains
const team = generatePipelineTemplate({
name: 'review-pipeline',
workerCount: 3 // 3 sequential stages
});
// Tasks: stage-1 -> stage-2 (blockedBy: stage-1) -> stage-3 (blockedBy: stage-2)
Key difference: Tasks have explicit blockedBy/blocks dependency chains. Stage 2 cannot start until Stage 1 completes.
Swarm
Pattern: 1 coordinator + N self-organizing workers
Best for: Large task backlogs where any worker can pick up any task
Example: Batch file processing — 50 files need formatting, any worker can grab the next unprocessed file
// Generates: 1 lead (coordinator) + N workers with TaskList for self-claiming
const team = generateSwarmTemplate({
name: 'batch-processor',
workerCount: 5
});
Key difference: Workers have TaskList so they can browse and self-claim tasks. No explicit assignment from the lead — workers pull work autonomously.
Router
Pattern: 1 router + N specialists
Best for: Heterogeneous work that needs classification before execution
Example: Support ticket triage — router classifies each ticket and sends it to the right specialist (billing, technical, account management)
// Generates: 1 router + N specialists
const team = generateRouterTemplate({
name: 'support-triage',
workerCount: 3 // 3 specialist domains
});
Key difference: Router has classification tools but no file-write capability. It analyzes and delegates; specialists execute.
Map-Reduce
Pattern: 1 orchestrator + N parallel workers with fan-out/fan-in
Best for: Problems that decompose into independent chunks requiring consolidation
Example: Codebase analysis — orchestrator splits the repo into N directories, each worker analyzes their directory, orchestrator consolidates findings
// Generates: 1 orchestrator + N workers
// Tasks: map-split -> worker-chunk-1..N (all blockedBy: map-split)
const team = generateMapReduceTemplate({
name: 'code-analysis',
workerCount: 4
});
Key difference: Two-phase task structure. The map task splits work; all worker tasks are blocked by the map task. Orchestrator has REDUCER_TOOLS for consolidation.
Decision Matrix
| Factor | Leader-Worker | Pipeline | Swarm | Router | Map-Reduce |
|---|---|---|---|---|---|
| Task independence | High | Low (sequential) | High | High | High |
| Needs classification? | No | No | No | Yes | No |
| Needs consolidation? | Optional | Last stage | Optional | Optional | Yes (critical) |
| Order matters? | No | Yes | No | No | No |
| Worker autonomy | Medium | Low | High | Low | Medium |
| Best member count | 2–6 | 2–5 | 3–10 | 2–5 | 3–8 |
For professionals: These topologies map directly to distributed systems patterns. Leader-worker is the classic coordinator pattern (ZooKeeper, Kubernetes controller). Pipeline is a staged processing chain (Unix pipes, Apache Kafka Streams). Swarm is work-stealing (Go scheduler, Java ForkJoinPool). Router is content-based routing (RabbitMQ topic exchanges, nginx upstream routing). Map-reduce is the canonical Hadoop/Spark pattern. The key architectural insight: topology is a first-class configuration choice, not an emergent property — you declare the communication pattern and the framework enforces it through tool assignment and task dependency structures.
GSD Workflow Integration
Teams integrate with GSD at three points: research phases, execution phases, and debugging sessions.
Research Teams
The built-in generateGsdResearchTeam() creates a 5-member team (1 synthesizer + 4 researchers) pre-configured for parallel ecosystem investigation:
- Stack researcher — languages, frameworks, libraries, runtime environments
- Features researcher — API surface, extensibility points, integration options
- Architecture researcher — scalability, modularity, data flow, deployment topology
- Pitfalls researcher — known limitations, failure modes, security concerns, migration risks
- Synthesizer — combines all four dimensions into a unified research report
Used during /gsd:research-phase to parallelize what would otherwise be a serial investigation.
Debugging Teams
The built-in generateGsdDebuggingTeam() creates a 4-member adversarial team (1 coordinator + 3 investigators):
- Alpha — primary hypothesis investigator (most likely explanation)
- Beta — adversarial investigator (challenges Alpha's hypothesis, explores alternatives)
- Gamma — environmental investigator (infrastructure, dependencies, configuration)
- Coordinator — forms hypotheses, dispatches investigators, synthesizes root cause analysis
Used during /gsd:debug to investigate bugs from multiple angles simultaneously.
Execution Phase Teams
For /gsd:execute-phase, you can create custom teams to parallelize phase work. If a phase plan has independent tasks, a leader-worker team lets multiple workers execute tasks concurrently while the lead tracks progress and resolves conflicts.
Member Configuration
Each team member is defined by these fields:
| Field | Type | Required | Description |
|---|---|---|---|
agentId | string | Yes | Unique identifier within the team, maps to .claude/agents/{agentId}.md |
name | string | Yes | Display name |
agentType | string | No | Role: coordinator, worker, orchestrator, specialist, router, reducer |
model | string | No | Model alias: haiku (fast), sonnet (balanced, default), opus (highest capability) |
tools | string[] | No | Assigned tools (auto-populated from templates) |
prompt | string | No | Initial instructions for this member |
backendType | string | No | Process backend: in-process, tmux, or iterm2 |
cwd | string | No | Working directory for this member |
planModeRequired | boolean | No | Whether this member must run in plan mode |
Tool Assignment by Role
Templates automatically assign tools based on member role. Here is the complete mapping:
| Role | Tools |
|---|---|
| Leader/Coordinator | Read, Write, Bash, Glob, Grep, TaskCreate, TaskList, TaskGet, TaskUpdate, SendMessage, TeammateTool |
| Worker (leader-worker) | Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch, TaskGet, TaskUpdate, SendMessage |
| Pipeline Stage | Read, Write, Edit, Bash, Glob, Grep, TaskGet, TaskUpdate, SendMessage |
| Swarm Worker | Read, Write, Edit, Bash, Glob, Grep, TaskList, TaskGet, TaskUpdate, SendMessage |
| Router | Read, Bash, Glob, Grep, TaskCreate, TaskList, TaskGet, TaskUpdate, SendMessage, TeammateTool |
| Reducer/Orchestrator | Read, Write, Bash, Glob, Grep, TaskCreate, TaskList, TaskGet, TaskUpdate, SendMessage, TeammateTool |
Notice the key differences: workers get Edit and web tools but not TaskCreate; leaders get task management tools (TaskCreate, TeammateTool) but not Edit or web tools; routers cannot Write files (they classify and delegate, not execute); swarm workers uniquely get TaskList for self-claiming.
Model Selection and Cost
The cost estimator provides per-member and total estimates based on model pricing and topology heuristics:
| Model | Input (per 1M tokens) | Output (per 1M tokens) | Best For |
|---|---|---|---|
haiku | $0.25 | $1.25 | Simple classification, routing, status checks |
sonnet | $3.00 | $15.00 | Balanced work — coordination, synthesis, standard coding |
opus | $15.00 | $75.00 | Complex reasoning, deep research, adversarial debugging |
Coordinator roles receive a 1.5x token multiplier in cost estimates because they handle delegation and synthesis in addition to their own work. Typical cost per invocation for a 4-member leader-worker team with sonnet workers: $0.15–$0.60.
Team Validation
The validateTeamFull() orchestrator runs seven checks in sequence:
| Check | ID | Type | What It Catches |
|---|---|---|---|
| Schema validation | VALID-01 | Error | Missing required fields, invalid types, empty members array |
| Member resolution | VALID-02 | Info | Agent files missing from .claude/agents/ (with fuzzy name suggestions) |
| Skill conflicts | VALID-03 | Warning | Cross-member skill overlap detected via semantic similarity (≥0.85) |
| Role coherence | VALID-04 | Warning | Different-role members with near-duplicate descriptions |
| Task cycles | VALID-05 | Error | Circular blockedBy dependencies (Kahn's algorithm, O(n+m)) |
| Tool overlap | VALID-06 | Warning | Multiple members sharing write-capable tools (Write, Edit, MultiEdit) |
| Topology rules | VALID-07 | Error | Topology-specific violations (e.g., leader-worker without a coordinator lead) |
Errors are blocking — the team config is invalid and must be fixed. Warnings are informational — the team will work but you may want to address potential issues.
# Validate a specific team
skill-creator team validate my-team
# Validate all teams
skill-creator team validate --all
Missing agent suggestions: When VALID-02 finds a missing agent file, it searches for similar names using Levenshtein distance (≤2) and shared prefixes (≥4 characters). If your team references my-team-woker-1, it will suggest my-team-worker-1.
Inter-team validation: When multiple teams declare outputTo/inputFrom links, the validator checks that all referenced team names exist, flags consistency mismatches, and runs cycle detection to prevent deadlocks between teams.
For sysadmins: Team files live in .claude/teams/{name}/config.json (project scope) or ~/.claude/teams/{name}/config.json (user scope). Agent files always go to .claude/agents/ at project scope due to a Claude Code discovery limitation (bug #11205). For monitoring, watch validation output — warnings about tool overlap and skill conflicts are early indicators that a team's responsibilities are not cleanly separated. The TeamStore enforces path safety via validateSafeName() and assertSafePath(), preventing path traversal attacks through crafted team names.
Communication Patterns
Agents coordinate through a structured message and task system. Here are the primary communication tools:
| Tool | Purpose | Who Uses It |
|---|---|---|
TaskCreate | Create a new task in the team's task queue | Leaders, orchestrators, routers |
TaskList | Browse available tasks (for self-claiming or monitoring) | Leaders, swarm workers, routers |
TaskGet | Read details of a specific task | All members |
TaskUpdate | Change task status, claim a task, report completion | All members |
SendMessage | Send a message to another agent's inbox | All members |
TeammateTool | Direct coordination with a specific teammate | Leaders, orchestrators, routers |
Message Types
The team system supports structured message types for specific coordination events:
shutdown_request/shutdown_response— graceful team shutdown protocoltask_completed— notification that a task has finishedplan_approval_request/plan_approval_response— plan-mode approval flowjoin_request— dynamic member joining
The message type system is extensible — the type is a union of known types with string, so custom message types work without schema changes.
Task Lifecycle
Tasks move through three statuses: pending → in_progress → completed. Tasks can have:
owner— the agent ID that claimed the taskblockedBy— task IDs that must complete firstblocks— task IDs that depend on this taskactiveForm— present-continuous description for spinner display (e.g., "Investigating root cause")
Scaling Considerations
When to Add More Workers
- Task queue backlog growing — if pending tasks consistently outnumber in-progress tasks, add workers
- Wall-clock time matters more than cost — more workers means faster parallel completion at higher token cost
- Task independence is high — adding workers only helps when tasks can run concurrently
When to Switch Topology
- Leader-worker → Pipeline: When you realize tasks have natural ordering dependencies
- Leader-worker → Swarm: When task assignment by the leader becomes a bottleneck
- Router → Leader-worker: When classification is not needed — all tasks go to the same type of worker
- Swarm → Map-reduce: When you need a consolidation step after parallel processing
Cost vs. Capability Trade-offs
- Use haiku for workers on simple, well-defined tasks (formatting, data extraction)
- Use opus for specialists on tasks requiring deep reasoning (research, debugging)
- Use sonnet for coordinators — they need to understand context and delegate, not perform deep analysis
- Coordination multiplier: Leaders, routers, and orchestrators use ~1.5x the tokens of a worker due to delegation overhead
Inter-Team Communication
When multiple teams need to coordinate, use outputTo/inputFrom declarations in the team config. The inter-team bridge validates that:
- All referenced team names exist
outputTo/inputFromdeclarations are consistent (team A outputs to B, team B declares input from A)- No circular dependencies exist between teams (detected via Kahn's algorithm)
For professionals: The inter-team cycle detection uses the same Kahn's algorithm as intra-team task cycle detection, applied at the team granularity instead of the task granularity. This is a config-time validator, not a runtime message broker — it catches architectural deadlocks before agents start executing. The validation is O(n+m) where n is team count and m is link count, so it scales to arbitrarily large team networks without performance concern.
Team Configuration
Teams are stored as JSON files in .claude/teams/:
{
"name": "research-team",
"description": "Parallel research across multiple dimensions",
"leadAgentId": "research-synthesizer",
"members": [
{ "agentId": "research-synthesizer", "name": "Synthesizer", "agentType": "coordinator", "model": "sonnet" },
{ "agentId": "researcher-alpha", "name": "Alpha", "agentType": "specialist", "model": "opus" }
],
"createdAt": "2026-01-15T10:00:00Z"
}
Each member references an agent file in .claude/agents/. The leadAgentId must match one member's agentId.
Team Validation
Team validation checks schema compliance, topology rules, tool overlap, skill conflicts, and role coherence:
skill-creator team validate my-team # Validate specific team
skill-creator team validate --all # Validate all teams
Errors are blocking (invalid schema, missing lead, duplicate IDs, topology violations, dependency cycles). Warnings are informational (tool overlap, skill conflicts, role coherence).
GSD Workflow Templates
Two built-in templates for GSD workflows:
| Template | Members | Pattern | Use Case |
|---|---|---|---|
| Research Team | 5 (1 synthesizer + 4 researchers) | leader-worker | Parallel ecosystem research |
| Debugging Team | 4 (1 coordinator + 3 investigators) | leader-worker | Adversarial debugging |
import { generateGsdResearchTeam, generateGsdDebuggingTeam } from 'gsd-skill-creator';
const research = generateGsdResearchTeam();
const debugging = generateGsdDebuggingTeam();
See GSD-TEAMS.md for detailed workflow analysis and COMPARISON.md for choosing the right abstraction.
Calibrating Activation Thresholds: Source Code Reference
The threshold optimizer (src/calibration/threshold-optimizer.ts) uses F1 score optimization via grid search to find thresholds that maximize balanced accuracy between precision and recall.
ThresholdOptimizer Grid Search
The optimizer evaluates 46 candidate thresholds from 0.50 to 0.95 in 0.01 increments, computing F1, precision, recall, and accuracy for each one against calibration events with known outcomes.
export class ThresholdOptimizer {
private static readonly GRID_MIN = 0.5;
private static readonly GRID_MAX = 0.95;
private static readonly GRID_STEP = 0.01;
findOptimalThreshold(
events: CalibrationEvent[],
currentThreshold: number
): OptimizationResult {
const candidates: ThresholdCandidate[] = [];
for (
let threshold = ThresholdOptimizer.GRID_MIN;
threshold <= ThresholdOptimizer.GRID_MAX;
threshold = Math.round((threshold + ThresholdOptimizer.GRID_STEP) * 100) / 100
) {
candidates.push(this.evaluateThreshold(events, threshold));
}
// Sort by F1 descending to find optimal
const sortedCandidates = [...candidates].sort((a, b) => b.f1 - a.f1);
const optimal = sortedCandidates[0];
const current = this.evaluateThreshold(events, currentThreshold);
return {
optimalThreshold: optimal?.threshold ?? currentThreshold,
optimalF1: optimal?.f1 ?? 0,
currentThreshold,
currentF1: current.f1,
improvement: (optimal?.f1 ?? 0) - current.f1,
dataPoints: events.length,
allCandidates: candidates,
};
}
}
Confusion Matrix Evaluation
Each threshold candidate is evaluated by classifying calibration events into true/false positives and negatives, then computing standard metrics with safe division.
evaluateThreshold(
events: CalibrationEvent[],
threshold: number
): ThresholdCandidate {
let tp = 0; // True Positive: predicted activate, actually accepted
let fp = 0; // False Positive: predicted activate, actually rejected
let tn = 0; // True Negative: predicted no activate, actually would reject
let fn = 0; // False Negative: predicted no activate, actually would accept
for (const event of events) {
const bestScore = this.getBestScore(event);
const predicted = bestScore >= threshold;
const actual = event.outcome === 'continued';
if (predicted && actual) tp++;
else if (predicted && !actual) fp++;
else if (!predicted && !actual) tn++;
else if (!predicted && actual) fn++;
}
const precision = tp + fp > 0 ? tp / (tp + fp) : 0;
const recall = tp + fn > 0 ? tp / (tp + fn) : 0;
const f1 = precision + recall > 0
? (2 * precision * recall) / (precision + recall) : 0;
const total = tp + fp + tn + fn;
const accuracy = total > 0 ? (tp + tn) / total : 0;
return { threshold, f1, precision, recall, accuracy };
}
CalibrationStore: JSONL Persistence
Calibration events are stored in an append-only JSONL file at ~/.gsd-skill/calibration/events.jsonl. The store uses a write queue to serialize concurrent writes and prevent JSON interleaving.
export class CalibrationStore {
private eventsPath: string;
private writeQueue: Promise<void> = Promise.resolve();
constructor(basePath?: string) {
const baseDir = basePath ?? join(homedir(), '.gsd-skill', 'calibration');
this.eventsPath = join(baseDir, 'events.jsonl');
}
async record(input: CalibrationEventInput): Promise<CalibrationEvent> {
const event: CalibrationEvent = {
...input,
id: randomUUID(),
timestamp: new Date().toISOString(),
};
await this.appendLine(event);
return event;
}
async getKnownOutcomes(): Promise<CalibrationEvent[]> {
const events = await this.readAll();
return events.filter(e => e.outcome !== 'unknown');
}
private async appendLine(event: CalibrationEvent): Promise<void> {
await this.ensureDir();
this.writeQueue = this.writeQueue.then(async () => {
const line = JSON.stringify(event) + '\n';
await appendFile(this.eventsPath, line, 'utf-8');
});
await this.writeQueue;
}
}
Calibration Data Types
| Type | Description |
|---|---|
ThresholdCandidate |
Metrics for a single threshold: f1, precision, recall, accuracy |
OptimizationResult |
Optimal vs current threshold comparison with improvement delta |
CalibrationEvent |
Recorded skill activation decision with outcome (continued/corrected/unknown) |
CalibrationEventInput |
Event data before id/timestamp are added |

