返回 Skill 列表
extension
分类: AI Agent 能力无需 API Key

debate-orchestrator

组织正式辩论,包括正方和反方,通过结构化的交流来协调辩手和评委。适用于运行辩论交流、管理辩论轮次或继续被中断的辩论时使用。

person作者: jakexiaohubgithub

Debate Orchestrator

Manages formal debate execution through deterministic state tracking and resumability.

State Machine

Debates cycle through 2 phases per exchange:

| current_phase | Action Required | |---------------|-----------------| | awaiting_arguments | Spawn both debaters in parallel | | awaiting_judgment | Spawn judge to evaluate all new arguments |

After judgment: cycle repeats with current_exchange incremented.

Key Properties:

  • No "complete" state - orchestrator decides when to stop based on requested exchange count
  • Parallel execution - both sides argue simultaneously each exchange
  • Resumable - read state, execute required action, repeat
  • Exchange 0 is special (opening) - both sides produce 3 independent arguments
  • Exchange 1+ are rebuttal - sides produce single arguments with attacks/defends

Running Exchanges

1. Read State

Check {debate}/debate.md frontmatter (JSON format):

{
  "current_exchange": 0,
  "current_phase": "awaiting_arguments"
}

Extract motion from the # Motion section (first markdown heading after frontmatter).

2. Determine Exchange Type

Opening Exchange: current_exchange == 0

  • Both debaters produce 3 independent arguments simultaneously
  • Judge scores all 6 arguments

Rebuttal Exchange: current_exchange >= 1

  • Both debaters produce 1 argument simultaneously
  • Judge scores both new arguments

3. Execute Based on Phase + Exchange Type

Opening Exchange (Exchange 0)

When current_exchange == 0 and current_phase == awaiting_arguments:

Load template:

Read templates/debater-opening.md from this skill's directory.

Spawn both debaters in parallel:

Use a single message with two Task tool invocations to spawn both debaters simultaneously.

For each side (proposition and opposition):

  1. Substitute placeholders in template:

    • {motion}: Extracted motion text
    • {side}: Side name (proposition or opposition)
  2. Spawn debater:

    Use Task tool with subagent_type: "debater"
    Prompt: [substituted template content]
    

Process outputs:

After both debaters complete:

  1. Write proposition output to /tmp/prop_arg.json
  2. Write opposition output to /tmp/opp_arg.json
  3. Execute the python package debate_ops: python3 {skill_base_dir}/debate_ops process-exchange {debate} 0 --prop-file /tmp/prop_arg.json --opp-file /tmp/opp_arg.json

Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.

The script creates 6 argument files: prop_000a.md, prop_000b.md, prop_000c.md, opp_000a.md, opp_000b.md, opp_000c.md

State automatically updates to current_phase: awaiting_judgment.

Judge opening arguments:

When current_exchange == 0 and current_phase == awaiting_judgment:

Load template:

Read templates/judge.md from this skill's directory.

Substitute placeholders:

  • {argument_files}: Space-separated list of all 6 opening arguments:
    @{debate}/arguments/prop_000a.md @{debate}/arguments/prop_000b.md @{debate}/arguments/prop_000c.md @{debate}/arguments/opp_000a.md @{debate}/arguments/opp_000b.md @{debate}/arguments/opp_000c.md
    
  • {motion}: Extracted motion text

Spawn judge:

Use Task tool with subagent_type: "judge"
Prompt: [substituted template content]

Process output:

  1. Use Write tool to save agent output to /tmp/judge.json
  2. Execute the python package debate_ops: python3 {skill_base_dir}/debate_ops process-judge {debate} --json-file /tmp/judge.json

Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.

State automatically updates to current_phase: awaiting_arguments, current_exchange: 1.

Rebuttal Exchange (Exchange 1+)

When current_exchange >= 1 and current_phase == awaiting_arguments:

Build argument context:

  1. List all files in {debate}/arguments/
  2. Separate into proposition and opposition arguments:
    • Proposition: Files matching prop_*.md
    • Opposition: Files matching opp_*.md
  3. Filter to arguments from previous exchanges only:
    • Extract exchange number from filename (e.g., prop_003 → exchange 3)
    • Include only arguments where exchange < current_exchange
  4. Sort by exchange number (chronological order)

