Pattern's group coordination system enables multiple agents to work together through various patterns. This guide covers how to create, configure, and use agent groups.
A group is a collection of agents that coordinate using a specific pattern:
pub struct AgentGroup {
pub id: GroupId,
pub name: String,
pub description: String,
pub coordination_pattern: CoordinationPattern,
pub state: GroupState,
pub members: Vec<(AgentModel, GroupMembership)>,
}Six patterns are available:
pub enum CoordinationPattern {
Supervisor { leader_id, delegation_rules },
RoundRobin { current_index, skip_unavailable },
Voting { quorum, voting_rules },
Pipeline { stages, parallel_stages },
Dynamic { selector_name, selector_config },
Sleeptime { check_interval, triggers, intervention_agent_id },
}pub enum GroupMemberRole {
Regular, // Standard member
Supervisor, // Group leader
Observer, // Receives messages but doesn't respond
Specialist { domain: String }, // Expert in a domain
}One agent leads, delegating tasks to others:
graph TB
M[Message] --> L[Leader Agent]
L -->|Delegate| W1[Worker 1]
L -->|Delegate| W2[Worker 2]
L --> R[Synthesized Response]
[groups.pattern]
type = "supervisor"
leader = "Pattern"
[groups.pattern.delegation_rules]
max_delegations_per_agent = 3
delegation_strategy = "capability" # round_robin, least_busy, random
fallback_behavior = "handle_self" # queue, failUse Cases:
- Task delegation with oversight
- Quality control
- Hierarchical coordination
Agents take turns in order:
graph LR
M[Message] --> A1[Agent 1]
A1 -.next.-> A2[Agent 2]
A2 -.next.-> A3[Agent 3]
A3 -.next.-> A1
[groups.pattern]
type = "round_robin"
skip_unavailable = true # Skip inactive agentsUse Cases:
- Fair distribution of work
- Load balancing
- Team discussions
Sequential processing through stages:
graph LR
M[Message] --> S1[Analysis Stage]
S1 --> S2[Planning Stage]
S2 --> S3[Execution Stage]
S3 --> R[Result]
[groups.pattern]
type = "pipeline"
stages = ["Analyzer", "Planner", "Executor"]
parallel_stages = false
# Stage failure handling (in code)
# on_failure = "skip" | "retry" | "abort" | "fallback"Use Cases:
- Multi-step workflows
- Analysis pipelines
- Document processing
Context-based agent selection:
graph TB
M[Message] --> S{Selector}
S -->|Capability Match| A1[Expert Agent]
S -->|Load Balance| A2[Least Busy]
S -->|Random| A3[Any Agent]
[groups.pattern]
type = "dynamic"
selector = "capability" # random, load_balancing, supervisor
[groups.pattern.selector_config]
preferred_domain = "task_management"Available Selectors:
random: Random selectioncapability: Match message content to agent capabilitiesload_balancing: Select least recently used agentsupervisor: LLM-based selection by supervisor agent
Special Addressing:
@all: Broadcast to all active agents@agentnameoragentname:: Route directly to named agent
Agents vote on decisions:
graph TB
M[Message] --> A1[Agent 1]
M --> A2[Agent 2]
M --> A3[Agent 3]
A1 --> V{Voting}
A2 --> V
A3 --> V
V --> R[Consensus Result]
[groups.pattern]
type = "voting"
quorum = 3
[groups.pattern.voting_rules]
voting_timeout = 30 # seconds
tie_breaker = "random" # first_vote, no_decision, or specific_agent
weight_by_expertise = trueUse Cases:
- Critical decisions
- Consensus building
- Multi-perspective evaluation
Background monitoring with intervention triggers:
graph TB
T[Timer] --> C{Check Triggers}
C -->|Condition Met| A[Intervention Agent]
C -->|Normal| T
A --> I[Proactive Message]
[groups.pattern]
type = "sleeptime"
check_interval = 1200 # 20 minutes
intervention_agent = "Pattern"
[[groups.pattern.triggers]]
name = "hyperfocus_check"
priority = "high"
[groups.pattern.triggers.condition]
type = "time_elapsed"
duration = 5400 # 90 minutes
[[groups.pattern.triggers]]
name = "activity_sync"
priority = "medium"
[groups.pattern.triggers.condition]
type = "constellation_activity"
message_threshold = 20
time_threshold = 3600Trigger Conditions:
time_elapsed: Duration since last activitypattern_detected: Named pattern recognitionthreshold_exceeded: Metric over thresholdconstellation_activity: Message count or time thresholdscustom: Custom evaluator
Use Cases:
- ADHD hyperfocus monitoring
- Periodic check-ins
- Background task management
Full group configuration in constellation.toml:
[[groups]]
name = "Main Support"
description = "Primary ADHD support team"
[groups.pattern]
type = "dynamic"
selector = "capability"
[[groups.members]]
name = "Pattern"
config_path = "agents/pattern/agent.toml"
role = "supervisor"
capabilities = ["coordination", "planning", "emotional_support"]
[[groups.members]]
name = "Entropy"
config_path = "agents/entropy/agent.toml"
role = { specialist = { domain = "task_breakdown" } }
capabilities = ["task_analysis", "decomposition", "prioritization"]
[[groups.members]]
name = "Archive"
config_path = "agents/archive/agent.toml"
role = "regular"
capabilities = ["memory", "recall", "pattern_recognition"]
# Data source routing to group
[groups.data_sources.bluesky]
type = "bluesky"
name = "bluesky"
target = "Main Support"# List groups
pattern group list
# Create group (interactive TUI builder)
pattern group create
# Create group from TOML template
pattern group create --from crisis.toml
# Add member
pattern group add member "Crisis Response" Pattern --role regular
# View status
pattern group status "Crisis Response"
# Edit group (interactive TUI builder)
pattern group edit "Crisis Response"
# Export configuration
pattern group export "Crisis Response" -o crisis.tomlGroups emit events during message processing:
pub enum GroupResponseEvent {
Started { group_id, pattern, agent_count },
AgentStarted { agent_id, agent_name, role },
TextChunk { agent_id, text, is_final },
ReasoningChunk { agent_id, text, is_final },
ToolCallStarted { agent_id, call_id, fn_name, args },
ToolCallCompleted { agent_id, call_id, result },
AgentCompleted { agent_id, agent_name, message_id },
Complete { group_id, pattern, execution_time, agent_responses, state_changes },
Error { agent_id, message, recoverable },
}use pattern_core::coordination::{DynamicManager, DefaultSelectorRegistry};
let registry = Arc::new(DefaultSelectorRegistry::new());
let manager = DynamicManager::new(registry);
let mut stream = manager.route_message(&group, &agents, message).await?;
use tokio_stream::StreamExt;
while let Some(event) = stream.next().await {
match event {
GroupResponseEvent::TextChunk { agent_id, text, .. } => {
println!("[{}]: {}", agent_id, text);
}
GroupResponseEvent::Complete { execution_time, .. } => {
println!("Completed in {:?}", execution_time);
}
_ => {}
}
}Each pattern maintains its own state:
pub enum GroupState {
Supervisor { current_delegations: HashMap<AgentId, usize> },
RoundRobin { current_index, last_rotation },
Voting { active_session: Option<VotingSession> },
Pipeline { active_executions: Vec<PipelineExecution> },
Dynamic { recent_selections: Vec<(DateTime<Utc>, AgentId)> },
Sleeptime { last_check, trigger_history, current_index },
}State is automatically updated after each message and persisted to the database.
Agents in a group can share memory blocks:
// Share a block with another agent
db.share_block(owner_id, block_id, recipient_id, MemoryPermission::ReadOnly).await?;
// Access shared content
let doc = memory.get_shared_block(recipient_id, owner_id, "shared_notes").await?;Shared blocks appear in context with attribution:
<block:shared_notes permission="ReadOnly" shared_from="Archive">
Cross-agent insights about user patterns
</block:shared_notes>| Pattern | Best For |
|---|---|
| Supervisor | Delegation, quality control |
| RoundRobin | Fair distribution, load balancing |
| Pipeline | Sequential workflows |
| Dynamic | Expertise matching |
| Voting | Critical decisions |
| Sleeptime | Background monitoring |
Define specific, actionable capabilities:
# Good - specific and matchable
capabilities = ["task_breakdown", "time_estimation", "priority_analysis"]
# Too vague - hard to match
capabilities = ["help", "support"]- Keep groups focused (3-7 members typically optimal)
- Mix complementary capabilities
- Assign clear roles
- Consider overlapping group memberships for different contexts
The same agent can belong to multiple groups:
Pattern Agent
├── Main Support (Dynamic)
├── Crisis Response (RoundRobin)
├── Planning (Supervisor - as member)
└── Sleeptime (Sleeptime - as intervener)
- Check agent states:
pattern agent list - Verify group membership:
pattern group status <name> - For capability selector: Ensure agents have matching capabilities
- Check
skip_unavailablesetting - Verify member
is_activestatus - Review agent logs for errors
- Check timeout settings
- Verify stage agents are available
- Review
on_failureaction (skip, retry, abort, fallback)
- Enable debug logging:
RUST_LOG=pattern_core::coordination=debug - Check selector configuration
- Verify agent capabilities match message content