adversarial-spec
Iteratively refine a product spec by debating with multiple LLMs (GPT, Gemini, Grok, etc.) until all models agree. Use when user wants to write or refine a specification document using adversarial development.
1How It Works & Mechanism
The core mechanism is not merely 'calling multiple models' but 'Claude actively participating in the ring': SKILL.md requires Claude to provide its own independent critique and synthesis adjudication alongside the opponent models' conclusions, clearly communicating this to the user.
**Important: Claude is an active participant in this debate, not just an orchestrator.** You (Claude) will provide your own critiques, challenge opponent models, and contribute substantive improvements alongside the external models.
The actual execution layer is a built-in Python CLI (debate.py + 5 modules); the skill feeds documents to the script via stdin using fixed command lines, and the script uses litellm to call various providers in parallel, parsing `[AGREE]` / `[SPEC]` tags.
python3 "$(find ~/.claude -name debate.py -path '*adversarial-spec*' 2>/dev/null | head -1)" critique --models MODEL_LIST --doc-type TYPE <<'SPEC_EOF'
Invocation channels fall into two categories: API key-based models use litellm as a unified egress; subscription-based models (ChatGPT/Google accounts) use local CLI child processes, passing documents via argv/stdin to codex / gemini.
cmd = [ "codex", "exec", "--json", "--full-auto", "--skip-git-repo-check", "--model", actual_model, "-c", f'model_reasoning_effort="{reasoning_effort}"', ]
Convergence decisions rely on literal markers in model outputs rather than semantic evaluations: if any model fails to emit [AGREE], it proceeds to the next round; premature agreements in the first two rounds trigger an anti-laziness interrogation round via --press.
**Handling Early Agreement (Anti-Laziness Check):** If any model says `[AGREE]` within the first 2 rounds, be skeptical.
Long debates can be interrupted and rolled back: session states, per-round checkpoints, and common configurations are persisted separately to disk, isolating sessions from profiles.
SESSIONS_DIR = Path.home() / ".config" / "adversarial-spec" / "sessions" CHECKPOINTS_DIR = Path.cwd() / ".adversarial-spec-checkpoints"
An optional human-in-the-loop channel is available via a Telegram bot: it pushes a summary to the user after each round, polls for a reply within 60 seconds, and incorporates feedback into the next round; if no reply is received, it auto-continues.
TELEGRAM_API: str = "https://api.telegram.org/bot{token}/{method}"
Enterprise alternative channel: switchable to AWS Bedrock to route all model invocations through the Bedrock prefix (for compliance/gateway scenarios), with configuration saved to config.json in the home directory.
**When Bedrock mode is enabled, ALL model calls route through Bedrock** - no direct API calls are made.
Final artifact delivery is performed by Claude (the host) rather than the script: the skill requires printing and writing the final document to spec-output.md in the current directory (or tech-spec-output.md if continuing from a PRD); the script itself does not produce this file.
1. Print the complete, polished document to terminal 2. Write it to `spec-output.md` in current directory
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| package | litellm |
| api | 多家 LLM 供应商 API(经 litellm 统一出口) |
| cli | codex(OpenAI Codex CLI,走 ChatGPT 订阅) |
| cli | gemini(Google Gemini CLI,走 Google 账号) |
| api | AWS Bedrock(可选企业通道,全部调用可改走 bedrock/ 前缀) |
| network | Telegram Bot API(可选人工在环) |
| package | 开发依赖(pytest/pytest-cov/ruff/mypy/pre-commit) |
4Recommended Governance & Evidence
- scripts/: Executes local scripts or commands: python3 <…>/debate.py critique|diff|export-tasks|send-final|providers|focus
- 网络端点: Declares external network access: litellm → official vendor APIs (OpenAI / Anthropic / Google / xAI / Mistral / Groq / O
- 本地工作目录: File I/O and artifact output: ~/.claude/adversarial-spec/config.json (bedrock enable/disable/add-model/ali
5Second-Pass Verification
- [ok] 多模型调用确实存在(非纯提示词) — models.py import litellm + from litellm import completion,标准路径 'response = completion(**completion_kwargs)';providers.py CODEX_AVAILABLE/GEMINI_CLI_AVAILABLE 用 shutil.which 探测。
- [ok] 订阅制模型走 CLI 子进程 — call_codex_model 构造 ['codex','exec','--json','--full-auto','--skip-git-repo-check','--model',…] 并 subprocess.run;call_gemini_cli_model 构造 ['gemini','-m',model,'-y'] 并把 prompt 经 input= 传入。
- [ok] Telegram 端点与轮询 — telegram_bot.py 'TELEGRAM_API: str = "https://api.telegram.org/bot{token}/{method}"' + 'with urlopen(req, timeout=30)'(urllib,非 requests);poll_for_reply(timeout=60 默认) 与 cmd_notify 均存在。
- [ok] Bedrock 模式确实可全量接管调用 — is_bedrock_enabled()/get_bedrock_config() 读 GLOBAL_CONFIG_PATH;models.py 在 bedrock 分支设置 AWS_REGION 并给 model 加 'bedrock/' 前缀;handle_bedrock_command 支持 status/enable/disable/add-model/remove-model/alias。
- [discrepancy] 『Maximum 10 rounds』是否由代码强制 — SKILL.md 写 'Maximum 10 rounds per cycle (ask user to continue if reached)',但对 debate.py 全文检索无任何轮数上限常量/参数(--round 只是当前轮号,--rounds 只用于 send-final 汇报)。结论:轮数上限是提示词纪律,代码不设护栏,已在 how_it_works 第 4 条与 risks 中如实标注。
- [discrepancy] 『Write it to spec-output.md』的归属 — 第一遍曾按『脚本写文件』记录;第二遍在 scripts/ 全目录检索 'spec-output' 零命中,确认该写入由宿主 Write 工具完成(SKILL.md allowed-tools: Bash, Read, Write, AskUserQuestion)。已改写为『成品交付由 Claude 完成』并据此调整 file_writes。
- [discrepancy] Python 版本要求一致性 — SKILL.md Requirements 写 'Python 3.10+ with `litellm` package installed',而 pyproject.toml 写 requires-python = ">=3.9" 且 ruff target-version = "py39"、mypy python_version = "3.10"。属文档与打包元数据的轻微不一致(不影响功能判定)。
- [ok] 成本追踪是否真有实现(非仅文档) — providers.py MODEL_COSTS 价目表 + DEFAULT_COST;debate.py 'Cost: ${cost_tracker.total_cost:.4f}' 与 JSON 输出 'cost': {total, input_tokens, output_tokens, by_model}。
6Verdict & Scenarios
89a0a6e57cca0f6a…