Load template:

Read templates/debater-rebuttal.md from this skill's directory.

Spawn both debaters in parallel:

Use a single message with two Task tool invocations to spawn both debaters simultaneously.

For proposition debater:

  • Substitute placeholders:
    • {motion}: Extracted motion text
    • {side}: proposition
    • {exchange}: Current exchange number
    • {your_arguments}: Newline-separated list: @{debate}/arguments/prop_000a.md, @{debate}/arguments/prop_000b.md, etc.
    • {opponent_arguments}: Newline-separated list: @{debate}/arguments/opp_000a.md, @{debate}/arguments/opp_000b.md, etc.

For opposition debater:

  • Substitute placeholders:
    • {motion}: Extracted motion text
    • {side}: opposition
    • {exchange}: Current exchange number
    • {your_arguments}: Newline-separated list of opposition arguments
    • {opponent_arguments}: Newline-separated list of proposition arguments

Process outputs:

After both debaters complete:

  1. Write proposition output to /tmp/prop_arg.json
  2. Write opposition output to /tmp/opp_arg.json
  3. Execute the python package debate_ops: python3 {skill_base_dir}/debate_ops process-exchange {debate} {current_exchange} --prop-file /tmp/prop_arg.json --opp-file /tmp/opp_arg.json

Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.

State automatically updates to current_phase: awaiting_judgment.

Judge rebuttal arguments:

When current_exchange >= 1 and current_phase == awaiting_judgment:

Load template:

Read templates/judge.md from this skill's directory.

Substitute placeholders:

  • {argument_files}: Space-separated list of both new arguments:
    @{debate}/arguments/prop_{current_exchange:03d}.md @{debate}/arguments/opp_{current_exchange:03d}.md
    
  • {motion}: Extracted motion text

Spawn judge:

Use Task tool with subagent_type: "judge"
Prompt: [substituted template content]

Process output:

  1. Use Write tool to save agent output to /tmp/judge.json
  2. Execute the python package debate_ops: python3 {skill_base_dir}/debate_ops process-judge {debate} --json-file /tmp/judge.json

Check result JSON for errors or warnings. On errors, state remains unchanged - report to user and halt. On warnings, note them and continue.

State automatically updates to current_phase: awaiting_arguments, current_exchange incremented.

4. Decide When to Stop

After each phase, check if you should continue:

  • Read the updated state from {debate}/debate.md
  • Compare current exchange number to requested total exchanges
  • If sufficient exchanges completed: stop and report
  • Otherwise: loop back to step 1

The state itself doesn't track "completion" - you decide when done based on user request.

Error Handling

Processing scripts return:

{
  "success": true/false,
  "argument_id": "prop_001" | ["prop_000a", "prop_000b", "prop_000c"],
  "errors": ["fatal errors"],
  "warnings": ["non-fatal warnings"]
}

On errors:

  • State remains unchanged - can safely retry
  • Report error to user
  • Ask how to proceed (retry, skip, abort)

On warnings:

  • Note them
  • Continue execution
  • Mention warnings in completion summary

Note: By default the tmp files get deleted by the script. But if you face errors while writing to a tmp file because it already exists, just Read it and try again.

Resumability

Execution can be interrupted at any point and resumed by reading state:

  • State indicates exactly what phase is needed next
  • Execute that phase
  • State updates atomically on success
  • On failure, state remains unchanged - retry is safe

Completion Report

When requested exchanges complete, report current state:

✓ Completed {N} exchanges for '{debate_slug}'

**Current Scores** (zero-sum tug-of-war):
- Proposition: {total} ({count} arguments)
- Opposition: {total} ({count} arguments)

**Next steps**:
- Continue debating: `/debate-run {debate_slug} X` to run X more exchanges
- Generate report: `/debate-report {debate_slug}` to create comprehensive analysis with visualizations

Extract totals and counts from cumulative_scores in {debate}/debate.md frontmatter. Total exchanges = current_exchange from debate.md.

Note on zero-sum scoring: Positive total = winning, negative total = losing, zero = even. One side typically has positive total, the other negative (tug-of-war).