swarm-discussion
"Deep-dive into problems as if multiple experts were debating"
Staff+ Engineer Thinking Pattern
"When there's no clear answer, expose blind spots by confronting diverse perspectives."
For unsolved problems or unprecedented challenges, multiple experts participate as a team, engaging in "true discussions" through messaging where they challenge and supplement each other.
Features
- •Team-based Architecture: Compose teams using the Teammate API
- •Messaging-based Dialogue: Experts communicate directly with each other
- •Statement → Rebuttal → Counter-rebuttal: True discussion, not just parallel statements
- •Dynamic Expert Generation: Automatically define appropriate experts based on the topic
- •Complete Evidence Preservation: Save all messages
- •User Participation: Use AskUserQuestion for direction confirmation
Architecture
code
┌─────────────────────────────────────────────────────────────────┐
│ Discussion Team │
│ team_name: discussion-{id} │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Expert 1 │ │ Expert 2 │ │ Contrarian │ │Cross-Domain│ │
│ │ │◄──────────────►│ │◄─────────────►│ │
│ │ inbox ◄───┼──── messages ──┼──► inbox │ messages │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ └──────────────┴──────┬───────┴──────────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ Moderator │ │
│ │ - Present topics │ │
│ │ - Facilitate │ │
│ │ - Convergence │ │
│ └─────────┬─────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ Historian │ │
│ │ - Record │ │
│ │ - Synthesize │ │
│ └───────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Role Design
Fixed Roles
| Role | Responsibility | Characteristic |
|---|---|---|
| Moderator | Facilitate discussion, present topics, determine convergence | Discussion facilitator |
| Historian | Record statements, synthesize, generate summaries | Record keeper |
| Contrarian | Question assumptions, present counterarguments | Always seeks opposing views |
| Cross-Domain | Provide analogies from other fields | Brings alternative perspectives |
Dynamically Generated Roles (3-4 based on topic)
Analyze the topic and define appropriate experts. Each expert has the following attributes:
json
{
"id": "database-expert",
"name": "Database Expert",
"expertise": ["RDB", "NoSQL", "Distributed DB"],
"thinkingStyle": "pragmatic",
"bias": "Prioritizes practicality and performance",
"replyTendency": "Shows concrete implementation examples"
}
Discussion Flow
Phase 1: Initialization
javascript
// 1. Generate discussion ID
const discussionId = slugify(topic); // e.g., "microservice-transaction"
// 2. Create team
Teammate({
operation: "spawnTeam",
team_name: `discussion-${discussionId}`
})
// 3. Create directory structure
Bash({
command: `mkdir -p ~/.claude/discussions/${discussionId}/{personas,rounds,artifacts,context}`
})
// 4. Analyze topic and define experts (executed by Orchestrator)
const dynamicExperts = analyzeTopicAndDefineExperts(topic);
// → [{ id, name, expertise, thinkingStyle, bias, replyTendency }, ...]
// 5. Add fixed roles
const fixedRoles = [
{ id: "moderator", name: "Moderator", role: "Discussion facilitator" },
{ id: "historian", name: "Historian", role: "Record keeper" },
{ id: "contrarian", name: "Contrarian", role: "Devil's advocate" },
{ id: "cross-domain", name: "Cross-Domain", role: "Alternative perspective" }
];
const allExperts = [...dynamicExperts, ...fixedRoles];
// 6. Confirm expert composition with user
AskUserQuestion({
questions: [{
question: `Start discussion with the following experts?\n${allExperts.map(e => `- ${e.name}`).join('\n')}`,
header: "Confirm Experts",
options: [
{ label: "Start (Recommended)", description: "Begin with this composition" },
{ label: "Modify", description: "Add or change experts" }
],
multiSelect: false
}]
})
// 7. Save manifest.json
Write(`~/.claude/discussions/${discussionId}/manifest.json`, {
id: discussionId,
title: topic,
created: new Date().toISOString(),
status: "active",
currentPhase: "initial",
currentRound: 0,
team_name: `discussion-${discussionId}`,
personas: allExperts
})
// 8. Save each expert definition
for (const expert of allExperts) {
Write(`~/.claude/discussions/${discussionId}/personas/${expert.id}.json`, expert)
}
// 9. Create discussion task
TaskCreate({
subject: `Discussion: ${topic}`,
description: `Experts: ${allExperts.map(e => e.name).join(", ")}`,
activeForm: "Preparing discussion team"
})
Phase 2: Round Execution (Statement → Rebuttal → Convergence)
javascript
async function executeRound(discussionId, roundNum, roundTopic) {
const teamName = `discussion-${discussionId}`;
const experts = loadPersonas(discussionId);
// 1. Create round task
TaskCreate({
subject: `Round ${roundNum}: ${roundTopic}`,
description: "Experts are discussing",
activeForm: `Round ${roundNum} in progress`
})
TaskUpdate({ taskId: roundTaskId, status: "in_progress" })
// 2. Array to store all messages
const allMessages = [];
// ========== Step 1: Initial Statement Phase ==========
// Moderator presents the topic
const moderatorOpening = await Task({
team_name: teamName,
name: "moderator",
subagent_type: "general-purpose",
prompt: `
You are the Moderator. Please start the discussion on the following topic.
【Topic】
${roundTopic}
【Previous Discussion】
${previousRoundsSummary || "(New discussion)"}
【Task】
1. Clearly present the topic
2. Suggest 2-3 discussion angles
3. Include questions for each expert
`
});
allMessages.push({
from: "moderator",
type: "opening",
content: moderatorOpening,
timestamp: new Date().toISOString()
});
// Send Moderator's opening message to all experts
for (const expert of experts.filter(e => e.id !== "moderator" && e.id !== "historian")) {
Teammate({
operation: "write",
target_agent_id: expert.id,
value: JSON.stringify({
type: "round_start",
topic: roundTopic,
moderator_opening: moderatorOpening
})
})
}
// Dynamic experts make initial statements (parallel)
const initialStatements = [];
for (const expert of experts.filter(e => !["moderator", "historian", "contrarian", "cross-domain"].includes(e.id))) {
Task({
team_name: teamName,
name: expert.id,
subagent_type: "general-purpose",
prompt: buildExpertPrompt(expert, {
phase: "initial",
topic: roundTopic,
moderatorOpening: moderatorOpening,
instruction: "Share your perspective on this topic from your area of expertise."
}),
run_in_background: true
})
}
// Collect statements
for (const expert of dynamicExperts) {
const statement = await collectStatement(expert.id);
initialStatements.push({
from: expert.id,
type: "initial_statement",
content: statement,
timestamp: new Date().toISOString()
});
allMessages.push(initialStatements[initialStatements.length - 1]);
// Share statement with other experts
broadcastMessage(teamName, expert.id, statement, experts);
}
// ========== Step 2: Rebuttal Phase ==========
// Contrarian provides counterarguments
const contrarianResponse = await Task({
team_name: teamName,
name: "contrarian",
subagent_type: "general-purpose",
prompt: `
You are the Contrarian.
【Topic】
${roundTopic}
【Previous Statements】
${formatStatements(initialStatements)}
【Task】
1. Question the assumptions of each statement
2. Point out overlooked risks or exceptions
3. Challenge from a "Is that really true?" perspective
4. Raise constructive questions
`
});
allMessages.push({
from: "contrarian",
type: "counterpoint",
content: contrarianResponse,
timestamp: new Date().toISOString()
});
// Share Contrarian's rebuttal with everyone
broadcastMessage(teamName, "contrarian", contrarianResponse, experts);
// ========== Step 3: Counter-Rebuttal Phase ==========
// Dynamic experts respond to Contrarian (parallel)
for (const expert of dynamicExperts) {
Task({
team_name: teamName,
name: expert.id,
subagent_type: "general-purpose",
prompt: buildExpertPrompt(expert, {
phase: "rebuttal",
topic: roundTopic,
previousStatements: initialStatements,
contrarianResponse: contrarianResponse,
instruction: "Respond to Contrarian's rebuttal - either counter or accept. Make your position clear."
}),
run_in_background: true
})
}
// Collect rebuttals
const rebuttals = [];
for (const expert of dynamicExperts) {
const rebuttal = await collectStatement(expert.id);
rebuttals.push({
from: expert.id,
type: "rebuttal",
content: rebuttal,
timestamp: new Date().toISOString()
});
allMessages.push(rebuttals[rebuttals.length - 1]);
}
// ========== Step 4: Cross-Domain Perspective ==========
const crossDomainResponse = await Task({
team_name: teamName,
name: "cross-domain",
subagent_type: "general-purpose",
prompt: `
You are the Cross-Domain Thinker.
【Topic】
${roundTopic}
【Discussion So Far】
${formatStatements(allMessages)}
【Task】
1. Draw analogies from other fields (biology, economics, physics, etc.)
2. Show how similar problems have been solved in other domains
3. Propose new frameworks or perspectives
`
});
allMessages.push({
from: "cross-domain",
type: "analogy",
content: crossDomainResponse,
timestamp: new Date().toISOString()
});
// ========== Step 5: Convergence ==========
// Moderator synthesizes the discussion
const synthesis = await Task({
team_name: teamName,
name: "moderator",
subagent_type: "general-purpose",
prompt: `
Synthesize this round's discussion.
【All Statements】
${formatStatements(allMessages)}
【Output Format】
{
"summary": "Summary of this round (about 200 characters)",
"agreements": ["Agreement 1", "Agreement 2"],
"disagreements": ["Disagreement 1", "Disagreement 2"],
"insights": ["Discovered insight 1", "Insight 2"],
"openQuestions": ["Unresolved question 1", "Question 2"],
"nextTopicSuggestions": ["Next topic candidate 1", "Candidate 2"]
}
`
});
// ========== Step 6: Record ==========
// Historian creates complete record
const roundRecord = {
roundId: roundNum,
topic: roundTopic,
timestamp: new Date().toISOString(),
messages: allMessages, // Save all messages
synthesis: JSON.parse(synthesis),
metadata: {
messageCount: allMessages.length,
participants: [...new Set(allMessages.map(m => m.from))]
}
};
Write(`~/.claude/discussions/${discussionId}/rounds/${String(roundNum).padStart(3, '0')}.json`, roundRecord)
// Complete task
TaskUpdate({ taskId: roundTaskId, status: "completed" })
// ========== Step 7: Confirm Next Action ==========
AskUserQuestion({
questions: [{
question: "What would you like to do next?",
header: "Progress",
options: [
{ label: "Deep dive", description: synthesis.nextTopicSuggestions[0] || "Most important topic" },
{ label: "Different topic", description: "Select another topic" },
{ label: "Another round", description: "Continue on same topic" },
{ label: "Synthesis phase", description: "Summarize the discussion" },
{ label: "Pause", description: "Resume later" }
],
multiSelect: false
}]
})
return roundRecord;
}
// Helper function: Broadcast message
function broadcastMessage(teamName, fromId, message, experts) {
for (const expert of experts) {
if (expert.id !== fromId && expert.id !== "historian") {
Teammate({
operation: "write",
target_agent_id: expert.id,
value: JSON.stringify({
type: "message",
from: fromId,
content: message
})
})
}
}
}
Phase 3: Synthesis
javascript
async function synthesizeDiscussion(discussionId) {
const teamName = `discussion-${discussionId}`;
const allRounds = loadAllRounds(discussionId);
// Historian synthesizes everything
const finalSynthesis = await Task({
team_name: teamName,
name: "historian",
subagent_type: "general-purpose",
prompt: `
You are the Historian. Synthesize the entire discussion.
【All Round Records】
${JSON.stringify(allRounds, null, 2)}
【Output Format】
{
"executiveSummary": "Summary of the entire discussion (about 500 characters)",
"insights": [
{
"title": "Insight title",
"description": "Detailed description",
"confidence": "high/medium/low",
"supportingEvidence": ["Supporting statements"],
"dissentingViews": ["Dissenting views if any"]
}
],
"agreements": [
{ "point": "Agreement point", "supporters": ["Supporters"] }
],
"unresolvedDebates": [
{
"topic": "Point of contention",
"positions": [
{ "stance": "Position A", "advocates": ["Advocates"], "arguments": ["Arguments"] },
{ "stance": "Position B", "advocates": ["Advocates"], "arguments": ["Arguments"] }
]
}
],
"openQuestions": ["Unresolved questions"],
"recommendations": ["Recommended actions"]
}
`
});
// Save artifacts
const synthesis = JSON.parse(finalSynthesis);
Write(`~/.claude/discussions/${discussionId}/artifacts/synthesis.json`, synthesis)
Write(`~/.claude/discussions/${discussionId}/artifacts/synthesis.md`, formatSynthesisAsMarkdown(synthesis))
Write(`~/.claude/discussions/${discussionId}/artifacts/open-questions.md`, formatOpenQuestions(synthesis))
return synthesis;
}
Phase 4: Checkpoint / Termination
javascript
async function checkpointDiscussion(discussionId) {
const teamName = `discussion-${discussionId}`;
// 1. Generate resume context
const resumeContext = await Task({
team_name: teamName,
name: "historian",
subagent_type: "general-purpose",
prompt: `
Generate the minimum context needed to resume this discussion later.
Items to include:
1. Discussion theme and purpose (1 paragraph)
2. Key progress so far (bullet points)
3. Current topics and state
4. Summary of participants' main positions
5. Issues to address next time
Length: 1000-2000 characters
Format: Markdown
`
});
Write(`~/.claude/discussions/${discussionId}/context/summary.md`, resumeContext)
// 2. Update manifest
updateManifest(discussionId, {
lastActive: new Date().toISOString(),
status: "paused",
currentPhase: "checkpoint"
})
// 3. Shutdown all workers
const experts = loadPersonas(discussionId);
for (const expert of experts) {
Teammate({
operation: "requestShutdown",
target_agent_id: expert.id
})
}
// 4. Cleanup
Teammate({ operation: "cleanup" })
}
async function resumeDiscussion(discussionId) {
// 1. Load manifest
const manifest = Read(`~/.claude/discussions/${discussionId}/manifest.json`)
// 2. Recreate team
Teammate({
operation: "spawnTeam",
team_name: manifest.team_name
})
// 3. Load resume context
const context = Read(`~/.claude/discussions/${discussionId}/context/summary.md`)
// 4. Update manifest
updateManifest(discussionId, {
lastActive: new Date().toISOString(),
status: "active"
})
// 5. Notify Moderator of resumption
const reopening = await Task({
team_name: manifest.team_name,
name: "moderator",
subagent_type: "general-purpose",
prompt: `
Resuming the discussion.
【Previous Context】
${context}
【Participants】
${manifest.personas.map(p => `- ${p.name}`).join('\n')}
Review the previous state and suggest next steps.
`
})
return reopening;
}
Data Structure
code
~/.claude/discussions/{discussion-id}/
├── manifest.json # Metadata
├── personas/ # Expert definitions
│ ├── expert-1.json
│ ├── contrarian.json
│ └── ...
├── rounds/ # Complete record of each round
│ ├── 001.json # Contains all messages
│ ├── 002.json
│ └── ...
├── artifacts/ # Outputs
│ ├── synthesis.json # Structured synthesis
│ ├── synthesis.md # Markdown format
│ └── open-questions.md # Unresolved questions
└── context/
└── summary.md # Resume context
Round JSON Structure (Message-based)
json
{
"roundId": 2,
"topic": "Microservice Transaction Management",
"timestamp": "2026-01-29T10:30:00Z",
"messages": [
{
"from": "moderator",
"type": "opening",
"content": "In this round...",
"timestamp": "2026-01-29T10:30:00Z"
},
{
"from": "database-expert",
"type": "initial_statement",
"content": {
"position": "I recommend the Saga pattern",
"reasoning": "Distributed transactions are...",
"proposals": ["Choreography-based Saga", "Orchestration-based Saga"],
"codeExample": "..."
},
"timestamp": "2026-01-29T10:31:00Z"
},
{
"from": "contrarian",
"type": "counterpoint",
"content": "The Saga pattern has the problem of compensating transaction complexity...",
"timestamp": "2026-01-29T10:33:00Z"
},
{
"from": "database-expert",
"type": "rebuttal",
"content": "True it's complex, but with proper design...",
"timestamp": "2026-01-29T10:35:00Z"
},
{
"from": "cross-domain",
"type": "analogy",
"content": "This is similar to settlement systems in finance...",
"timestamp": "2026-01-29T10:37:00Z"
}
],
"synthesis": {
"summary": "General agreement on adopting Saga pattern, but compensating transaction design remains a challenge",
"agreements": ["Distributed transactions should be avoided"],
"disagreements": ["Choreography vs Orchestration"],
"insights": ["Financial settlement patterns are a useful reference"],
"openQuestions": ["Is automatic generation of compensating transactions possible?"]
}
}
Prompt Templates
Dynamic Expert Prompt
javascript
function buildExpertPrompt(expert, options) {
return `
You are participating in the discussion as "${expert.name}".
【Your Profile】
- Areas of expertise: ${expert.expertise.join(", ")}
- Thinking style: ${expert.thinkingStyle}
- Natural bias: ${expert.bias}
- Response tendency: ${expert.replyTendency}
【Current Phase】
${options.phase}
【Topic】
${options.topic}
【Previous Statements】
${options.previousStatements ? formatStatements(options.previousStatements) : "(First statement)"}
${options.contrarianResponse ? `
【Contrarian's Rebuttal】
${options.contrarianResponse}
` : ""}
【Task】
${options.instruction}
【Output Format】
{
"position": "Your stance on this topic (1-2 sentences)",
"reasoning": "Detailed analysis",
"proposals": ["Concrete proposals"],
"counterpoints": ["Rebuttals or supplements to others"],
"questions": ["Additional questions to consider"],
"codeOrDiagrams": "Code examples or diagrams (optional)"
}
`;
}
Important Notes
Cost Awareness
- •Team-based approach has higher overhead than direct launch
- •5-10 Task/Teammate calls per round
- •Use only when deep discussion is needed
Leveraging Messaging
- •Use
Teammate({ operation: "write" })to share statements - •Experts can respond based on received messages
- •Enables true dialogue
Importance of Cleanup
- •Always
requestShutdown→cleanupwhen discussion ends - •Leaving teams running wastes resources
Importance of Evidence
- •Save all statements chronologically in the
messagesarray - •Enables complete reconstruction of discussion flow later
Usage Example
code
User: /swarm-discussion "Microservice Transaction Management" System: 1. Create team: discussion-microservice-transaction 2. Define experts: - Distributed Systems Designer - Database Expert - Operations Engineer - Contrarian (fixed) - Cross-Domain (fixed) 3. Confirm with user → "Start" 4. Round 1: - Moderator: Present topic - Experts: Initial statements (parallel) - Contrarian: Rebuttal - Experts: Counter-rebuttals - Cross-Domain: Alternative perspective - Moderator: Convergence/synthesis 5. Confirm next action with user 6. Round 2, 3, ... 7. Synthesis phase → artifacts/synthesis.md 8. Checkpoint → cleanup